Study/class note

머신러닝 / 다중 공선성, 상관관계 분석, 단순회귀분석 모델 구현(R, 파이썬)

chanzae 2022. 2. 11. 14:12

의사결정트리의 정확도는 94.4%였는데 랜덤포레스트의 정확도는 100%

 

단순회귀분석 ----> 상관관계 ----> 다중회귀분석

 

ㅇ 다중 공선성(variance inflation factor)

회귀분석에서 사용된 모형의 일부 설명변수(독립변수)가 다른 독립변수와의 상관정도가 높아서 데이터 분석시 부정적인 영향을 미치는 현상을 말함.

 

두 독립변수들끼리 서로에게 영향을 주고 있다면 둘 중 하나의 영향력을 검증할 때 다른 하나의 영향력을 완전히 통제할 수 없게 됨.

 

- 회귀분석의 유형

1. 단순회귀 : 독립변수 1개, 종속변수와의 관계 직선

2. 다중회귀 : 독립변수 n개, 종속변수와의 관계 선형(1차함수)

3. 다항회귀 : 독립변수가 종속변수와의 관계가 1차함수 이상의 관계

4. 곡선회귀 : 독립변수 1개, 종속변수와의 관계 곡선

5. 로지스틱회귀 : 종속변수가 범주형(이진변수)인 경우

6. 비선형회귀 : 회귀식의 모양이 미지의 모수들의 선형관계로 이루어져 있지 않은 모형

 

머신러닝(기계학습)으로 무엇을 하고자 하는가?

> 1. 분류 : knn, naivebayes, decision tree, random forest, 규칙기반 알고리즘(oneR, Riper)

   2. 수치예측 : regression

 

다중회귀분석을 잘못하지 않으려면, 즉 분석을 잘하려면 먼저 선행되어야할게 독립변수간의 상관관계를 확인해봐야함.

 

ex)

단순회귀 : 평수(독립변수), 아파트가격(종속변수)

다중회귀 : 평수, 역과의 거리, 층수(독립변수) --- 아파트 가격(종속변수)

 

위와같이 평수와 역과의 거리는 상관관계가 없음. 평수와 층수와의 관계도 상관관계가 없음. 다중회귀분석시 문제가 되지 않음.

 

문제가 되는 경우는 다음과 같음.

ex) 학업성취도(종속변수) ---- (독립변수) 일평균 공부시간, 일평균 음주량, 혈중 알코올농도

일평균 음주량과 혈중 알코올 농도는 서로 상관관계가 아주 높다

음주가 학업성취도에 미치는 영향을 알아보려고 회귀분석을 하려고 하는데 일평균 음주량과 혈중 알코올 농도는 서로 아주 강한 상관정도를 보이고 있음.

 

이런 경우에 회귀분석을 했을 때 나오는 회귀계수값이 굉장히 불안정한 계수값을 보이게 됨. 학업성취도에 미치는 영향에서 일평균 음주량 뿐만아니라 혈중 알코올 농도도 아주 중요한데 위의 2개를 다 넣고 다중회귀분석을 돌리게 되면 일 평균음주량의 영향력이 크다(기울기가 크다)라고 나오면서 혈중 알코올 농도(기울기)는 상대적으로 작게 나옴.

 

공선성은 두 개의 독립변수들 간의 관계를 의미하는데 예를들어 두 개의 독립변수들 간의 상관계수가 1이면 완전한 공선성을 보인다고 하고, 계수가 0이면 공선성이 없음을 의미함.

다중공선성을 알아보기 위한 가장 간단한 방법은 독립변수들간의 상관관계를 조사하는 것. 독립변수들 간의 상관관계(일반적으로 0.9이상)은 공선성을 판단하는 지표가 된다.

 

현업기준 : 팽창계수(vif)가 보통 10보다 큰 것을 골라내고 엄격하게 하려면 5보다 큰 것을 골라냄. 느슨하게 하려면 15 또는 20으로 주로 골라냄.

(팽창계수 = 공선성계수)

 

# R
# 패키지 설치
install.packages("car")  # 다중공선성 확인을 위한 패키지
install.packages("MASS")  # 실습데이터가 있는 패키지
library(car)
library(MASS)

