빠르게 여러 컬럼 간 정보를 보고싶을 때가 있다.
예를들어 엑셀에서는 이런 차트를 기본으로 제공해주기 때문에 분석이 용이하다.
엑셀에서도 간단히 되는게 Python에서 간단히 안될리가 없다.
물론 Python에서도 쉽게 결과를 얻을 수 있다.
다룰 것은 다음과 같다.
- 공분산 (Covariance)
- 상관계수 (Correlation)
- 산점도 (Scatter)
- 추세선 (Trend)
- 결정계수 (R-squared, )
Dataframe dtype
수치 계산에 들어가기 앞서 Pandas의 Dataframe의 자료형에 대한 이해가 필요하다.
보통 Dataframe을 만들면서 dtype을 지정하지 않을텐데, 자칫하다 컬럼이 ‘object’형으로 지정될 수 있다.
이게 Plot을 그릴 땐 문제가 되진 않지만, 계산을 할 때는 문제가 생긴다.
이에 Dataframe의 컬럼에 자료형을 지정해주어야 한다.
예를들어 다음과 같은 방법으로 Dataframe의 모든 컬럼에 float 자료형을 지정해줄 수 있다. [Docs]
df = pd.DataFrame(column=['a', 'b', 'c'], dtype='float')
Docs에도 나와있듯이 이 방법은 모든 컬럼을 하나의 자료형으로 바꾸어준다.
만약 각 컬럼을 원하는 자료형으로 바꾸고 싶은 경우에는 귀찮아도 아래의 방법으로 일일이 바꿔줘야한다. [Docs]
df.astype('float') df.astype({'a': 'float', 'b': 'int32', 'c': 'category'})
Covariance
공분산 계산은 단순하다. [Docs]
df.cov()
공분산은 두 변수간 편차 곱의 평균으로 표현된다.
다시말해 한 변수만을 사용하여 공분산을 구하면 그게 곧 분산이다. ()
문제는 편차가 정규화되지 않았기 때문에 scale에 민감하다는 것이다.
이를 보완하고자 나온 것이 다음에 소개할 상관계수(Correlation)로, 공분산을 각 확률변수의 표준편차로 나누어준 것이다.
Correlation
흔히 사용되는 Correlation로는 Pearson과 Kendall, Spearman이 있다.
Default는 Pearson이며, 만약 방법을 지정하고싶다면 method=’kendall’과 같이 지정해줄 수 있다.
만약 커스텀 Correlation을 구하고싶다면 커스텀 함수를 만들어 method로 지정해주면 된다. [Docs]
Correlation를 계산하는 방법은 세 가지이다.
- 한 컬럼과 다른 모든 컬럼들의 Correlation (corrwith)
- 두 컬럼 간의 Correlation (corr)
- 모든 컬럼간의 Correlation (corr)
어쨋든 결과는 모두 동일하다.
어떤 결과만을 표시할지의 문제이다.
df.corrwith(df['avg'], method='spearman') # 'avg' 컬럼과 다른 모든 컬럼간의 Spearman Rank Correlation df['avg'].corr(df[5], method='kendall') # 'avg' 컬럼과 5 컬럼 간의 Kentall Tau Correlation df.corr(method='pearson') # 모든 컬럼 간의 Pearson Correlation
아래는 df.corr를 통한 모든 컬럼 간의 Correlation이다.
만약 결과를 Heatmap으로 보고싶다면 seaborn 패키지를 활용할 수 있다.
import seaborn as sb sb.heatmap(data = df.corr(), annot=True, fmt = '.2f', linewidths=.5, cmap='Blues')
cmap이나 annotation, 크기 등은 Docs를 보며 적절히 수정해주면 된다.
다음은 실행 결과이다.
아래와 같은 응용도 가능하다.
mask = np.zeros_like(df.corr()) mask[np.triu_indices_from(mask)] = True plt.rcParams["figure.figsize"] = (10,6) # 그림 크기 조정 sb.heatmap(data = df.corr(), mask=mask, annot=True, fmt = '.3f', linewidths=0, cmap='Greens')
Scatter Plot
Pandas Dataframe에서 특정한 두 컬럼을 x축, y축으로 설정하여 Scatter Plot을 그리는 방법이다.
필자는 ‘avg’ 컬럼을 x축으로, 5 컬럼을 y축으로 사용하였다.
import matplotlib.pyplot as plt dataframe.plot(kind='scatter',x='avg',y=5) plt.show()
Trend Line
numpy 패키지의 polyfit 함수를 통해 직선을 주어진 점에 fitting한다.
polyfit은 fitting 후 weight를 반환한다. [Docs]
그리고 poly1d는 weight를 이용해 1차함수를 반환한다. [Docs]
import numpy as np df.plot(kind='scatter', x='avg', y=5) fit_weight = np.polyfit(df['avg'], df[5], 1) # 'avg' 컬럼을 x값으로, 5 컬럼을 y값으로 하여 1차식으로 피팅한다. trend_f = np.poly1d(fit_weight) plt.plot(df['avg'], trend_f(df['avg']),"r-") plt.title("y={:.6f}x+({:.6f})".format(fit_weight[0], fit_weight[1])) plt.show()
R-square
R2를 계산하기 위해서는 데이터와 예측값이 필요하다.
위의 경우 사용할 데이터는 산점도이며 예측값은 추세선이 된다.
R2를 계산하기 위해 아래와 같이 동일한 x값에서의 y값을 준비한다.
r2_score 함수는 Docs에서 확인할 수 있다.
from sklearn.metrics import r2_score r2 = r2_score(df[5], trend_f(df['avg']))
최종적으로는 다음과 같은 결과를 얻을 수 있다.
df.plot(kind='scatter', x='avg', y=5) fit_weight = np.polyfit(df['avg'], df[5], 1) trend_f = np.poly1d(fit_weight) r2 = r2_score(df[5], trend_f(df['avg'])) plt.plot(df['avg'], trend_f(df['avg']),"r-") plt.title("y={:.6f}x+({:.6f}) [R2={:.6f}]".format(fit_weight[0], fit_weight[1], r2)) plt.show()