통계

결정계수와 p-value 파이썬으로 구해보기

이석사 중 2022. 12. 9. 11:26
728x90

오늘부터 본격적으로 적합성 검사 라이브러리를 만들어보겠습니다!


기초)

먼저 라이브러리를 만들기 전에 조금에 통계학적 지식이 필요합니다

 

저희가 적합성 검사를 하는 이유는 제가 입력시켜준 자료에 모델이 적합한지를 확인하기 위해서입니다

 

통계에서 가설을 검정하기 위해서는 대립가설과 귀무가설을 사용합니다

 

조금 어려운 말 같아 보이지만 이렇게 이해하면 쉽습니다

 

대립 가설 : 내가 검정하고 싶은 것, 증명하고 싶은 것, 확인하고 싶은 것

귀무 가설 : 대립 가설과 정반대되는 가설

 

그러면 적합성에 이 두 가설을 적용시켜봅시다

 

우리가 적합성을 검사를 하는 이유를 모델이 내 자료에 적합한지 확인하기 위해서라고 했져??

 

그러면 대립 가설이 '모델이 내 자료에 적합하다' 로 설정이 됩니다

 

반대로 귀무 가설은 '모델이 내 자료에 적합하지 않다'로 설정이 가능하겠죠??

 

이해되시나요??

 

귀무가설과 대립가설을 기각시키기 위해서는 T-value와 p-value가 필요합니다

 

보통 손으로 계산을 할 때는 T-value를 이용하는 방법으로 배웠지만

 

저희는 컴퓨터에게 계산을 맡길 거기 때문에 p-value를 통해 비교하겠습니다

 

선형 회귀 분석은 말 그대로 예측하는 기법입니다

 

그렇기 때문에 입력되는 예측인자는 정해져 있어도 구해지는 예측량들의 범위는 굉장히 넓을겁니다

 

가장 적합한 직선을 찾는 과정에서 예측량이 5가 나올수도 있고 10이 나올 수도 있다는 말입니다

 

그러면 저 범위 내에서 우연히 내가 찾고 싶은 값이 나왔을 수도 있겠져?

 

가설이 맞는지 틀린지도 모르는데 찾고 싶은 값이 정말 우연하게 갑지기 튀어 나왔을 수도 있습니다

 

바로 '우연하게 내가 원하는 값이 나왔을 확률'을 p-value라고 합니다

 

그러면 정확하게 내 값이 나왔을 확률이 커져야 모델이 정확한 거고 내 자료에 적합하다는 뜻이니까

 

p-value는 작을수록 좋겠죠??

 

이걸 비교하는 부분도 코드에 포함이 되어 있습니다


 

적합성을 판단하려면 적합성을 나타내는 척도들도 필요하겠죠

 

일반적으로 R^2으로 표현하는 결정계수, MSE와 MSR, F-ratio 이렇게 3가지를 사용합니다

 

오늘 코드에서 나올 내용은 결정계수가 나옵니다

 

결정계수는 모델이 내 자료를 설명하는 비율을 말합니다

 

0 ~ 1의 숫자를 가지기 때문에 1에 가까울 수록 잘 설명하는 모델로 생각할 수 있습니다

 

보통 결정계수는 구하는 방법이 두 가지가 있습니다

 

SST와 SSR의 비율로 구하는 방법과 상관계수를 제곱하는 방법 이렇게 2가지가 있는데 

 

저는 피어슨 상관계수를 제곱하는 방법으로 구했습니다

 

이제 코드 설명으로 가겠습니다


코드)

import numpy as np
from scipy import stats
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt

#Coefficent of Detect
class COD:
    def __init__(self, x, y):
        self.r, self.p_val = stats.pearsonr(x, y)
        self.R = self.r**2

        print('R_squared : {}, p-value : {}'.format(round(self.R, 4), round(self.p_val, 4)))

#5% 유의성 검사
class valence5:
    def __init__(self, x, y):
        self.r10, self.p10_val = stats.pearsonr(x, y)

        if self.p10_val < 0.05:
            print('P-value가 충분히 작기 때문에 선형 회귀 모델이 자료에 적합합니다')
        else:
            print('P-value가 유의 수준 5%보다 크기 때문에 선형 회귀 모델이 자료에 적합하지 않습니다')

#1% 유의성 검사
class valence1:
    def __init__(self, x, y):
        self.r20, self.p20_val = stats.pearsonr(x, y)

        if self.p20_val < 0.01:
            print('P-value가 충분히 작기 때문에 선형 회귀 모델이 자료에 적합합니다')
        else:
            print('P-value가 유의 수준 1%보다 크기 때문에 선형 회귀 모델이 자료에 적합하지 않습니다')

만든 코드는 조금 길지만 수학적 계산이 많아서 코드 자체는 전혀 어렵지 않습니다

 

또 라이브러리를 만든다고 해서 저희가 numpy나 scipy같은 다른 라이브러리들의 기능을 구현하지 않아도 됩니다

 

라이브러리 내에 다른 라이브러리를 또 부를 수 있습니다

 

물론 저렇게 사용하면 대량의 자료를 사용할 때는 속도가 조금 느려질 수도 있지만

 

저희는 아직 그렇게 방대한 양의 자료를 다루지 않기 때문에 넘어가겠습니다

 

하나씩 뜯어서 설명을 가보겠습니다


결정계수)

class COD:
    def __init__(self, x, y):
        self.r, self.p_val = stats.pearsonr(x, y)
        self.R = self.r**2

        print('R_squared : {}, p-value : {}'.format(round(self.R, 4), round(self.p_val, 4)))

이름을 COD라고 지은 이유는 결정계수를 영어로 Coefficient of Determination 라고 하기 때문입니다

 

아래는 정말 간단합니다

 

scipy에 stats 라이브러리에는 stats.pearsonr이라는 피어슨 상관계수를 구하는 모듈이 있습니다

 

정말 친절하게 피어슨 상관 계수와 p-value도 같이 구해줍니다

 

상관 계수와 p-value를 각각 self.r과 self.p_val이라는 변수에 지정합니다

 

앞에 self를 붙여주면 COD class를 호출하지 않는한 저 결정계수를 구하는 코드가 실행되지 않기 때문에

 

같은 이름의 변수를 여러개를 사용할 수 있습니다

 

그리고 self.R이라는 변수에 상관 계수를 제곱해서 구해줍니다

 

실행을 하면 자동으로 결정계수가 나올수 있도록 print 문까지 작성해주었습니다

 

제가 입력해준 자료는 1901년부터 2000년까지의 해양의 온도 아노말리, 즉 편차 자료 입니다

 

Year와 Value 컬럼들을 추출해서 입력을 시켜주면

이렇게 결정계가 구해집니다!!

 

다른 라이브러리들은 결과 값을 변수에 지정하면 출력되지 않게 돼있지만 저는 그런 부분을 추가하지는 않았습니다

 

값이 바로바로 보고 싶었기 때문이죠

 

앞에 기초 설명 부분 때문에 글이 많이 길어져서 p-value로 유의성 검사하는 부분은 다음 포스팅 때 하겠습니다

 

오늘도 긴 글 읽어주셔서 감사합니다!!

728x90