출처 : https://www.youtube.com/watch?v=9F4PZ_1orF0

xy좌표계의 basis vector : $\hat{i} , \hat j$ 기저벡터.

스칼라를 달리함으로써 다른 2차원벡터를 다 얻을 수 있어.

여기서 스칼라를 달리하면서 다른벡터를 얻는 과정을 두 벡터의 선형결합이라고 부른다.

두 basis vector가 같은 직선상에 위치한다면, 결과벡터의 끝점이 원점을 지나는 한 직선으로 제한되어버린다.

두 벡터가 영벡터인경우 → 원점에 갇힘

span

The set of all possible vectors that you can reach with a linear combination of a given pair of vectors called the span of those two vectors

주어진 벡터 쌍의 선형결합으로 다다를 수 있는 모든 결과벡터의 집합을 두 벡터의 생성(선형생성, span)이라고 한다.

두 벡터가 일직선위에 있다면 그들의 span은 단지 직선이다.

Linearly dependent 선형 종속

$\vec{u} = a\vec{v} + b\vec{w}$
벡터들 중 span의 축소 없이 하나를 제거해도 되는경우

벡터 중 하나가 다른 벡터들의 선형결합으로 표현될 수 있다는 말 (그 벡터는 이미 다른 벡터들의 span에 속하므로)

Linearly independent 선형 독립

$\vec{u} \neq a\vec{v}$ (모든 a에 대하여)
$\vec{u} \neq a\vec{v} + b\vec{w}$ (모든 a, b에 대하여)

출처 : [Linear Algebra] Lecture 9 선형 독립(Linear independence), Span, 기저(Basis) 그리고 차원(Dimension)

Vector Projection

두개의 벡터에서 둘 중 하나로 전사시키는것!

Vector Projection

($\mathbb{R}^{2}$ 공간에서의) Linear Projections
임의의 두 벡터 $\vec a, \vec b$ 가 있을 때, $\vec b$에 Projection된 벡터의 길이를 $\vec \mu$ 라고하자.
이 둘 사이의 각도를 $\theta$라고 하면, 코사인법칙에 의하여
$$\cos{\theta} ={{아래길이}\over {빗변} } = {|\vec \mu| \over {|\vec a|} } ={\vec {a}\cdot{\vec b}\over{|\vec a|\cdot|\vec{b}|}} $$ 이다.
이때, $|\vec \mu|$에 대하여 정리하면, $|\vec \mu| = {\vec a \cdot \vec b \over |\vec b|}$ 이다.
일단 이 상황에서, $\vec b$방향의 단위벡터 $\hat b$ 를 구하면, ${\hat b} = {\hat \mu} = {{1\over{|\vec b|}}\cdot{\vec b}}$ 이므로, 최종 !!
$${\vec \mu }= {{\vec {a} \cdot \vec {b} \over {|\vec b|^2} }\cdot{\vec b}}$$ 이다.
여기서 앞부분의 ${{\vec a \cdot \vec b \over {|\vec{ b}|^2} }}$ 은 스칼라값이다.!

2차원 벡터 프로젝션해보기

$y=x$ 라는 벡터에 projection한다.

v = [7, 4]

def vecmul(w,v):
    try: return np.array(list(map(lambda x : x[0]*x[1], zip(w,v))))
    except:
        if type(w)!=list: return list(map(lambda x :w*x , v))
        else: return list(map(lambda x : v*x, w))

def vecdot(w,v):
    try: return sum(list(map(lambda x : x[0]*x[1], zip(w,v))))
    except:
        if type(w)!=list: return sum(list(map(lambda x: w*x, v)))
        elif type(v)!=list: return sum(list(map(lambda x: v*x, w)))

def vecdiv(w,v):
    return np.array(list(map(lambda x : x[0]/x[1], zip(w,v))))

def myProjection(w , v=[1,1] ) :
    # 채우세요.
    w_prime = vecmul( vecdot(w,v) / vecdot(v,v) ,  v )

    return w_prime

# myProjection([7,4])
vprime = myProjection(v)
vprime

$\vec v = (7,4)$가 $(5,5)$가 되었다

plt.figure(figsize=(10,10))

x_minus_proj = list(map(lambda x : x[1]-x[0], zip(v,vprime)))

plt.plot(x_vals,y_vals,'--',color='r')
plt.xlim(-1,10)
plt.ylim(-1,10)
plt.arrow(0,0,v[0],v[1], head_width=.2, linewidth=3,head_length=.2, color='b')

plt.arrow(0,0,vprime[0],vprime[1], ls='--', head_width=.2, head_length=.2, color='g',linewidth=3)

plt.arrow(v[0],v[1],x_minus_proj[0],x_minus_proj[1], head_width=.2 , head_length=.2, color='y',linewidth=2)
plt.grid()
# axes.figure.figsize=(20,20)

'Linear Algebra' 카테고리의 다른 글

Vector, Scalar  (0) 2021.02.07

단순하게 생각하자!

스칼라 Scalar

단일 숫자. 변수에 저장할 때는 일반적으로 소문자를 사용