# 데이터 로드
data("Boston") # 미국의 보스톤 지역의 집값 데이터를 불러옴
Boston
 [01]  CRIM 자치시(town) 별 1인당 범죄율
 [02]  ZN 25,000 평방피트를 초과하는 거주지역의 비율
 [03]  INDUS 비소매상업지역이 점유하고 있는 토지의 비율
 [04]  CHAS 찰스강에 대한 더미변수(강의 경계에 위치한 경우는 1, 아니면 0)
 [05]  NOX 10ppm 당 농축 일산화질소
 [06]  RM 주택 1가구당 평균 방의 개수
 [07]  AGE 1940년 이전에 건축된 소유주택의 비율
 [08]  DIS 5개의 보스턴 직업센터까지의 접근성 지수
 [09]  RAD 방사형 도로까지의 접근성 지수
 [10]  TAX 10,000 달러 당 재산세율
 [11]  PTRATIO 자치시(town)별 학생/교사 비율
 [12]  B 1000(Bk-0.63)^2, 여기서 Bk는 자치시별 흑인의 비율을 말함.
 [13]  LSTAT 모집단의 하위계층의 비율(%)
 [14]  MEDV 본인 소유의 주택가격(중앙값) (단위: $1,000)

> medv가 종속변수

 

# 다중회귀분석 모델
model <- lm(medv~ ., data = Boston)
model

Coefficients:
(Intercept)         crim           zn        indus         chas          nox  
  3.646e+01   -1.080e-01    4.642e-02    2.056e-02    2.687e+00   -1.777e+01  
         rm          age          dis          rad          tax      ptratio  
  3.810e+00    6.922e-04   -1.476e+00    3.060e-01   -1.233e-02   -9.527e-01  
      black        lstat  
  9.312e-03   -5.248e-01

> 다중회귀다보니 각 변수별 기울기가 나옴.

> 우리가 확인해야할 것은 다중공선성을 보이는 것이 있는지 확인하는 것.

vif(model) > 10 #다중공선성을 보이는 변수 확인

   crim      zn   indus    chas     nox      rm     age     dis     rad     tax 
  FALSE   FALSE   FALSE   FALSE   FALSE   FALSE   FALSE   FALSE   FALSE   FALSE 
ptratio   black   lstat 
  FALSE   FALSE   FALSE 

> 전부 false여서 다중공선성을 보이는 컬럼은 없음

집값에 영향을 미치는 독립변수들 중에서 서로 상관관계가 높게 나타나는 독립변수들이 없다는 의미

 

 

ㅇ상관관계 데이터 분석 - p.260

두 변수간의 상관관계는 변수의 관계가 직선에 가깝게 따르는 정도를 나타내는 숫자

상관관계는 -1 ~ +1 사이의 범위에 있음.

(회귀분석은 영국은 생물하자이자 수학자인 프란시스 갈톤이 부모와 자식의 키의 관계를 알아보기 위한 연구에서 처음으로 제안한 것을 수학자 칼 피어슨에 의해 함수관계를 도출하여 수학적 관계를 정립)

두 변수의 공분산을 표준편차의 곱으로 나눈 값으로 상관계수를 구함.

 

회귀분석시 상관관계를 확인!

1. 독립변수와 독립변수들끼리의 상관관계 확인 > 다중공선성 문제가 생길 수 있기 때문

2. 독립변수와 종속변수와의 상관관계 확인 > 독립변수와 종속변수와의 관계를 빠르게 판단할 수 있기 때문

 

ex) 우주 왕복선 챌리저호의 폭파원인을 분석하기 위해서 상관관계분석을 하시오.

     "O형링 파손에 영향을 미치는 독립변수가 무엇인가?"

데이터셋 : challenger.csv

cha <- read.csv("c:\\data\\challenger.csv", header = T)
head(cha)
str(cha)

$ distress_ct : o형링 파손수

$ temperature : 온도
$ field_check_pressure : 압력
$ flight_num : 비행기 번호(비행기 노후화와 연관)

cor(cha)

                             distress_ct   temperature     field_check_pressure   flight_num
distress_ct                1.0000000   -0.51112639         0.28466627          0.1735779
temperature            -0.5111264    1.00000000         0.03981769           0.2307702
field_check_pressure   0.2846663    0.03981769         1.00000000           0.8399324
flight_num               0.1735779     0.23077017         0.83993237           1.0000000

> 피어슨 상관계수가 -0.51이므로 음의 상관관계를 보이고 있음.

온도와 o형링 손상간의 상대적인 강도가 -0.51로 최대값인 -1의 절반정도이기 때문에 적당히 강한 음의 선형관계가 있음을 의미함. 이 값은 오링 데이터를 연구하는 엔지니어에게 저온에서 발사할 경우 문제가 될 수 있다는 명확한 지표가 됨.

 

