기본 콘텐츠로 건너뛰기

[matplotlib]quiver()함수

데이터 특성찿기

다음 테이블에서 속성(attribute)는 설명변수(독립변수), 라벨(labels)은 반응변수(종속변수)를 나타낸다.

사용자ID속성1속성2속성3라벨
016.5Male12120
144.2Female17270
275.7Male375
385.8Female860

위의 데이터는 행과 열로 구성되어 있다. 
각 행은 각 사용자에 속한 속성들을 나타내고 이는  instance, example, observation으로 명명된다. 
열은 다양한 이름으로 명칭된다. 즉, 
속성들은 Predictors(예측자), Features, 독립변수, 입력변수(inputs)로 나타내고 
라벨은 , 결과변수(output), targets, 종속변수, 반응변수로 나타낸다. 

위 테이블의 데이터 타입은 수치변수(속성1, 속성3, 라벨)와 목록변수(factor, 속성2)로 구성되어있다. 그러나 대부분의 기계학습의 알고리즘에서는 목록변수를 처리할 수 없다. 그러므로 목록변수는 수치변수로 전환되되야 한다. 

독립변수가 위 태이블과 같이 수치형인 경우 regression 분석 문제로 귀결되고 다음 테이블과 같이 반응변수를 True, False와 같이 목록변수로 변화시킨 경우 분류문제(classification problem)가 된다. 

위 테이블은 pandas의 DataFrame 구조이다. 이 구조의 기본 통계량에 대한 정보는 
pd.describe()에 의해 나타낼 수 있다. 이 함수는 수치변수인 변수만을 선별적으로 계산된다. 
print(d.describe())
       사용자ID     속성1      속성3        라벨 
count  4.000000  4.000000   4.000000    4.00000
mean   5.000000  5.550000  10.000000  266.25000
std    3.162278  0.967815   5.944185  237.60524
min    1.000000  4.200000   3.000000   75.00000
25%    3.250000  5.325000   6.750000  108.75000
50%    5.500000  5.750000  10.000000  195.00000
75%    7.250000  5.975000  13.250000  352.50000
max    8.000000  6.500000  17.000000  600.00000

그러나 열기준으로 행단위의 계산은 이루어지지 않는다. 행단위의 통계량을 나타내기 위해 
데이터를 보다 근원구조인 numpy 구조로 전환한여 다음의 함수들을 결합하여 (np.apply_along_axid() 함수와 평균, 표준편차등) 새로운 함수를 생성하여 사용한다. 

def StatDescribeS(data, ax=0):
    cnt=data.size
    mu=np.apply_along_axis(np.mean, ax, data)
    sd=np.apply_along_axis(np.std, ax, data)
    quantile=np.percentile(data, [0, 25, 50, 75, 100],ax)
    return({'count':cnt, 'mean':mu, 'std':sd, 'quantile':quantile})

우선 위 데이터를 numpy 구조 즉, 행렬 구조로 전환한다.
d1=np.array(d)
print(d1)
[[1 6.5 'Male' 12 120]
 [4 4.2 'Female' 17 270]
 [7 5.7 'Male' 3 75]
 [8 5.8 'Female' 8 600]]
또한 수치형태인 자료만을 계산한다.  
StatDescribeS(d1[:,[1,3,4]], 1)
{'count': 12, 'mean': array([  46.16666667,   97.06666667,   27.9       ,  204.6       ]), 'std': array([  52.25631275,  122.39393594,   33.32296505,  279.59146387]), 'quantile': array([[6.5, 4.2, 3.0, 5.8],
       [9.25, 10.6, 4.35, 6.9],
       [12.0, 17.0, 5.7, 8.0],
       [66.0, 143.5, 40.35, 304.0],
       [120.0, 270.0, 75.0, 600.0]], dtype=object)}
다음은 google finance로 부터 kopsi 일일 주가 자료를 호출하여 열이름 Open, High, Low, Close, Volume의 요약 통계량을 나타내었다.
이 작업을 수행하기 위해 몇개의 패키지를 인스톨 할 필요가 있다. 
또한 호출한 데이터는 pandas의 DataFrame 구조로서 pd.describe()로 결과가 반환된다. 
import numpy as np import pandas as pd from datetime import datetime import matplotlib.pyplot as plt from pandas_datareader import data, wb import pandas_datareader.data as web