벡터 Vector

  • n차원의 벡터는 컴포넌트라 불리는 n개의 원소를 갖는 모음 (컴포넌트는 스칼라로 간주되지 않음)
    • 벡터는 일반적으로 위의 화살표를 갖는 소문자의 형태로 표기 $\vec{a}=$$n+1\brack 3$

    벡터의 크기 (Magnitude, Norm, Length)

  • 단순히 길이에 지나지 않음 → 피타고라스정리를 통해 길이를 구함
  • $|\vec{a}|$ 라고 표기
    • $\vec a = [1,3,3]$ → $|\vec a| = \sqrt{1^2+3^2+3^2}$

    벡터의 내적 (Dot Product)

    각 구성요소를 서로 곱한 후 합한 값과 같음.

    $v=[1,2,3,4]$ , $x=[5,6,7,8]$
    v $\cdot$ x = $15 +26+37+48$ = 70

벡터의 내적에서는 두 벡터의 길이가 반드시 동일해야함.
교환법칙 및 분배법칙 적용 가능.

매트릭스 (Matrix, 행렬)

행과 열을 통해 배치되어있는 숫자. 대문자를 통해 표기

(행,열)의 차원을 가짐.

전치행렬 (Transpose)

행과 열을 바꾼 행렬. rotation과는 조금 다름!

def transpose(mat):
    rows = len(mat)
    cols = len(mat[0])
    tmp=[[0 for _ in range(rows)] for _ in range(cols)]
    tmp=[]
    for i in range(cols): # 0 1 2
        temp=[]
        for j in range(rows): # 0 1 2 3
            temp.append(mat[j][i])
        tmp.append(temp)
    return tmp
F=[[15,2,8],[-15,-11,0],[-17,13,17],[-3,-16,-12]]
transpose(F)

'''
[[15, -15, -17, -3], [2, -11, 13, -16], [8, 0, 17, -12]]
'''
np.matrix(F).T
"""
matrix([[ 15, -15, -17,  -3],
        [  2, -11,  13, -16],
        [  8,   0,  17, -12]])"""

정사각 매트릭스 (Square Matrix)

  • 행과 열의 수가 동일한 행렬
  • Diagonal(대각) 대각선부분만 값이 있고, 나머지는 전부 0

Diagonal (대각): 대각선 부분에만 값이 있고, 나머지는 전부 0입니다.

Upper Triangular (상삼각): 대각선 위쪽 부분에만 값이 있고, 나머지는 전부 0입니다.

Lower Triangular (하삼각): upper triangular 와 반대로, 대각선 아래에만 값이 있습니다.

Identity (단위 매트릭스):

  • Diagonal 매트릭스 중에서, 모든 값이 1인 경우입니다. 임의의 정사각 매트릭스에 단위 행렬을 곱하면, 그 결과값은 원본 정사각 매트릭스로 나오며,
  • 반대로 임의의 매트릭스에 대해서 곱했을때 단위 매트릭스가 나오게 하는 매트릭스를 역행렬 (Inverse)라고 부릅니다.

def mkId(mat):
    row=len(mat)
    col=len(mat[0])
    tmp=[[0 for _ in range(row)] for _ in range(col) ]
    for i in range(row):
        for j in range(col):
            if i==j: tmp[i][j]=1
    return tmp
G=[[-17,11],[10,3]]
matmul(mkId(G),G)

Symmetric (대칭): 대각선을 기준으로 위 아래의 값이 대칭인 경우 입니다.

Determinant

행렬식은 모든 정사각 매트릭스가 갖는 속성으로, det(A) 혹은 |A| 로 표기된다.

def determinant(mat): #3x3까지만 처리...
    row=len(mat)
    col=len(mat[0])
    front=0
    back=0
    if row>2:
        for i in range(row):
            ff=1
            bb=1
            for k in range(row):
                #정방향
                x=k
                y=(i+k)%row

                #역방향
                yy=(row-1-k+i)%row

                ff = ff*mat[x][y]
                bb = bb*mat[x][yy]

            front+=ff
            back+=bb
    else:
        ff=1
        bb=1
        for i in range(row):
            ff=ff*mat[i][i]
            bb=bb*mat[i][row-i-1]
        front+=ff
        back+=bb
    return front-back    

H=[[8,18],[-4,12]]
J=[[-10,6,-6],[2,3,-2],[3,-1,-8]]
tmp=[[4,-3,0,1],
     [1,2,-1,2],
     [1,2,5,7],
     [4,3,2,2]]
determinant(H) , determinant(J)
# (168, 386)

np.linalg.det(H), np.linalg.det(J)#, np.linalg.det(tmp)

(167.99999999999997, 386.00000000000006)

Inverse 역행렬

행렬과 그 역행렬을 곱하면 언제나 I (단위행렬) 이 된다.

A$a b \brack c d$ → $A^{-1} =$ $1\over{ad-bc}$$b, -d\brack -c , d$

np.linalg.inv(H)

역행렬이 존재하지 않는경우!! → 특이행렬 (Singular Matrix)

Determinant 값이 0 이 되면, 역행렬 식에서 분모가 0 이 됨. →
매트릭스의 행과 열이 선형의 의존관계가 있는 경우

MSE (Mean Squared Error) 평균제곱오차

$1\over 𝑛$ $Σ^𝑛_1(𝑦_𝑖−𝑡_𝑖)^2$ 통계적 추정의 정확성에 대한 질적 척도수치가 작을수록 정확성이 높음 손실함수로 쓰임

MAE (Mean Absolute Error) 평균절대오차

실제 값과 측정(예측)값의 차이 $1\over {𝑛}$ ${Σ^𝑛_1|{𝑦_𝑖}−{𝑥}|}$ 회귀지표로써 사용됨