ex.위의 결과를 R로 시각화 하시오.

install.packages("psych")  # 시각화위한 패키지 설치
library(psych)
pairs.panels(cha, cex=5)

 문제296. 위의 결과를 파이썬으로 시각화하시오.

# python
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
 
cha= pd.read_csv("c:\data\challenger.csv")
sns.heatmap(cha.corr(), annot = True, cmap = 'GnBu', linewidths = 0.2)  
fig = plt.gcf() # fig를 지정하고 나서
fig.set_size_inches(10,8) # 그래프의 사이즈 조절
plt.show()

 

문제297. o형링 파손에 영향을 미치는 요소가 무엇인지 확인하기 위해 다중 회귀분석을 할텐데 회귀분석하기에 앞서 다중 공선성 문제를 보이는 컬럼이 있는지 확인하시오.

#1. 패키지 로드
library(car)

#2. 데이터 로드
cha <- read.csv("c:\\data\\challenger.csv", header = T)

# 다중회귀분석 모델
model <- lm(distress_ct ~ ., data = cha)
model

vif(model) > 10 #다중공선성을 보이는 변수 확인

> Coefficients:
         (Intercept)           temperature  field_check_pressure  flight_num  
            3.527093             -0.051386              0.001757    0.014293  


>         temperature field_check_pressure           flight_num 
               FALSE                FALSE                FALSE 

현업기준으로 봤을 때 다중공선성 문제를 보이는 변수들은 없음.

 

o형링 파손에 가장 큰 영향을 미치는 요소가 온도(temperature)였음. 저온에서 발사할 때 o형링이 더 잘 손상된다라는 상관관계를 확인, 온도 독립변수 하나만 가지고 단순회귀 분석을 해보겠음.

 

 

ㅇ o형링 파손수를 종속변수로 두고 온도를 독립변수로 설정하여 단순회귀 분석하기

54 단순회귀분석 모델을 R 로 구현

#1. 데이터로드

#2. 산포도 그래프 시각화
#3. 단순회귀 분석
#4. 단순회귀분석 결과 확인

#5. 회귀직선 시각화

#1. 데이터로드
cha <- read.csv("c:\\data\\challenger.csv", header = T)

#2. 산포도 그래프 시각화
attach(cha)
plot(distress_ct ~ temperature, pch = 21, col = 'lightsteelblue', bg = 'lightsteelblue', cex = 2)

#3. 단순회귀 분석
model <- lm(distress_ct ~ temperature, data = cha)
model

 

#4. 단순회귀분석 결과 확인

Coefficients:
(Intercept)  temperature  
    3.69841     -0.04754 

> 단순회귀식을 써보자면 y =  -0.04754 * x + 3.69841   (y : o형링 파손수, x : 온도)

화씨 31도에서 o형링 파손수 2.21개, 화씨 60도에서 o형링 파손수 0.82개, 화씨 70도에서 o형링 파손수 0.34개

=> 화씨 30도에서 발사하는게 화씨 60도에서 발사하는 것보다 3배 더 위험하고 화씨 70도에서 발사하는 것보다 거의 7~8배 위험하다.

 

#5. 회귀직선 시각화

abline(model, col = 'blue')

55 단순회귀 분석 모델을 파이썬으로 구현

#1. 데이터 로드

#2. 종속변수와 독립변수 지정

#3. 모델 생성

#4. 모델 훈련

#5. 기울기와 절편 구하기

#6. 시각화

#1. 데이터 로드
import pandas as pd

cha = pd.read_csv("c:\\data\\challenger.csv")
cha.head()

#2. 종속변수와 독립변수 지정
x = cha[['temperature']]  #독립변수
y = cha[['distress_ct']]  #종속변수

#3. 모델 생성
from sklearn.linear_model import LinearRegression

model = LinearRegression()

#4. 모델 훈련
model.fit(x,y)

#5. 기울기와 절편 구하기
print('기울기 : %f'%model.coef_)
print('절편 : %f'%model.intercept_)

#6. 시각화
import seaborn as sns

sns.regplot(x,y)

문제298. 화씨 62도에서는 o형링이 몇개나 파손되는지 예측하시오.

# 예측
model.predict([[62]])   # [[0.75095238]]

 

