빅데이터, 데이터분석

파이썬으로 빅데이터 다중선형회귀분석 구현하기

톰이야요 2023. 5. 22. 08:00

수집가능한 데이터(독립변수)를 최대한 모으고 모아서, 알고있는 결과데이터(종속변수)와의 인과관계를 찾고자 파이썬으로 다중선형회귀분석 프로그램을 만들어 보았습니다.

 

2023.05.20 - [빅데이터, 데이터분석] - 빅데이터 회귀분석의 기본이론

 

빅데이터 회귀분석의 기본이론

빅데이터 분석 프로젝트를 하게 되었습니다. 프로젝트라고 하니 뭔가 거창한 느낌이긴 한데, 혼자서 1년간 공부하고 실제 결과물까지 만들어 본 값진 경험이라 할까나요? ㅎㅎ 컴퓨터 프로그래

rookiego90.tistory.com

 

 

 

파이썬에는 회귀분석 라이브러리가 기본으로 제공되며, 데이터를 읽고 쓰기 편한 라이브러리가 다양하게 있습니다. 그래서 파이썬을 많이 쓰나봅니다. 처음에는 주어진 데이터셋에서 회귀분석을 해보았습니다. 이렇게 해보면 1회만 회귀분석을 하고 결과가 출력이 됩니다. 최적의 회귀방정식을 선택하기 위해서 전진선택법, 후진제거법 등의 단계적 선택방법이 있으나, 가장 좋은 방법은 모든 경우를 다 만들어보고 비교하는게 제일 정확할 것 같았습니다. 모든 경우의 수를 만들기 위해 조합을 이용하였고, 분석결과를 엑셀로 저장하여 확인을 용이하도록 했습니다. 16개 이상의 변수로 만들어지는 조합은 10만개가 넘어가기 때문에 그 이상은 분석시간이 하루가 넘어가니 사람의 개입이 일부 필요합니다.

 

아래에는 공부하면서 단계별로 구현한 소스코드이니 참고하세요.

 

 


 

 

 

파이썬 다중선형회귀분석

 

 

아래는 csv파일에 정리된 데이터를 선형회귀분석하는 파이썬 코드입니다.

csv파일에는 종속변수('계')과 원인일 될 수 있는 독립변수들로 구성이 되어 있습니다.

sklearn.lenear_model 라이브러리를 이용해 회귀분석을 수행하며, 훈련데이터와 결과를 바탕으로 평가하는 평가데이터의 양을 구분하여 처리하는 방식입니다.

 

#파일열기
import csv
import numpy as np
import pandas as pd

df = pd.read_csv('data.csv', encoding='utf-8', index_col=0)

#선형회귀분석
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score

#원본 데이터프레임 df
ch_df = df.copy()

#X,Y 분할
X = re_df.drop(['계'], axis=1, inplace=False)
Y = df['계']

#훈련데이터와 평가데이터 분할
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.1, random_state=156)

#선형회귀분석(모델생성)
lr = LinearRegression()

#선형회귀분석(모델훈련)
lr.fit(X_train, Y_train)

#선형회귀분석(예측수행)
Y_predict = lr.predict(X_test)

#결과출력
mse = mean_squared_error(Y_test, Y_predict)
rmse = np.sqrt(mse)
print('결정계수: {0:.3f}'.format(r2_score(Y_test, Y_predict)). end=',')
print('Y절편: ', lr.intercept_, end=',')
print('회귀계수: ', np.round(lr.coef_, 1))

 

 


 

 

파이썬 다중선형회귀분석 - 조합을 활용한 모든 경우의 수 회귀분석

sklearn.linear_model

 

 

 

아래는 주어진 독립변수들로부터 가장 적합한 모형을 찾기 위해, 독립변수로 만들 수 있는 모든 경우의 수에 대한 회귀분석을 실행하는 코드입니다. 조합을 이용하여 독립변수 리스트를 매번 재구성하여, 결과를 출력하는 방식입니다.

 

 

#파일열기
import csv
import numpy as np
import pandas as pd

df = pd.read_csv('data.csv', encoding='utf-8', index_col=0)

#조합 - 경우의 수 순회
import itertools

#선형회귀분석
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score

#원본 데이터프레임 df
ch_df = df.copy()

#모든 경우의 수 체크

#Y절편을 제외한 컬럼리스트를 pool에 등록
pool = ch_df.drop(['계'], axis=1, inplace=False)
print('변수의 갯수: ', len(pool.columns))

for i in range(1, len(pool.columns)+1) :
   relist = list(itertools.combinations(pool, i))
   for val in re_list :
      re_df = ch_df.copy()
      for each_val in val :
         re_df.drop([each_val], axis=1, inplace=True)

      #X,Y 분할
      X = re_df.drop(['계'], axis=1, inplace=False)
      Y = df['계']

      #훈련데이터와 평가데이터 분할
      X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.1, random_state=156)

      #선형회귀분석(모델생성)
      lr = LinearRegression()

      #선형회귀분석(모델훈련)
      lr.fit(X_train, Y_train)

      #선형회귀분석(예측수행)
      Y_predict = lr.predict(X_test)

      #결과출력
      mse = mean_squared_error(Y_test, Y_predict)
      rmse = np.sqrt(mse)
      print('결정계수: {0:.3f}'.format(r2_score(Y_test, Y_predict)). end=',')
      print('Y절편: ', lr.intercept_, end=',')
      print('회귀계수: ', np.round(lr.coef_, 1))

 

 


 