def mse(actual,predict):
    n=0
    sum=0
    for a,p in zip(actual,predict):
        sum += (a-p)**2
        n+=1
    return sum/n
def mae(actual, predict):
    n=0
    sum=0
    for a,p in zip(actual,predict):
        sum += abs(a-p)
        n += 1
    return sum/n

Orthogonal matrix 직교행렬

직교행렬은 정방행렬로 이것의 열과 행들은 Orthogonal(직교) 단위벡터가 된다.

즉, $Q^TQ = QQ^T = I$ 의 조건을 만족하면 Orthogonal Matrix라고 할 수 있다.

Q의 전치행렬과, 자기 자신 Q 를 곱했을 때 I(Identity 행렬)이 된다는 것은, Q의 전치행렬이 Q 의 역행렬과 같아지고, 이렇게 되면, 직교행렬이라고 부를 수 있다.

직교행렬 Q는 반드시 Intervible 해야하며, 또 다른 특징이 있다면 어떠한 직교행렬의 Determinant 는 +1 또는 -1 이다. 선형 변환으로써, 하나의 직교행렬은 백터의 내적을 보존하고, 따라서 유클리드 공간에서 isometry(등거리변환)으로써 작동한다. 예를들면 회전, 반영 또는 회전반영과 같은 것.

출처 : https://m.blog.naver.com/PostView.nhn?blogId=sw4r&logNo=221358626240&proxyReferer=https:%2F%2Fwww.google.com%2F

하우스 홀더 변환 (Householder Transformation)

하우스홀더행렬은 길이가 1인 Unit vector v에 대하여, 다음과 같이 정의됨

$H = I-2vv^T$

이렇게 만들어진 행렬 H 는 임의의 벡터 x에 곱했을 때, 벡터 v에 직교하는 평면에 대하여 벡터 x를 반전시킨다.
따라서 P = I-$2uu^T$ 일때, 다음과 같은 그림을 그려볼 수 있다.

이렇게 하우스홀더행렬은 벡터를 특정 평면에 대해 반전시킬 때 쓸 수 있다. (하우스홀더행렬도 직교행렬)

만약 벡터 x를 unit vector y의 방향으로 변환시키고 싶을 때? → 벡터 x를 unit vector y의 방향으로 변환시키면 |x|y가 될테니, 벡터x와 벡터|y|를 양분하는 평면의 normal vector(법선벡터)를 구해 v라고 하고, 이 벡터로 하우스홀더행렬을 구해 x에 곱하면 된다.

와.........너무어렵다........ 나중에 다시읽어보자

