이 글은 『밑바닥부터 시작하는 데이터 과학』 도서를 보고 정리한 글입니다.
데이터 과학자가 갖춰야할 기본 기술 중 하나는 데이터 시각화다.
데이터 시각화에는 데이터 탐색과 데이터 전달, 두가지 목적이 있다.
1.1 matplotlib
1.2 막대 그래프
1.3 선 그래프
1.4 산점도
1.1 matplotlib
웹을 위한 복잡하고 인터랙티브한 시각화로는 좋지 않은 도구지만, 간단한 막대/선 그래프, 산점도를 그릴 때는 나쁘지 않은 도구이다.
▶ matplotlib 중 우리는 matplotlib.pyplot 모듈을 사용할 것이다.
▶ pyplot : 시각화를 단계별로 간편하게 만들 수 있는 구조로 되어있다.
▶ 시각화가 완성되면 savefig()를 통해 그래프 저장, show()를 통해 화면에 띄울 수 있다.
▶ex)
from matplotlib import pyplot as plt
years = [1950, 1960, 1970, 1980, 1990, 2000, 2010]
gdp = [300.2, 543.3, 1075.9, 2862.5, 5979.6, 10289.7, 14958.3]
# x축에 연도, y축에 GDP가 있는 선 그래프를 만들자.
plt.plot(years, gdp, color='green', marker='o', linestyle='solid')
# 제목 추가
plt.title("Nominal GDP")
# y축에 레이블을 추가
plt.ylabel("Billions of $")
plt.show()
- plt.plot( [x축], [y축], 여러 옵션 ... )
- marker 옵션 : 그래프에 마커 표시를 하기위해서는 marker='o'를 추가하면 된다.
1.2 막대 그래프
막대 그래프는 이산적인 항목들에 대한 변화를 보여줄 때 사용하면 좋다.
▶ ex) 여러 영화가 아카데미 시상식에서 받은 상의 개수 비교
from matplotlib import pyplot as plt
movies = ["Annie Hall", "Ben-Hur", "Casablanca", "Gandhi", "West Side Story"]
num_oscars = [5, 11, 3, 8, 10]
# 막대 너비의 기본 값이 0.8
xs = [i for i, _ in enumerate(movies)] # _ 에는 인덱스를 반환할 것이다. but 필요없으므로 패스
# 왼편으로부터 x축의 위치가 xs이고 높이가 num_oscars인 막대 그래프
plt.bar(xs, num_oscars)
plt.ylabel("# of Academy Awards")
plt.title("My Favorite Movies")
# xticks를 이용하여 x축에 몇 개의, 어떤 값을 넣을지 정한다.
plt.xticks([i for i,_ in enumerate(movies)], movies)
plt.show()
▶ enumerate
순서가 있는 자료형(리스트, 튜플, 문자열)을 입력으로 받아 인덱스 값을 포함하는 enumerate 객체를 돌려준다.
인덱스와 값을 한 쌍으로 반환한다.
▶ bar( [x축], [y축]) : 막대 그래프를 나타내는 메서드
▶ xticks
tick을 몇 개([i+0.5 for i,_ in enumerate(movies)]의 , 어떤 label(movies)을 표시할지 조절할 수 있다.
▶막대그래프를 이용하면 히스토그램(histogram)도 나타낼 수 있다.
히스토그램 : 정해진 구간에 해당되는 항목의 개수를 보여줌으로써 값의 분포를 관찰할 수 있는 그래프 형태
▶ex)
from matplotlib import pyplot as plt
from collections import Counter
grades = [83, 95, 91, 87, 63, 88, 100, 0, 73, 67, 0, 82, 85]
decilt = lambda grade: grade // 10 * 10 # grade를 10으로 나눈 값의 정수에 10을 곱하는 람다식.
histogram = Counter(decilt(grade) for grade in grades)
# grades 원소들을 반복문으로 decilt(람다)함수를 호출한 후, Counter클래스로 각 점수들의 개수를 구한다.
plt.bar([x for x in histogram.keys()], # keys값(점수) 개수로 반복문을 돌린다.
histogram.values(), # 각 막대의 높이를 values값(점수의 빈도 수)
8) # 너비를 8로 설정.
plt.axis([-5, 105, 0, 6]) # x축은 -5부터105, y축은 0부터 6까지 표시
plt.xticks([10*i for i in range(11)]) # x축의 레이블은 0,10,20,...,100까지
plt.xlabel("Decile") # x축 이름
plt.ylabel("# of Students") # y축 이름
plt.title("Distribution of Exam 1 Grades")
plt.show()
▶ collections 모듈의 Counter 클래스 : 데이터의 개수를 셀 때 사용되는 클래스
위의 예시에서 Counter 클래스는 주어진 점수가 몇번 등장하는지 사전 형태
(key:values)로 반환한다.
▶ // : 수를 10으로 나눈 값에서 소수를 없앤 정수를 구한다.
grade // 10 * 10 : 83을 80으로, 95를 90으로 바꾸는 식이 된다.
▶ 너비가 8 -> -4~4, 6~14, 16~24, ..., 86~94, 96~104에 막대그래프가 나타난다.
0(-4~4: )에 2개 : 0, 0
60(56~64)에 2개 : 63, 67
70(66~54)에 1개 : 73
80(76~84)에 5개 : 83, 87, 88, 82, 85
▶ plt.bar의 세번째 인자는 막대의 너비를 지정한다.
(데이터(10,20,30,...,100)에 따라 각 구간의 너비가 10이므로 막대의 너비를 8로 정해서 막대 간에 공간이 생기도록 했다.)
▶ plt.axis를 사용할 때 주의!
- plt.axis를 사용할 때는 모든 값을 포함하는 축을 사용해야 한다.
- 만약 위에서 x축과 y축을 plt.axis([0, 100, 1, 5])로 한다면 좌측 그래프처럼 나타나, 오해를 불러올 수 있다.
1.3 선 그래프
선 그래프는 어떠한 경향을 보여줄 때 유용하다. 위에서 보여준 것처럼 plt.plot()을 이용해 표현이 가능하다.
▶ ex)
from matplotlib import pyplot as plt
variance = [1, 2, 4, 8, 16, 32, 64, 128, 256]
bias_squared = [256, 128, 64, 32, 16, 8, 4, 2, 1]
total_error = [x+y for x,y in zip(variance, bias_squared)]
xs = [i for i, _ in enumerate(variance)]
# 한 차트에 여러개의 series를 그리기 위해 plt.plot을 여러번 호출할 수 있다.
# x축은 모두 xs
plt.plot(xs, variance, 'g-', label='variance') # variance에 대한 초록색 실선(g-)
plt.plot(xs, bias_squared, 'r-.', label='bias^2') # bias_squared에 대한 붉은색 점선-.-.-.(r-.)
plt.plot(xs, total_error, 'b:', label='total error') # total_error에 대한 파란색 점선 . . . . (g:)
# 범례를 위쪽 중앙에 위치시키는 옵션 loc=9
plt.legend(loc=9)
plt.xlabel("model complexity")
plt.title("The Bias-Variance Tradeoff")
plt.show()
▶ zip() : 같은 길이의 리스트를 같은 인덱스끼리 잘라서 리스트로 반환하는
내장함수.
여기서는 두개의 리스트에서 각 인덱스의 값들을 뽑아서 덧셈을 한다.
▶ g- : green 실선 / r-. : red -.-.-모양 점선 / b: : blue ....모양 점선
▶ legend() : 범례 표시하는 역할. (각 함수에 대한 설명)
옵션으로 loc=9 (위쪽 중앙에 위치)
1.4 산점도
산점도는 두 변수간의 연관 관계를 보여주고 싶을 때 적합한 형태의 그래프
▶ ex) 각 사용자의 친구 수와 그들이 매일 사이트에서 체류하는 시간 사이의 연관성 (친구가 많을 수록 사이트 체류 시간이 길다.)
from matplotlib import pyplot as plt
friends = [70, 65, 72, 63, 71, 64, 60, 64, 67]
minutes = [175, 170, 205, 120, 220, 130, 105, 145, 190]
labels = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h','i']
plt.scatter(friends, minutes)
# 각 포인트에 레이블을 단다.
for label, friend_count, minute_count in zip(labels, friends, minutes):
plt.annotate(label, # 표시할 text
xy=(friend_count, minute_count), # text 표시할 (포인트) 좌표
xytext=(5, -5), # text가 point로부터 멀어지는 정도(x축,y축)
textcoords='offset points') # xy(좌표 측의 값)에서부터 xytext offset 위치(단위 point)에 출력
plt.title("Daily Minutes vs. Number of Friends")
plt.xlabel("# of friends")
plt.ylabel("daily minutes spent on the site")
plt.show()
▶ plt.scatter() : 마커를 그리는데 있어서 scatter()는 plot()보다 더 다양한 기능을 제공한다.
scatter()는 옵션으로 화살표 표시도 할 수 있다.
▶ plt.annotate() : 각 위치에 text를 표시해주는 기능
plt.annotate에서 [text], [text표시 좌표]는 필수로 포함해야한다.
▶ xytext는 textcoords 인자에 따라 의미하는 바가 달라진다.
▶ textcoords='offser points' : 단위를 point로 지정한다.
'offset points'가 'offset pixels'보다 당연히 조금 더 멀게 위치한다. (단위 차이)
* offset : 시작점(처음)으로부터 주어진 지점까지의 거리차
+) xytext나 textcoords 같은 옵션은 직접 입력해보면서 차이를 확인하면 쉽게 이해할 수 있다.
축의 범위 설정의 중요성
변수 간 비교를 할때 축의 범위를 자동으로 설정하게 놔두면, 공정한 비교를 하지 못하게 될 수 있다.
from matplotlib import pyplot as plt
test_1_grades = [99, 90, 85, 97, 80]
test_2_grades = [100, 85, 60,90, 70]
plt.scatter(test_1_grades, test_2_grades)
plt.title("Axes Are Comparable")
plt.xlabel("test 1 grade")
plt.ylabel("test 2 grade")
plt.show()
좌측 그래프에 추가로 작성한 코드는 다음과 같다.
plt.axis("equal")
데이터의 형태에 따라 어떤 종류의 그래프를 사용할 지 정하는 것이 중요하다.
앞서 설명한 그래프 외에도 Regplot, Jointplot, kde, Barplot, Boxplot, Pairplot, countplot, heatmap, pie 그래프 등이 있다. 공부해볼 예정이다.
'Python > Review' 카테고리의 다른 글
퍼셉트론 (0) | 2021.01.19 |
---|---|
클래스와 넘파이, 그리고 matplotlib (0) | 2021.01.03 |
Parameter Learning (Gradient Descent) (0) | 2020.12.31 |
Const Function - Intuition 1,2 (0) | 2020.12.28 |
Linear Regression(선형 회귀) (0) | 2020.12.27 |