파이썬 다중선형회귀분석 - 조합을 활용한 모든 경우의 수 회귀분석, 결과파일 저장

statsmodels

 

 

조합을 이용해 모든 경우의 수 회귀분석을 할 때 결과정리를 용이하도록 하기 위해 다른 라이브러리로 개발해 보았습니다. 독립변수들로 조합할 수 있는 모든 그룹을 회귀분석하고 그 결과를 엑셀에 저장하도록 하였습니다. 엑셀에는 독립변수의 종류, 결정계수, 조정된 결정계수, 계수, t값, p값 등을 모두 기록하여 결과를 정렬하거나 확인하기가 좋습니다.

 

 

#파일열기
import csv
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

#조합 - 경우의 수 순회
import itertools

#선형회귀분석
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
#statsmodels 회귀분석
import statsmodels.api as sm

#정의
str_result = '식수' #Y절편(종속변수)의 컬럼명을 설정
max_r2 = -999.999 #가장 높은 절편을 구하기 위한 비교변수
print_no = 100 #회귀분석 n회마다 진행율을 표시

nCases = 0 #회귀분석을 수행할 모든 경우의 수 횟수
nCaseCount = 0 #회귀분석을 수행하는 n번째 수
nCount = 0 #횟수계산을 위한 임시변수 (10번째마다 초기화)

#결과파일의 포멧 정의
data_init = [['설명', '회귀식의설명력', '상관계수를 적용한 조정된 결정계수', 'F통계량', 'F통계량에 해당하는 p-value', '절편 및 계수', 't', 'p']]
out_df = pd.DataFrame(data_init)
out_df.columns = ['구분', '결정계수', '조정된결정계수', 'f값', 'p값', '변수_계수', '변수_t값', '변수_p값']

#파일 불러오기
df = pd.read_csv('data.csv', encoding='utf-8', index_col=0)

#Y절편을 제외한 컬럼리스트를 pool에 등록
pool = df.drop([str_result], axis=1, inplace=False)
print('변수:', len(pool.columns), ' 개')

#모든 케이스 수량표시
for i range(1,len(pool.columns)) :
   nCases += len(list(itertools.combinations(pool,i)))
print('회귀분석 수행 횟수 : ', nCases)

#변수로 나올 수 있는 각각 조합을 회귀분석 수행
for i in range(1, len(pool.columns)) :
   #변수에 대한 조합을 리스트로 생성 (i개로 구성된 조합)
   re_list = list(itertools.combinations(pool, i))

   #만들어진 조합을 컬럼에서 빼고, 회귀분석 수행
   for val in re_list :
      #수정, 삭제할 수 있는 데이터프레임을 복사(re_df)
      re_df = df.copy()

      #수정데이터프레임에서 조합리스트의 변수를 삭제
      for each_val in val :
         re_df.drop([each_val], axis=1, inplace=True)

      #X,Y 분할
      X = re_df.drop([str_result], axis=1, inplace=False)
      Y = pd.DataFrame(df, columns=[str_result])
      final_df = pd.concat([X,Y], axis=1)

      #회귀분석(statmodels)
      model = sm.OLS.from_formula(str_result + "~" + "+".join(X.columns), data=final_df)
      result = model.fit()

      #결과
      r2 = result.rsquared #결정계수
      r2_adj = result.rsquared_adj #조정된 결정계수
      fvalue = result.fvalue
      f_pvalue = result.pvalue

      #변수별 결과
      str_params = result.params
      str_tvalue = result.tvalue
      str_pvalue = result.pvalues

      if r2 > max_r2 :
         max_r2 = r2
         max_result = result

      #데이터프레임에 결과치 저장
      new_data = {'구분': ','.join(X.columns.tolist()), '결정계수': r2, '조정된결정계수': r2_adj, 'f값': fvalue, 'p값': f_pvalue, '변수_계수':str_params, '변수_t값': str_tvalue, '변수_p값': str_pvalue}
      out_df = outdf.append(new_data, ignore_index = True)

      #진행현황 표시
      print('.', end='')
      nProgressPercent = nCaseCount/nCases*100
      if (nCount == print_no) :
         nCount = 0
         print(np.round(nProgressPercent, 1), '%')
      nCaseCount += 1
      nCount += 1
print('\n')

#가장 높은 결정꼐수를 가진 모델 결과 출력
Print(max_result.summary())

#파일로 결과 저장
out_df.to_excel('result.xlsx')

 

 

 

파이썬 프로그래밍은 처음해보기 때문에 잘못된 사용 또는 비효율적인 코드가 있을 수 있습니다. 그리고 프로그램한 소스를 복사한것이 아닌 코드를 보고 타이핑 한 것이라 오류가 있을 수도 있습니다. 그건 찾아서 고치면 되겠죠? ^^

 

활용도 하시고, 참고하셔서 좋은 결과물 만드시기 바랍니다.