출처 : 파이썬으로 Linear Regression 해보기 - 우아한형제들 기술 블로그
(https://woowabros.github.io/study/2018/08/01/linear_regression_qr.html)

'Linear Algebra' 카테고리의 다른 글

Span, Vector Projection  (0) 2021.02.07

종속적(의존적) 관계에 놓인 사건들을 기반으로 확률을 구함
두 변수의 사전확률과 사후확률의 관계를 정의

베이즈주의 (Bayesian)

선택된 표본이 특정한 사건(부분집합)에 속한다는 가설, 명제, 신뢰도로 확률을 표현한다.
베이지안관점에서 사건(부분집합)은 원하는 답(표본)이 포함되어 있을 가능성이 있는 후보의 집합 이며, 이는 우리가 어떤 사건을 "이 사건속에 속한 원소 중 원하는 답이 있다로 주장하는것이다.
베이즈 정리를 통하여, 조건부 확률을 구하며
사전확률과 사후확률의 개념을 통하여 정보를 반영하는 식으로 사용한다.

dfnas.groupby('Genre').count() # 전체
dfnas.iloc[:1136].groupby('Genre').count() # 상위 10%

def 액션내면성공하니(성공확률, 액션l성공, 액션l실패):
    tpr=액션l성공
    fpr=액션l실패
    numerator= tpr * 성공확률
    denominator= numerator + ( fpr * (1 - 성공확률))
    return numerator/denominator
액션내면성공하니(0.1, 250/1136, 1675/(8546+1675))

상위 10%는 그냥 NA_Sales의 sort_value 함수를 통하여 내림차순으로 한 뒤 10%만큼인 1136라인까지를 사용하였다

 

tmp=액션내면성공하니(0.1, 250/1136, 1675/(8546+1675))
results=[]
for _ in range(20):
    results.append(tmp)
    tmp = 액션내면성공하니(tmp, 250/1136, 1675/(8546+1675))
results
tmp = pd.DataFrame(results, columns=['p'], index=range(1,21))
tmp.reset_index()

베이지안을 적용해서, 액션장르를 한번 출시할 때마다 성공확률이 어떻게 될지 테스트해보았다.

과연 이렇게 하는게 맞는지 한참을 고민했다.

참조 : 다크 프로그래머 :: 베이지언 확률(Bayesian Probability) (tistory.com) , 다크 프로그래머 :: 베이즈 정리, ML과 MAP, 그리고 영상처리 (tistory.com)

'Statistics' 카테고리의 다른 글

중심극한정리(CLT), 큰 수의 법칙(Law of large numbers)  (0) 2021.01.27
Covariance and Correlation 상관계수  (0) 2021.01.27
Chi-Square Test  (0) 2021.01.27
P-value란?  (0) 2021.01.27
T-Test, Chi-Square  (0) 2021.01.27

큰 수의 법칙 (Law of Large Numbers)

큰 수의 법칙은 동일한 조사를 여러 번 반복할 때, $\bar X$의 분포는 추출하는 표본의 갯수(n)에 의존한다는 것을 보여준다.

하지만, 실제 표본들의 평균($\bar X$)이 어떤 분포를 하는지에 대해서는 정보를 주지 않는다.그저 표본이 많으면 $\bar X$의 분산이 줄어들 것이라 것만 알려준다.

from scipy import stats
def getStdErr(samples, conf=0.95):
    n=len(samples)
    s=np.std(samples)
    return stats.t.ppf((1+conf)/2, n-1)*(s/np.sqrt(n-1))
def confidenceInterval(samples, conf=0.95):
    x= np.mean(samples)
    interval=getStdErr(samples)
               ##mean,     interval ,               interval length
    return round(x,5), [x-interval, x+interval], round(2*interval,5)
import pandas as pd
import numpy as np
dfraw = sns.load_dataset('penguins')
dfraw.dropna(axis=0,inplace=True)
dfraw.reset_index(drop=True, inplace=True)

samp1df=dfraw.sample(20, random_state=42)
samp1=samp1df['bill_depth_mm']
samp2df=dfraw.sample(200, random_state=42)
samp2=samp2df['bill_depth_mm']
len(samp1), len(samp2)
#  (20, 200)
confidenceInterval(samp1),confidenceInterval(samp2)
'''
((17.02, [16.040918665793555, 17.999081334206437], 1.95816),
 (17.2575, [16.987352342158953, 17.52764765784102], 0.5403))'''

신뢰 구간의 길이차이가 sample의 개수에 따라 많아질수록 짧아진다.

샘플수가 200개의 경우 20개보다 많아지다보니 더욱 모평균과 유사해지는 것이며, 동일한 confidence에 대해 더욱 예리해지는것과 같다고 볼 수 있다.

샘플의 수가 20개인 경우, 그것의 신뢰구간 길이는 1.95816이고, 이 경우, 1.95816길이의 구간 내에 모평균이 위치할 확률이 95%라는 의미.
200개인경우 0.5403인데, 200개샘플의 신뢰구간 길이가 더 작다.
이는 0.5403 길이의 구간 내에 모평균이 위치할 확률이 95%라는 의미

샘플 개수가 늘어남에따라 신뢰구간이 어떻게 변화하는지 그려보자

df7=pd.DataFrame({'sampleNumber':[i*10 for i in range(1,20)]})
df7['result']=df7['sampleNumber'].apply(lambda x: confidenceInterval(dfraw.sample(x, random_state=42)['bill_depth_mm']) )
df7['mean']=df7['result'].apply(lambda x: x[0])
df7['length']=df7['result'].apply(lambda x: x[2])
df7['st']=df7['result'].apply(lambda x: x[1][0])
df7['end']=df7['result'].apply(lambda x: x[1][1])
df7

plt.figure(figsize=(10,6))
plt.errorbar(x=df7['sampleNumber'], y=df7['mean'], yerr=df7['length'], fmt='o', capsize=5)
plt.xlabel('Sample Size',fontsize=20)
plt.ylabel('mean, interval',fontsize=20)
plt.show()

중심극한정리 (Central Limit Theorem)

The sample mean will be approximately normally distributed for large sample sizes, regardless of the distribution from which we are sampling.
샘플 데이터의 수가 많아질 수록(사이즈는 대략 30이상), 샘플의 평균은 정규분포에 근사한 형태로 나온다!

모집단에서 랜덤추출한 값의 평균을 반복해서 구하면 이 평균들은 정규분포를 따른다.

mean100list=[dfraw.sample(30)['bill_depth_mm'].mean() for _ in range(100)]
mean1000list=[dfraw.sample(30)['bill_depth_mm'].mean() for _ in range(1000)]
**plt.hist(x=mean100list)**

plt.hist(x=mean1000list)

동일하게 샘플사이즈 30으로 고정, 100번 추출한것과, 1000번 추출한것의 hist차이이다.

'Statistics' 카테고리의 다른 글

베이즈정리  (0) 2021.01.27
Covariance and Correlation 상관계수  (0) 2021.01.27
Chi-Square Test  (0) 2021.01.27
P-value란?  (0) 2021.01.27
T-Test, Chi-Square  (0) 2021.01.27

출처 : https://www.youtube.com/watch?v=RymrCV3K5J8 ← 상당히 좋음
[선형대수학 #6] 주성분분석(PCA)의 이해와 활용

양의 상관 → 두 변수가 동시에 커질때 (양의 연관성)

음의 상관 → 두 변수가 반대로 움직일 때 (음의 연관성)

무상관 → 상관이 없다 → 무상관이면 0에 가깝다

양의 상관에서는 + x + 또는 - x - 이므로 양의 값을 갖는다

음의 상관에서는 + x - 또는 - x + 이므로 음의 값을 갖는다

Cov값의 차이가 나타나는 이유 : (1)번이 X와 Y의 범위가 더 넓기 때문 -> 이를 표준화 해줘서 나오는게 상관계수야

상관계수는 수학적 관계이지, 속성의 관계는 아니다. 이는 선형관계의 측도이다. (곡선관계는 찾아내지 못한다)

연관성의 측도로 공분산을 사용 (Covariance == Cov)

X의 분산은 ? → X가 얼마나 퍼져있는가

Var(x) = $E(X-\mu_X)^2$

Y의 분산은 ? → Y가 얼마나 퍼져있는가

Var(Y) = $E(Y-\mu_Y)^2$

X,Y의 공분산은? → X,Y가 어떠한 방향성을 갖고있는가? → 이 공분산은 데이터가 얼마나 퍼져있냐에 따라 값의 차이가 있다

COV(X,Y) = $E(X-\mu_X)(Y-\mu_Y)$

X, Y 의 상관계수는? → 공분산의 표준화를 통하여, 얼마나 퍼져있든, 상관성을 볼수있다. 그러나 곡선관계는 해석이 불가하다.

Corr(X,Y) = $Cov(X,Y)\over{\sqrt{Var(X)*Var(Y)}}$ = $\rho$ → $-1\leq \rho \leq1$


import numpy as np
data=[243,278,184,249,207]
def mean(data):
    tmp=0
    n=0
    for i in data:
        tmp+=i
        n+=1
    return tmp/n
def var(data,df=0):#df = 1 :: 자유도 n-1 , df=0 : 자유도 n으로
    m=mean(data)
    n=0
    tmp = 0
    for i in data:
        tmp+=(i-m)**2
        n+=1
    return tmp/(n-df)
def std(data,df=0):
    variance=var(data)
    return variance**0.5
print('내가만든함수\t\t Numpy함수')
print(mean(data),'\t\t\t', np.mean(data))
print(var(data),'\t\t', np.var(data))
print(std(data),'\t', np.std(data))
"""
내가만든함수         Numpy함수
232.2              232.2
1090.96          1090.96
33.02968361943541      33.02968361943541
"""
# data
new=[88,89,83,112,104]
def cov(X,Y):
    muX=mean(X)
    muY=mean(Y)
    n=0
    up=0
    for x,y in zip(X,Y):
        n+=1
        up+=(x-muX)*(y-muY)
    return up/(n-1)

print(cov(data,new),'\n', np.cov(data,new)[0][1])
'''
71.69999999999999 ,  71.7     '''

def covv(X,Y): #sum, list, map, lambda , zip 이용해보기
    muX, muY = mean(X), mean(Y)
    return sum(list(map(lambda x : (x[0]-muX)*(x[1]-muY), zip(X,Y)))) / (len(X)-1)

covv(data,new) , cov(data,new) , np.cov(data,new)[0][1]
''' (71.69999999999999, 71.69999999999999, 71.7) '''
def corr(X,Y):
    muX, muY = mean(X), mean(Y)
    Sxx=sum(list(map(lambda x : (x-muX)**2, X)))
    Syy=sum(list(map(lambda y : (y-muY)**2, Y)))
    Sxy=sum(list(map(lambda x : (x[0]-muX)*(x[1]-muY), zip(X,Y))))
    return Sxy / ((Sxx**0.5)*(Syy**0.5))
corr(data,new),np.corrcoef(data,new)
'''
0.15868973512570766
array([[1.        , 0.15868974],
       [0.15868974, 1.        ]])
'''

Categorical 한 데이터에서의 상관관계 분석! → 스피어만 상관계수

R을 이용한 데이터 처리 & 분석 실무: 스피어만 상관 계수

스피어만 상관계수 (Spearman's Rank Correlation Codfficient)

두 데이터의 실제 값 대신, 두 값의 순위(rank)를 사용해 상관계수를 계산하는 방식이다.

피어슨상관계수와 마찬가지로 범위는 [-1,1]이며, 양의상관—음의상관을 나타낸다.

스피어만상관계수는 비선형관계의 연관성을 파악할 수 있다는 장점이 있다.

또한, 데이터의 순위만 매길 수 있다면 적용 가능하므로 연속형(Continuous) 데이터에 적합한 피어슨상관계수와 달리 이산형(Discrete)데이터, 순서형(Ordinal)데이터에 적용이 가능하다.

Ex. 국어점수와 영어점수의 상관계수 → 피어슨 , 국어석차와 영어석차의 상관계수 → 스피어만

$\rho =$ $\Sigma_i{(x_i-\overline{x})(y_i-\overline{y})}\over{\sqrt{\Sigma_i{(x_i-\overline{x}})}\sqrt{\Sigma_i{(y_i-\overline{y}})}}$ → $\rho = 1 -$ ${6\Sigma{d_i}^2}\over{n(n^2-1)}$ , $(d_i = x_i - y_i)$

$x_i$는 변수 x에서 i 번째 데이터의 순위
$y_i$는 변수 y에서 i 번째 데이터의 순위
$\overline{x}, \overline{y}$ 는 각각 x,y의 평균
여기서 $d = x_i - y_i$ 라고 하면, 식이 굉장히 간단해지는데,

from scipy import stats

data=[243,278,184,249,207]
new=[88,89,83,112,104]

def getRank(X): #주어진 list의 각각 랭크값을 반환 (동일값도 랭크증가)
    tmp=[]
    xrank=sorted(X, reverse=True)
    for x in X:
        tmp.append(xrank.index(x)+1)
    return tmp

def spearmanR(X,Y):
    xrank, yrank=getRank(X), getRank(Y)
    up = 6 * sum(list(map(lambda x : (x[0]-x[1])**2 , zip(xrank,yrank) ) ) ) 
    down=len(X) * (len(X)**2-1)
    return 1 - (up/down)

spearmanR(data,new), stats.spearmanr(data,new)
# (0.5 , SpearmanrResult(correlation=0.49999999999999994, pvalue=0.39100221895577053))

'Statistics' 카테고리의 다른 글

베이즈정리  (0) 2021.01.27
중심극한정리(CLT), 큰 수의 법칙(Law of large numbers)  (0) 2021.01.27
Chi-Square Test  (0) 2021.01.27
P-value란?  (0) 2021.01.27
T-Test, Chi-Square  (0) 2021.01.27

스킨 편집의 HTML에 아래 스크립트부분을 head 에 삽입

    <script type="text/javascript" async

src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-MML-AM_CHTML">

</script>

 

<script type="text/x-mathjax-config">

MathJax.Hub.Config({

  tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}

});

</script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-MML-AM_CHTML"></script>

관찰된 분포가 이론상의 분포에 얼마나 잘 맞는가?

범주형 자료에 대한 추론

https://miro.medium.com/max/1207/1*8afcwlzxwXCWT4ALtx-WSw.png

one-sample 카이제곱값을 구하는 코드 만들어보기!

import numpy as np
import pandas as pd
### 1. 넘파이 이용
## 넘파이를 통한 구현
ar1=np.array(df1)
ar2=ar1.mean()
arr_chi=(ar1-ar2)**2/ar2
chi=arr_chi.sum()
chi

### 2. DataFrame 사용
df4=pd.DataFrame(df1)
mean=df4.DT.sum()/4 #979.25
df4['expected']=mean
df4['up'] = df4.apply(lambda x: 
               (x['DT']-x['expected'])**2 ,axis=1)
df4['chi']=df4.apply(lambda x: 
                x['up']/x['expected'], axis=1)
df4.chi.sum()

### 3. stats module 사용
stats.chisquare(df1)[0]

지역에 대한 1샘플 카이제곱검정

지역별 미분양 주택수의 합이 같은가 다른가?

import pandas as pd
import numpy as np
import seaborn as sns
import requests
#8월지정
url1='https://kosis.kr/openapi/Param/statisticsParameterData.do?method=getList&apiKey=NzE2OGY3ODQxZjNkMWMyOWUyYTYxMjVhN2UxOGRlNzI=&itmId=13103792722T1+&objL1=ALL&objL2=ALL&objL3=ALL&objL4=&objL5=&objL6=&objL7=&objL8=&format=json&jsonVD=Y&prdSe=M&startPrdDe=202008&endPrdDe=202008&loadGubun=2&orgId=116&tblId=DT_MLTM_2080'
response=requests.get(url1)
json=response.json()
dfraw=pd.json_normalize(json)
dfraw.fillna(0)
dfraw2 = dfraw[dfraw.columns[-6:]]
dfraw2

기본 전처리

df=dfraw2.query("(C1_NM=='서울' or C1_NM=='대전'or C1_NM=='대구'or C1_NM=='부산' )")
df.drop(columns=['PRD_SE','C1'], inplace=True)
select=df.C3_NM.unique()[2:] #array(['60㎡이하', '60〜85㎡', '85㎡초과'], dtype=object)
df['TF']=df.C3_NM.apply(lambda x: None if x=='총합' or x=='소계' else x)
df.dropna(axis=0, inplace=True)
df4.reset_index(drop=True, inplace=True)
df['DT']=df.DT.astype('int')
df1=df.groupby("C1_NM").sum()['DT']
df, df1

from scipy import stats
result = stats.chisquare(df1)
result
#  Power_divergenceResult(statistic=1564.4572376818994, pvalue=0.0)

결과

$𝐻_0$ : 지역별 미분양 주택수의 합은 같다. (고르게 분포)
$𝐻_1$ : 지역별 미분양 주택수의 합이 같지 않다. (고르지 않게 분포)
𝛼 : 0.05
𝑃−𝑣𝑎𝑙𝑢𝑒 : 0.0
따라서 귀무가설 기각. 대립가설 채택.
지역별 미분양 주택수의 합이 고르지 않게 분포하였다
(지역별 차이가 존재한다)

 


지역과 규모에 대하여 two sample chi square test

기본 전처리

tmp=df.query('C2_NM=="민간부문"').set_index(['C1_NM','TF'])['DT'].unstack()
cols=tmp.columns
tmp=tmp[[cols[1],cols[0],cols[2]]]
tmp

카이제곱 검정 시행

chi, p, dof, expected = stats.chi2_contingency(tmp)
print(f"chi 스퀘어 값: {chi}",
      f"p-value (a = 0.05): {p}",
      f"자유도 수: {dof}",
      f"기대값: \n{pd.DataFrame(expected)}",
      f"측정값: \n{tmp}", sep = "\n" )

결과

$𝐻_0$ : 지역별 그룹(평수) 간 차이가 없다
$𝐻_1$ : 지역별 그룹(평수) 간 차이가 있다.
𝛼 : 0.05
𝑃−𝑣𝑎𝑙𝑢𝑒 : 0.0
따라서 귀무가설 기각. 대립가설 채택.
지역별 평수가 고르지 않게 분포하였다
(지역별 평수간 차이가 존재한다)

참고 : https://m.blog.naver.com/PostView.nhn?blogId=parksehoon1971&logNo=221589203965&proxyReferer=https:%2F%2Fwww.google.com%2F
https://stackoverflow.com/questions/11725115/p-value-from-chi-sq-test-statistic-in-python

'Statistics' 카테고리의 다른 글

중심극한정리(CLT), 큰 수의 법칙(Law of large numbers)  (0) 2021.01.27
Covariance and Correlation 상관계수  (0) 2021.01.27
P-value란?  (0) 2021.01.27
T-Test, Chi-Square  (0) 2021.01.27
Type of Error  (0) 2021.01.27

P-value란?

검정통계량에대한 확률로, 우리가 얻은 검정통계량보다 크거나 같은 값을 얻을 수 있는 확률

여기서 계산하는 검정통계량들은 대부분이 귀무가설을 가정하고 얻게되는 값이라는점!

p-value는 귀무가설을 기각하면 안되는데, 기각할 확률이다. 여기서 귀무가설을 잘못 기각했는지, 맞게 기각했는지 확인할 수 없다.

가설검증이라는 것은 전체 데이터의 일부만을 추출하여 평균을 내고, 그 평균이 전체 데이터의 평균을 잘 반영한다는 가정 하에 전체 데이터의 평균을 구하는 작업인데, 아무리 무작위 추출을 잘한다 하더라도 추출된 데이터의 평균은 전체 데이터의 평균에서 멀어질 수 있음.
따라서 내가 추출한 데이터의 평균이 원래의 전체 데이터의 평균과 얼마나 다른 값인지를 알 수 있는 방법이 필요함. 그래서 나온게 p-value

t-value는 두 표본에 대해서 표본 집단 평균 간의 차이에, 그 차이에 대한 불확실도를 나눠줌으로써 집단간의 차이와 이 차이가 얼마나 확실한지를 한꺼번에 설명해준다. 그래서 검정통계량만을 제시함으로써 엄밀하고도 편리한 방식으로 두 표본 집단간의 차이를 표현할 수 있게 되었다.

그러나 t-분포는 표본수(자유도)에 따라 모양이 다르다보니 같은 t-value라고 하더라도 표본수에 따라서 표본 간의 차이가 충분히 크다고 할 수도 있고, 그렇지 않다고 할 수도 있는것이다. 그렇기에 p-value와 같은 확률로 유의성을 점검할 수 있는 지표로 기재했기에, 표본수에 관계없이, 검정통계량의 분포의 모양에 상관없이 확률이라는 값 하나만 기재하여 헷갈리지 않게 사용하는것.

P값이 선택된 유의수준보다 작다면, 귀무가설 $H_0$을 기각하고, 대립가설$H_a$을 수용.
P값이 유의수준보다 크거나 같다면, 귀무가설을 기각하지 못함 → 그러나 무조건적으로 $H_0$을 수용한다는 뜻은 아님!

출처 : 칸아카데미, 공대생의수학노트

'Statistics' 카테고리의 다른 글

Covariance and Correlation 상관계수  (0) 2021.01.27
Chi-Square Test  (0) 2021.01.27
T-Test, Chi-Square  (0) 2021.01.27
Type of Error  (0) 2021.01.27
Hypothesis Test 가설검정  (0) 2021.01.27

 

T-test

표본집단의 평균을 비교하고 싶을 때 선택
Sample 개수에 따라 one-sample t-test, Two sample T-test로 나뉨.

One sample T-test

1개의 샘플값들의 평균특정 값과 동일한지 비교.

정규화

$t =$ $\overline{X}-\mu\over{S\over{\sqrt{n}}}$

평균을 빼고 표준편차로 나눠준다! -> 주어진 데이터는 평균이 0, 표준편차가 1인 데이터로 Scaling 된다.

1 sample t test

서울시 가로수 데이터셋을 이용하였다.

서울시에는 구별로 이팝나무가 평균 400그루이다. 에 대한 검정

import pandas as pd

trees = pd.read_csv(url, sep = '\\t', skiprows = 1)
trees = trees.replace({'-':0})
trees.head(5)
# 기초 전처리
df = trees[['자치구','느티나무','왕벚나무','은행나무','이팝나무','양버즘나무']].query("자치구.str.endswith('구')", engine='python')
for col in df.columns[1:]:
    df[col]=df[col].apply(lambda x : int(x.replace(',','')))

가설 검정
$H_0$: 이팝나무의 평균이 400이 맞다.
$H_1$: 이팝나무의 평균이 400이 아니다.
유의수준 $\alpha$ : 0.05

테스트 결과 p-value = 0.002로 (p값이 유의수준보다 작다) 대립가설 $H_1$ 채택.
이팝나무의 평균이 400이 아니라고 유의수준 0.05에서 말할 수 있다.

Two sample T-test

two sample 또한 표본집단의 평균을 비교한다는 점에서는 one sample과 동일하다.
다만, one sample 에서는 표본집단의 평균이 특정한 값을 비교하는것이고, two sample 에서는 표본집단 A와 다른 표본집단 B와의 평균을 비교할 때 사용.

언제활용되는지, 언제응용할수있는지, 코드를 사용할수있어야한다

1) 한 집단 평균 검정- 하나의 데이터 집단의 평균과 비교하고자 하는 관측치를 통해 차이를 검정하는 방법이다.- 데이터 집단의 평균과 거리가 멀 수록 p-value 유의수준의 값이 떨어진다.- stats.ttest_1samp() 이용

one_sample = [177.3, 182.7, 169.6, 176.3, 180.3, 179.4, 178.5, 177.2, 181.8, 176.5]
print(mean(one_sample)   # 177.96
result = stats.ttest_1samp(one_sample, 175.6)   # 비교집단, 관측치

print('t검정 통계량 = %.3f, pvalue = %.3f'%(result))  

# t검정 통계량 = 2.296, pvalue = 0.072

2) 두 집단 평균 검정 - 두 데이터 집단간의 비교 - stats.ttest_ind(x,y) 이용

female = [63.8, 56.4, 55.2, 58.5, 64.0, 51.6, 54.6, 71.0]
male = [75.5, 83.9, 75.7, 72.5, 56.2, 73.4, 67.7, 87.9]
result = stats.ttest_ind(male, female)

print("t검정 통계량: %.3f, pvalue=%.3f"%(result)) 

# t검정 통계량 = 3.588, pvalue = 0.003

3) 대응 두 집단 ** - 복부 수술전 9명의 몸무게와 복부 수술후 몸무게 변화 - before 와 after의 변화가 얼마나 대응 되는지- stats.ttest_rel(x,y) 이용