startD=datetime(2010, 1, 1)
endD=datetime(2017, 3, 31)
k=web.DataReader("KRX:kospi", "google", startD,  endD)

k.head(3)

OpenHighLowCloseVolume
Date
2010-01-041681.711696.141681.711696.14295646000
2010-01-051701.621702.391686.451690.62407629000
2010-01-061697.881706.891696.101705.32425407000

print(k.describe())
         Open         High          Low        Close        Volume
count  1790.000000  1790.000000  1790.000000  1790.000000  1.790000e+03
mean   1950.969156  1959.133190  1939.760201  1949.901078  3.799980e+08
std     117.482559   116.535986   118.413943   117.268913  1.205752e+08
min    1550.800000  1566.300000  1532.680000  1552.790000  1.688330e+08
25%    1901.332500  1912.285000  1889.037500  1900.855000  3.007880e+08
50%    1973.765000  1981.565000  1964.120000  1971.365000  3.586785e+08
75%    2023.225000  2030.902500  2015.360000  2024.847500  4.284352e+08
max    2225.950000  2231.470000  2202.920000  2228.960000  1.209791e+09

이하 대부분의 분석을 위해 중요한 요소가 데이터의 정규분포 부합성이다. 
이 가정에 부합성을 검정할 수 있는 간단한 방법으로 qqplot을 그려보는 것으로 결과로 나타나는 선에 큰 편차를 보이지 않는다면 정규성에 부합한다고 할 수 있다. 
물론 자세한 정량적 분석을 실행할 있지만 지금은 data의 특성을 분석하는 것으로서 대략적인 개괄을 파악하는 것으로 유용한 방법이다. 
이 분석을 시행하기 위해서는 위의 패키지 외에 다음의 패키지가 필요하다. 
from scipy import stats
k1=k.ix[datetime(2017,1,1):, :]
k1.head(2)
OpenHighLowCloseVolume
Date
2017-01-022022.232031.792015.682026.16229874000
2017-01-032034.312044.072028.472043.97268127000

ax1=plt.subplot(221)#221:2개의 행, 2개의 열에서 1번째
stats.probplot(k1['Open'], dist='norm', plot=plt)
ax1=plt.subplot(222)
stats.probplot(k1['Close'], dist='norm', plot=plt)
ax1=plt.subplot(223)
stats.probplot(k1['Close'], dist='norm', plot=plt)
ax1=plt.subplot1(224)
stats.probplot(k['Close'], dist='norm', plot=plt)
plt.show()

이 그래프에 의해 이상치의 존재 가능성을 관찰할 수 있다.
다음은 위 k1 데이터에 Open, Close를 비교하여 그 차이에 따른 inc, dec 값을 추가 하였다. 
이 과정에서 lambda함수와 list comprehension을 사용하였다. 
lambda 함수를 간단한 사용자 정의 함수를 만드는 python의 축약함수이다. 
즉, 다음의 lambda 함수는 두 값을 전달받아 각 값의 크기를 비교하여 inc, dec를 지정하는 함수이고
comprehension list를 적용하여 데이터의 각행에 이 함수를 적용하였다.

y=lambda a, b: 'inc' if(a< b) else 'dec'
idx=[y(k1.ix[i,'Open'], k1.ix[i, 'Close']) for i in range(len(k1))] 

k1.head(3)  
OpenHighLowCloseVolumeidx
Date
2017-01-022022.232031.792015.682026.16229874000inc
2017-01-032034.312044.072028.472043.97268127000inc
2017-01-042046.292046.292040.612045.64371488000dec
위 데이블에서 'idx'열은 명목변수로 구성되어 있다. 그러므로 통계량 계산이 이루어지지 않는다.
그러므로 다음과 같이 수치형으로 전환하여야 한다. 
(위 테이블에서 idx 열을 삭제한다. k1.drop('idx', axis=1))

y=lambda a, b: 1 if(a< b) else 0
idx=[y(k1.ix[i,0],k1.ix[i,3]) for i in range(len(k1))]
k1.insert(5, "idx", idx)
k1.head(3)