문제299. (점심시간 문제) 광고비가 매출에 미치는 영향에 대한 단순회귀분석을 하는데 광고비(cost)와 매출(input)에 대한 단순회귀모델을 파이썬으로 만들고 광고비를 260,000,000만원이 들었을 때 예상되는 매출액이 얼마인지 출력하시오.

( cf. cost 26이  260,000,000만원. 독립변수, 종속변수 둘 다 단위가 천만원 단위 )

#1. 데이터 로드
import pandas as pd

hg = pd.read_csv("c:\\data\\simple_hg.csv")
hg.head()

#2. 종속변수와 독립변수 지정
x = hg[['cost']]
y = hg[['input']]

#3. 모델 생성
from sklearn.linear_model import LinearRegression

model = LinearRegression()

#4. 모델 훈련
model.fit(x,y)

#5. 기울기와 절편 구하기
print('기울기 : %f'%model.coef_)
print('절편 : %f'%model.intercept_)

# 예측
predict = model.predict([[26]])   # [[0.75095238]]
print('\n독립변수(cost)가 26일 때 예측값 : %f'%predict)

#6. 시각화
import seaborn as sns
import matplotlib.pyplot as plt

sns.set_style('whitegrid')
sns.regplot(x,y,scatter_kws = {'color' : 'blue'},line_kws = {'color': 'pink','alpha':0.3})

plt.show()

+) sns.replot 참고 사이트 : https://medium.com/@kathy.lu.rentals/visualizing-with-seaborn-regplot-2235ccbaedd4

 

 

ㅇ위의 단순회귀모델 성능을 확인하는 방법

#1. 독립변수(광고비) 전체를 모델에 넣어서 예측값을 출력
y_hat = model.predict(x)

#2. 실제값과 예측값이 얼마나 일치하는지 시각화
import matplotlib.pyplot as plt
import seaborn as sns

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

ax1 = sns.distplot(y, hist = False, label = 'y', color = 'salmon')  # 실제값
ax2 = sns.distplot(y_hat, hist = False, label = 'y_hat', ax = ax1, color = 'steelblue')  #예측값

plt.show()
plt.close()

#3. 결정계수값을 확인(회귀모델의 데이터에 대한 설명력)
r_square = model.score(x,y)
r_square  #0.7884035286357817

r_square값 = 0.7884035286357817

> 0~1 사이의 값으로 출력되는데 1에 가까울수록 설명력이 높은 모델임.

 

 

문제300.  키를 독립변수로 두고 체중을 종속변수로 두고서 단순 회귀 모델을 만들고 이 회귀 모형의 결정계수를 출력하시오.(실제값과 예측값과의 일치를 시각화 하세요)

#1. 데이터 로드
df_dict = {'weight' : [72, 72, 70, 43, 48, 54, 51, 52, 73, 45, 60, 62, 64, 47, 51, 74, 88,64, 56, 56  ],
          'tall' : [ 176, 172, 182, 160, 163, 165, 168, 163, 182, 148, 170, 166, 172, 169, 163, 170, 182, 174, 164, 160 ]  }

df =  pd.DataFrame(df_dict)

#2. 독립변수, 종속변수 설정
x = df[['tall']]
y = df[['weight']]

#3. 모델 생성
from sklearn.linear_model import LinearRegression

model = LinearRegression()

#4. 모델 훈련
model.fit(x,y)

#5. 기울기와 절편 구하기
W = model.coef_
b = model.intercept_

#6. 시각화
import seaborn as sns
import matplotlib.pyplot as plt

sns.set_style('whitegrid')
sns.regplot(x,y,scatter_kws = {'color' : 'blue'},line_kws = {'color': 'pink','alpha':0.7})

plt.title('y = %f*x + %f'%(W,b), size = 15)
plt.show()

#7. 예측값
y_hat = model.predict(x)

#8. 실제값, 예측값 일치 시각화
import matplotlib.pyplot as plt
import seaborn as sns

plt.rc('font',family = 'Malgun Gothic')  # 한글 안깨지게 하는 코드
plt.figure(figsize = (10,5))

ax1 = sns.distplot(y, hist = False, label = 'y', color = 'salmon')  # 실제값
ax2 = sns.distplot(y_hat, hist = False, label = 'y_hat', ax = ax1, color = 'steelblue')  #예측값

plt.legend(fontsize = 12, labels = ['실제값','예측값'])

plt.show()
plt.close()

#9. 결정계수값을 확인(회귀모델의 데이터에 대한 설명력)
r_square = model.score(x,y)
r_square  #0.6615877402621954

 

반응형