baseline = [67.2, 67.4, 71.5, 77.6, 86.0, 89.1, 59.5, 81.9, 105.5]
follow_up = [62.4, 64.6, 70.4, 62.6, 80.1, 73.2, 58.2, 71.0, 101.0]
paried_sample = stats.ttest_rel(baseline, follow_up)

print('t검정 통계량 = %.3f, pvalue = %.3f'%paired_sample)  

# t검정 통계량 = 3.668, pvalue = 0.006

출처 : https://m.blog.naver.com/BlogTagView.nhn?blogId=nonamed0000&pushNavigation=true&tagName=


2-sample t test

평균 느티나무 수가 왕벚나무수보다 큰가? 에 대한 가설검정을 실시

구별 평균 느티나무수와 왕벚나무수의 차이가 없다 가설검정
A : 평균 느티나무 수
B : 평균 왕벚나무 수
$H_0$: A $=$ B
$H_0$: A $\neq$ B
$\alpha$: 0.05
등분산검정 이후
p-value : 0.646
유의수준 0.05에서 귀무가설 채택
평균의 차이가 있다고 말할 수 없다.

In [ ]:df.head(5)
Out[ ]:

자치구    느티나무    왕벚나무    은행나무    이팝나무    양버즘나무
1    종로구    619    421    4072    711    1071
2    중구    460    289    3640    470    162
3    용산구    373    262    4444    198    1422
4    성동구    1975    602    1090    709    2401
5    광진구    1057    940    1247    760    2306