OpenHighLowCloseVolumeidx
Date
2017-01-022022.232031.792015.682026.162298740001
2017-01-032034.312044.072028.472043.972681270001
2017-01-042046.292046.292040.612045.643714880000

추가한 열 idx에서의 0과 1의 빈도수를 계산하기 위해 np.histgroam(객체, bins)를 적용한다. 

"idx"는 0과 1로 구성되었으므로 bins=2로 지정한다. 

np.histogram(k2['idx'], bins=2)

(array([29, 28], dtype=int64), array([ 0. ,  0.5,  1. ]))
데이터내의 각 변수(열)들의 상호 관련성을 평가하기 위해 pd.corr() 메소드를 사용한다. 
일반적으로 correlation 분석은 ‘pearson’, ‘kendall’, ‘spearman’ 방법을 사용한다.
pd.corr()메소드 실행에 있어 method의 매개변수의 인자를 지정하여 
분석 방법의 변화를 가져올 수 있다.
 
k1.corr(method="pearson")

OpenHighLowCloseVolumeidx
Open1.0000000.9838150.9884830.971236-0.104649-0.055146
High0.9838151.0000000.9866220.991273-0.1097640.050897
Low0.9884830.9866221.0000000.988284-0.1259020.053133
Close0.9712360.9912730.9882841.000000-0.1533660.134952
Volume-0.104649-0.109764-0.125902-0.1533661.000000-0.104735
idx-0.0551460.0508970.0531330.134952-0.1047351.000000
Pearson 상관계수는 다음과 같이 정의 된다. 변수 x, y에 대해 
(x-mean(x))(y-mean(y))/((x-mean(x))^2(y-mean(y))^2)과 같이 계산된다. 
이 계산을 함수로 만들어 사용해 보자. 
 def corr_PearsonS (x, y):
    x1=x-np.mean(x)
    y1=y-np.mean(y)
    numer=np.dot(np.transpose(x1), y1)
    denum1=np.dot(np.transpose(x1), x1)
    denum2=np.dot(np.transpose(y1), y1)
    return(numer/(np.dot(denum1, denum2))**0.5)

[corr_PearsonS (k1['Open'], k1[i]) for i in ['High', 'Low', 'Close']]
[0.98381510600243327, 0.98848326869722414, 0.97123638681982993]

각 변수에 대한 상관성을 그래프로 나타내기 위해 pandas 패키지의 
scatter_matrix를 적용한다. 
from pandas.tools.plotting import scatter_matrix

scatter_matrix(k1.ix[:, :4])
plt.show()

각 변수의 분포를 확인하기 위해 boxplot을 이용한다. 
plt.boxplot()를 적용하는데 여러 변수를 동시에 그릴 경우 객체는 numpy 객체이어야 한다. 

x=np.array(k1.ix[:,:4])
plt.boxplot(x)
plt.show()

댓글

이 블로그의 인기 게시물

[Linear Algebra] 유사변환(Similarity transformation)

유사변환(Similarity transformation) n×n 차원의 정방 행렬 A, B 그리고 가역 행렬 P 사이에 식 1의 관계가 성립하면 행렬 A와 B는 유사행렬(similarity matrix)이 되며 행렬 A를 가역행렬 P와 B로 분해하는 것을 유사 변환(similarity transformation) 이라고 합니다. $$\tag{1} A = PBP^{-1} \Leftrightarrow P^{-1}AP = B $$ 식 2는 식 1의 양변에 B의 고유값을 고려한 것입니다. \begin{align}\tag{식 2} B - \lambda I &= P^{-1}AP – \lambda P^{-1}P\\ &= P^{-1}(AP – \lambda P)\\ &= P^{-1}(A - \lambda I)P \end{align} 식 2의 행렬식은 식 3과 같이 정리됩니다. \begin{align} &\begin{aligned}\textsf{det}(B - \lambda I ) & = \textsf{det}(P^{-1}(AP – \lambda P))\\ &= \textsf{det}(P^{-1}) \textsf{det}((A – \lambda I)) \textsf{det}(P)\\ &= \textsf{det}(P^{-1}) \textsf{det}(P) \textsf{det}((A – \lambda I))\\ &= \textsf{det}(A – \lambda I)\end{aligned}\\ &\begin{aligned}\because \; \textsf{det}(P^{-1}) \textsf{det}(P) &= \textsf{det}(P^{-1}P)\\ &= \textsf{det}(I)\end{aligned}\end{align} 유사행렬의 특성 유사행렬인 두 정방행렬 A와 B는 'A ~ B' 와 같...

