통계

상관계수와 회귀식, 예측값 파이썬으로 구해보기

이석사 중 2022. 12. 21. 16:46
728x90

어제도 제 블로그를 찾아주신 다섯 분 감사드립니다!

 

오늘은 상관계수와 선형회귀 분석, MSE, MSR 부분입니다

 


저번 포스팅에서 유의성 검사까지 마쳤습니다

 

이제 상관계수가 유의한지 않은지를 알 수 있으니 선형 회귀 분석도 해보겠습니다

 

#Correlation 
class correlation:
    def __init__(self, x, y):
        self.p_r, self.pp_val = stats.pearsonr(x, y)
        self.s_r, self.sp_val = stats.spearmanr(x, y)

    def pearson(self):
        print('변수 X,Y에 대한 피어슨 상관계수는 {}입니다'.format(round(self.p_r, 4)))

    def spearman(self):
        print('변수 X,Y에 대한 스피어만 순위 상관 계수는 {}입니다'.format(round(self.s_r, 4)))

#Fitting Model
class formula:
    def __init__(self, x, y):
        self.a = np.array(x)
        self.reg = LinearRegression()
        self.reg.fit(self.a.reshape(-1, 1), y)

        self.a_grad = self.reg.coef_
        self.a_y = self.reg.intercept_

        self.a1_grad = self.a_grad.tolist()

        print('Regression coefficient a : {}, b : {}'.format(round(self.a1_grad[0], 4), round(self.a_y, 4)))

        print('Regression Formula : {} + {}x'.format(round(self.a_y, 4), round(self.a1_grad[0], 4)))

#Predict Predictor
class predict:
    def __init__(self, x, y, x10):
        self.x4 = np.array(x)

        self.model = LinearRegression()
        self.model.fit(self.x4.reshape(-1, 1), y)

        self.pred = np.array(x10)

        self.forecast = self.model.predict(self.pred.reshape(1, -1))

        self.sh = self.forecast.tolist()

        print('{}년의 온도 아노말리 예측값은 {}\u00B0C 입니다'.format(x10, round(self.sh[0], 4)))

#Mean Squares Regression
class msr:
    def __init__(self, x, y):
        self.x1 = np.array(x)
        self.x_me = np.mean(x)

        self.reg1 = LinearRegression()
        self.reg1.fit(self.x1.reshape(-1, 1), y)
        
        self.x1_grad = self.reg1.coef_

        self.x_dev = self.x1 - self.x_me

        self.x_msr = self.x1_grad**2 * np.sum(self.x_dev ** 2)

        self.x_msr1 = self.x_msr.tolist()

        print('MSR(Regression Mean Squares) : {}'.format(round(self.x_msr1[0], 4)))

#Mean Squared Error(MSE)
class mse:
    def __init__(self, x, y):
        self.x2 = np.array(x)
        self.y2 = np.array(y)

        self.reg2 = LinearRegression()
        self.reg2.fit(self.x2.reshape(-1, 1), self.y2)

        self.res = self.y2 - self.reg2.predict(self.x2.reshape(-1, 1))

        self.x2_mse = np.var(self.res)

        print('MSE(Mean Squared Error) : {}'.format(round(self.x2_mse, 4)))

#F - ratio
class Fratio:
    def __init__(self, x, y):
        self.x3 = np.array(x)
        self.y3 = np.array(y)

        self.x3_me = np.mean(x)

        self.reg3 = LinearRegression()
        self.reg3.fit(self.x3.reshape(-1, 1), y)

        self.x3_grad = self.reg3.coef_

        self.x3_dev = self.x3 - self.x3_me

        self.x3_msr = self.x3_grad**2 * np.sum(self.x3_dev ** 2)

        self.res1 = self.y3 - self.reg3.predict(self.x3.reshape(-1, 1))

        self.x3_mse = np.var(self.res1)

        self.F = self.x3_msr/self.x3_mse

        self.F1 = self.F.tolist()
        print('F - ratio : {}'.format(round(self.F1[0], 4)))

굉장히 길지만 하나하나 해보면 어렵지는 않습니다


#Correlation 
class correlation:
    def __init__(self, x, y):
        self.p_r, self.pp_val = stats.pearsonr(x, y)
        self.s_r, self.sp_val = stats.spearmanr(x, y)

    def pearson(self):
        print('변수 X,Y에 대한 피어슨 상관계수는 {}입니다'.format(round(self.p_r, 4)))

    def spearman(self):
        print('변수 X,Y에 대한 스피어만 순위 상관 계수는 {}입니다'.format(round(self.s_r, 4)))

상관 계수 부분은 피어슨 상관계수와 스피어만 상관계수를 구해서 출력만 하는 부분이라

 

따로 설명을 하지 않고도 넘어가도 될 것 같습니다


#Fitting Model
class formula:
    def __init__(self, x, y):
        self.a = np.array(x)
        self.reg = LinearRegression()
        self.reg.fit(self.a.reshape(-1, 1), y)

        self.a_grad = self.reg.coef_
        self.a_y = self.reg.intercept_

        self.a1_grad = self.a_grad.tolist()

        print('Regression coefficient a : {}, b : {}'.format(round(self.a1_grad[0], 4), round(self.a_y, 4)))

        print('Regression Formula : {} + {}x'.format(round(self.a_y, 4), round(self.a1_grad[0], 4)))

다음은 선형회귀 분석입니다

 

model.fit(x, y) 형태로 모델을 학습시킵니다

 

x는 예측인자, y는 예측량으로 x값은 반드시 array 형태로 들어가야 합니다

 

모양도 reshape를 통해서 -1, 1로 바꾼 다음 넣어주어야합니다

 

배열 모양에 -1이 들어가는 건 가변적으로 바꾼다는 뜻으로 자료의 갯수에 맞게 바뀐다는 말입니다

 

내 자료가 40개면 -1, 1로 만들면 (40,1), 20개면 (20,1)로 됩니다

 

그리고 model.coef_, model.intercept_로 기울기와 y절편을 구해주고 y = ax + b 모양으로 출력까지 시켰습니다

 

실행한 모습입니다

 

깔끔하게 나오죠??


#Predict Predictor
class predict:
    def __init__(self, x, y, x10):
        self.x4 = np.array(x)

        self.model = LinearRegression()
        self.model.fit(self.x4.reshape(-1, 1), y)

        self.pred = np.array(x10)

        self.forecast = self.model.predict(self.pred.reshape(1, -1))

        self.sh = self.forecast.tolist()

        print('{}년의 온도 아노말리 예측값은 {}\u00B0C 입니다'.format(x10, round(self.sh[0], 4)))

다음은 예측값을 구하는 부분입니다

 

예측값은 model.predict() 모듈을 사용하면 구해집니다

 

예측인자에 맞게 예측값이 나오기 때문에 array 형태로 출력이 되서 그냥 print문으로 출력하면

 

이상하게 출력이 됩니다

 

깔끔하게 출력하기 위해서 tolist로 리스트 값으로 바꿔주고 print문에 넣어줬습니다

 

제가 사용한 자료는 온도 아노말리 자료이기 때문에 ℃ 형태로 출력시켜줬습니다


MSE와 MSR은 통계적인 설명이 들어가야해서 글이 길어질 것 같아서

 

다음 포스팅에 이어서 쓰도록 하겠습니다!

 

감사합니다

 

 

 

728x90