등분산 검정

$H_0$ : 모든 분산이 동일함
$H_1$ : 모든 분산이 동일하지 않음
F(집단간 분산 / 집단내 분산) 값이 0.628이고,
p-value가 0.432로 유의수준 0.05보다 크다. 따라서, 귀무가설을 채택, 등분산성이있다. (분산이동일함)

In [ ]:
stats.levene(df['왕벚나무'],df['느티나무'])
Out[ ]:
LeveneResult(statistic=0.628175868691159, pvalue=0.4319252158673391)

등분산성 검정 이후, 2-sample t test

In[ ]:
stats.ttest_ind(df['왕벚나무'],df['느티나무'], equal_var=True)

Out[ ]: 
Ttest_indResult(statistic=-0.4629256014492562, pvalue=0.6455096880085703)

'Statistics' 카테고리의 다른 글

Covariance and Correlation 상관계수  (0) 2021.01.27
Chi-Square Test  (0) 2021.01.27
P-value란?  (0) 2021.01.27
Type of Error  (0) 2021.01.27
Hypothesis Test 가설검정  (0) 2021.01.27

Type of Error

1종 오류

귀무가설이 참인 상황에서, 표본이 낮은 확률을 뚫고 기각역에서 뽑힐 때 발생.

그럴리 없다고 생각해서 기각했는데 그런 일이 생겨버린거임!