[sympy] Sympy객체의 표현을 위한 함수들

Sympy객체의 표현을 위한 함수들 General simplify(x): 식 x(sympy 객체)를 간단히 정리 합니다. import numpy as np from sympy import * x=symbols("x") a=sin(x)**2+cos(x)**2 a $\sin^{2}{\left(x \right)} + \cos^{2}{\left(x \right)}$ simplify(a) 1 simplify(b) $\frac{x^{3} + x^{2} - x - 1}{x^{2} + 2 x + 1}$ simplify(b) x - 1 c=gamma(x)/gamma(x-2) c $\frac{\Gamma\left(x\right)}{\Gamma\left(x - 2\right)}$ simplify(c) $\displaystyle \left(x - 2\right) \left(x - 1\right)$ 위의 예들 중 객체 c의 감마함수(gamma(x))는 확률분포 등 여러 부분에서 사용되는 표현식으로 다음과 같이 정의 됩니다. 감마함수는 음이 아닌 정수를 제외한 모든 수에서 정의됩니다. 식 1과 같이 자연수에서 감마함수는 factorial(!), 부동소수(양의 실수)인 경우 적분을 적용하여 계산합니다. $$\tag{식 1}\Gamma(n) =\begin{cases}(n-1)!& n:\text{자연수}\\\int^\infty_0x^{n-1}e^{-x}\,dx& n:\text{부동소수}\end{cases}$$ x=symbols('x') gamma(x).subs(x,4) $\displaystyle 6$ factorial 계산은 math.factorial() 함수를 사용할 수 있습니다. import math math.factorial(3) 6 a=gamma(x).subs(x,4.5) a.evalf(3) 11.6 simpilfy() 함수의 알고리즘은 식에서 공통사항을 찾아 정리하...

sympy.solvers로 방정식해 구하기

sympy.solvers로 방정식해 구하기 대수 방정식을 해를 계산하기 위해 다음 함수를 사용합니다. sympy.solvers.solve(f, *symbols, **flags) f=0, 즉 동차방정식에 대해 지정한 변수의 해를 계산 f : 식 또는 함수 symbols: 식의 해를 계산하기 위한 변수, 변수가 하나인 경우는 생략가능(자동으로 인식) flags: 계산 또는 결과의 방식을 지정하기 위한 인수들 dict=True: {x:3, y:1}같이 사전형식, 기본값 = False set=True :{(x,3),(y,1)}같이 집합형식, 기본값 = False ratioal=True : 실수를 유리수로 반환, 기본값 = False positive=True: 해들 중에 양수만을 반환, 기본값 = False 예 $x^2=1$의 해를 결정합니다. solve() 함수에 적용하기 위해서는 다음과 같이 식의 한쪽이 0이 되는 형태인 동차식으로 구성되어야 합니다. $$x^2-1=0$$ import numpy as np from sympy import * x = symbols('x') solve(x**2-1, x) [-1, 1] 위 식은 계산 과정은 다음과 같습니다. $$\begin{aligned}x^2-1=0 \rightarrow (x+1)(x-1)=0 \\ x=1 \; \text{or}\; -1\end{aligned}$$ 예 $x^4=1$의 해를 결정합니다. solve() 함수의 인수 set=True를 지정하였으므로 결과는 집합(set)형으로 반환됩니다. eq=x**4-1 solve(eq, set=True) ([x], {(-1,), (-I,), (1,), (I,)}) 위의 경우 I는 복소수입니다.즉 위 결과의 과정은 다음과 같습니다. $$x^4-1=(x^2+1)(x+1)(x-1)=0 \rightarrow x=\pm \sqrt{-1}, \; \pm 1=\pm i,\; \pm1$$ 실수...