기각역이 차지하는 넓이는 유의수준과 같음. 따라서 1종 오류가 발생할 확률은 유의수준 $\alpha $임. → 1종 오류를 $\alpha$오류 라고도 함

→ 귀무가설이 참일 때, 1종 오류가 발생하지 않을 확률은 $1-\alpha$ 이다.

2종 오류

귀무가설이 거짓인 상황에서 발생.

누군가 귀무가설의 평균이 A 라 주장, 그러나 실제 평균은 $\mu$ 일때, 표본평균의 분포인데, 귀무가설이 주장하는 분포는 표본 평균의 평균이 A인 분포가 되는것임.

실제의 분포는 A와는 다른 평균을 갖는 분포임. 이 두개를 그려보면 아래와같음.

우리가 표본을 뽑는 모집단의 실제 분포는 오른쪽 분포임. 귀무가설이 거짓임에도 채택할 확률은 $\beta$ 임. → 2종 오류의 확률은 $\beta$ 임. 2종오류 = $\beta$ 오류

귀무가설이 거짓일 때 2종 오류가 발생하지 않을 확률은 1-$\beta$ 이다. (== 귀무가설이 거짓인 상황에서 옳은 결정을 할 확률)

'Statistics' 카테고리의 다른 글

Covariance and Correlation 상관계수  (0) 2021.01.27
Chi-Square Test  (0) 2021.01.27
P-value란?  (0) 2021.01.27
T-Test, Chi-Square  (0) 2021.01.27
Hypothesis Test 가설검정  (0) 2021.01.27

+ Recent posts