-
회귀 분석
단순 선형 회귀모델(Simple linear regression)
키가 큰 아이를 낳기 위해서는 키 큰 배우자와 결혼?
-
연구자 : 칼톤(Galton) => 피어슨(Pearson)
-
진화론 반박을 위해 연구
-
가설 : 진화론에 따르면 키가 큰 아버지의 자직은 점점 커지고 키가 작은 아버지의 자식은 점점 작아 진다
-
피어슨 공식 : Y = 83.73 + 0.516 X , X는 아버지의 키
-
키가 큰 아버지의 자식은 아버지보다 작고 전체 평균보다는 크다
-
키가 작은 아버지의 자식은 아버지보다 크고 전체 평균보다는 작다
-
자식의 키는 아버지 키에 영향을 받는다 하더라도 결국 평균으로 돌아가려는 현상
-
아버지의 키와 아들의 키가 서로 연관성이 있다는 사실
회귀분석
-
상관계수는 관계의 긴밀함을 수치적으로 계산
-
회귀분석은 한 변수의 변화에 따른 다른 변수의 값을 파악 할 수 있게 함
회귀 모델 만들기
month_incom <- c(100, 200, 300, 400) month_out <- c(50, 100, 150, 200) df <- data.frame(month_incom, month_out)
df
month_incom month_out <dbl> <dbl> 100 50 200 100 300 150 400 200 회귀모델 => 수학식 : y = 0.5 x
-
x축 : 독립변수
-
y축 : 종속변수
-
독립변수가 종속변수에 어떤 영향을 미치는 가 알아보는 식
-
정확한 함수식이 아닌 모든 데이터를 가장 만족시킬만한 최선의 함수식을 만들어야 함
-
수학의 함수로 표현 할 수 없는 그래프는 회귀모델이 될 수 없음
-
공평하게 대부분의 점과 선이 최대한 떨어지지 않도록 선을 만들어야 함
회귀모델 - 이론
-
어떤 자료에 대해 그 값에 영향을 주는 조건을 고려하여 구한 평균
y=h(x1,x2,x3,...,xk;β1,β2,β3,...,βk)+ϵ
h()
-
조건에 따른 평균을 구하는 함수 => 회귀 모델
-
어떤 조건 (x1,x2,x3,...,xk) 이 주어지면 각 조건의 영향력 (β1,β2,β3,...,βk) 을 고려하여 해당 조건 평균값 계산
오차항 ϵ
-
측정상의 오차
-
모든 정보를 파악할 수 없는 점
-
다양한 현실적인 한계로 인해 발생하는 불확실성
-
일종의 ‘잡음(noise)’
-
이론적으로 보면 평균이 0이고 분산이 일정한 정규 분포를 띄는 성질
회귀 분석이란?
-
h() 함수가 무엇인지를 찾는 과정을 의미
-
그럼 우리가 추정한 회귀 모델이 정말 h() 라는 걸 어떻게 확신할 수 있을까?
-
정확히 맞다는 것을 알 방법은 없음
어느 정도는 확신할 수 있는 방법 => 모델검정
-
우리가 만든 회귀 모델의 예측치와 실측치 사이의 차이인 ‘잔차(residual)’가 정말 우리가 가정한 오차항(e) 의 조건을 충족하는지 확인하는 것
underfitting
-
추정을 잘못하면 몇몇 중요한 조건들을 반영하지 못해 h()의 일부분만 회귀 모델로 만들어 진것
overfitting
-
실제 종속변수에 영향을 주는 조건이 아닌 단순한 ‘잡음’을 평균에 영향을 주는 조건으로 착각하고 모델에 반영
https://brunch.co.kr/@gimmesilver/38
선형성 vs. 비선형성
https://brunch.co.kr/@gimmesilver/18
y = a + bx
-
모집단 : Y=β0+β1x
-
표본 : y^=b0+b1x
R 사용 - lm()
# lm(data, 종속변수~독립변수) 회귀식 작성 # month_out = 0.5 * month_incom lm(data = df, month_out~month_incom)
Call: lm(formula = month_out ~ month_incom, data = df) Coefficients: (Intercept) month_incom 0.0 0.5
최소제곱법 => 회귀 모델식 구하는 방법
-
표준편차 : 평균으로 부터 떨어진 거리
-
잔차: 회귀모델로부터 데이터가 떨어진 값
-
회귀모델은 데이터가 평균으로 회귀한다는 의미
R에서 회귀모델 구하기 - lm()
# 데이터로드 df <- data.frame(Work_hour=c(1:7), Total_pay=seq(10000,70000, by = 10000)) df
Work_hour Total_pay <int> <dbl> 1 10000 2 20000 3 30000 4 40000 5 50000 6 60000 7 70000 plot(data = df, df$Total_pay ~ df$Work_hour, pch = 20, col = 'red') grid()
# 절편 b0과 기울기 b1구하기 - lm(종속변수~독립변수) LR <- lm(data = df, df$Total_pay ~ df$Work_hour) LR
Call: lm(formula = df$Total_pay ~ df$Work_hour, data = df) Coefficients: (Intercept) df$Work_hour -3.545e-12 1.000e+04
# 회귀선 추가 plot(data = df, df$Total_pay ~ df$Work_hour, pch = 20, col = 'red') grid() abline(LR, col='blue', lwd=2) # lwd : line width
안타와 홈런 변수를 활용한 회귀분석
-
data : 한국KBO 홈페이지 (http://www.koreabaseball.com)
# 데이터 로드 df <- read.csv('r-ggagi-data/example_kbo2015.csv')
str(df)
'data.frame': 10 obs. of 26 variables: $ ranking: int 1 2 3 4 5 6 7 8 9 10 $ team : chr "삼성" "넥센" "두산" "NC" ... $ AVG : num 0.3 0.3 0.291 0.288 0.277 0.276 0.27 0.27 0.259 0.256 $ G : int 102 102 99 101 104 99 102 102 103 100 $ PA : int 4091 4151 3950 3994 4082 3888 4037 3988 3984 3835 $ AB : int 3553 3620 3410 3485 3557 3373 3404 3498 3491 3362 $ R : int 634 658 570 591 545 476 504 466 458 469 $ H : int 1066 1085 991 1002 985 931 919 944 905 861 $ X2B : int 188 227 176 205 176 146 162 161 171 161 $ X3B : int 19 12 16 20 14 9 13 13 16 14 $ HR : int 127 155 98 110 130 92 82 87 83 95 $ TB : int 1673 1801 1493 1577 1579 1371 1353 1392 1357 1335 $ RBI : int 606 622 541 557 515 451 467 443 423 440 $ SAC : int 49 40 51 47 50 75 114 62 60 54 $ SF : int 44 37 45 36 23 17 27 26 29 23 $ BB : int 398 393 378 351 395 360 406 355 347 327 $ IBB : int 15 13 17 17 16 12 23 13 17 11 $ HBP : int 47 61 66 74 57 63 86 47 57 69 $ SO : int 650 815 544 717 866 720 780 799 803 778 $ GDP : int 78 79 95 65 105 73 78 75 68 68 $ SLG : num 0.471 0.498 0.438 0.453 0.444 0.406 0.397 0.398 0.389 0.397 $ OBP : num 0.374 0.374 0.368 0.362 0.356 0.355 0.36 0.343 0.334 0.332 $ OPS : num 0.845 0.872 0.806 0.815 0.8 0.761 0.757 0.741 0.723 0.729 $ MH : int 101 100 98 101 104 99 102 101 103 100 $ RISP : num 0.3 0.294 0.284 0.296 0.272 0.277 0.264 0.259 0.238 0.26 $ PH.BA : num 0.216 0.268 0.262 0.274 0.19 0.236 0.196 0.243 0.231 0.214
# 안타와 홈런의 상관관계 알아보기 # 안타 : H, 홈런 : HR df$H df$HR
- 1066
- 1085
- 991
- 1002
- 985
- 931
- 919
- 944
- 905
- 861
- 127
- 155
- 98
- 110
- 130
- 92
- 82
- 87
- 83
- 95
# 상관계수 -1 ~ 1 cor(df$H, df$HR)
0.838411602309812
# 산점도 plot(HR~H, data = df, pch = 20, col = 'grey', cex = 1.5) # cex 점크기
# 회귀모델 구하고 그리기 - 0.2871 안타 10번에 홈런 2.8번 LM <- lm(HR~H, data = df) LM
Call: lm(formula = HR ~ H, data = df) Coefficients: (Intercept) H -172.3105 0.2871
plot(HR~H, data = df, pch=20, col='grey', cex=1.5) grid() abline(LM, lwd=2, col='red')
mtcart 데이터셋으로 회귀분석하기
-
R 내장 dataset
# 데이터 로드 str(mtcars)
'data.frame': 32 obs. of 11 variables: $ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ... $ cyl : num 6 6 4 6 8 6 8 4 4 6 ... $ disp: num 160 160 108 258 360 ... $ hp : num 110 110 93 110 175 105 245 62 95 123 ... $ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ... $ wt : num 2.62 2.88 2.32 3.21 3.44 ... $ qsec: num 16.5 17 18.6 19.4 17 ... $ vs : num 0 0 1 1 0 1 0 1 1 1 ... $ am : num 1 1 1 0 0 0 0 0 0 0 ... $ gear: num 4 4 4 3 3 3 3 4 4 4 ... $ carb: num 4 4 1 1 2 1 4 2 2 4 ...
# 상관계수 -1 ~ 1 cor(mtcars$hp, mtcars$mpg)
-0.776168371826586
# 시각화 plot(mpg~hp, data = mtcars) # 회귀모델 구하기 Lm <- lm(mpg~hp, data = mtcars) abline(Lm, col='red')
# 회귀 계수 - 1hp(마력) 증가시 mpg(연비)는 -0.06823 만큼 떨어짐 Lm
Call: lm(formula = mpg ~ hp, data = mtcars) Coefficients: (Intercept) hp 30.09886 -0.06823
회귀모델과 인과관계
-
상관관계와 회귀모델은 직선관계이지 인과관계가 아님
-
스마트폰 보급율과 집값 상승은 상관관계가 거의 1 => 허위상관계수
-
인과관계를 밝히는 과정중에 회귀분석이 있는 것임
-
최소한의 방법으로 상관관계와 회귀분석이 있는 것임
-
도구에 기대하기보다 도구를 다스릴 때 올바르게 사물과 사실을 볼수 있음
선형회귀 모델 검증하기
-
b0, b1 회귀계수를 검증 하는 것, 특히 b1을 검증(x앞의 값)
결정계수 R2
-
R2=1 이면 모든 값은 회귀모델 위에 있음
-
작아질 수록 회귀모델에서 멀어짐
-
R2 클수록 모집단의 데이터에 적합했다고 함
-
Pearson 상관계수의 제곱 값
-
y 평균에서 회귀모델이 떨어져 있는 비율
-
다중선형회귀분석과 같이 회귀계수가 커지면 커짐 => 수정된 결정계수
SSR / SST 값
# R에서 결정계수 보기 # 결정계수 Multiple R-squared : 0.6024 # 수정된 결정계수 Adjusted R-squared : 0.5892 Lm <- lm(mpg~hp, data = mtcars) options(scipen=999) # scintific notation 나오지 않도록 summary(Lm)
Call: lm(formula = mpg ~ hp, data = mtcars) Residuals: Min 1Q Median 3Q Max -5.7121 -2.1122 -0.8854 1.5819 8.2360 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 30.09886 1.63392 18.421 < 0.0000000000000002 *** hp -0.06823 0.01012 -6.742 0.000000179 *** --- Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 Residual standard error: 3.863 on 30 degrees of freedom Multiple R-squared: 0.6024, Adjusted R-squared: 0.5892 F-statistic: 45.46 on 1 and 30 DF, p-value: 0.0000001788
선형 모델 가설검증
-
회귀모델 위에 없는 점은 오차
-
오차가 신뢰구간 안에 있는 지 검증 하는 것
F 통계량 - p-value: 0.0000001788
-
Y=β0+β1x 에서 β1 이 0일 확률
-
β0 만 남아서 상수, 회귀모델 적용 의미 없음
-
F 통계량이 0.05보다 낮으면 0일 가능성의 거의 없다고 판단
β1 의 신뢰구간 구하기
confint(Lm) # -0.06823 신뢰구간 안에 들어있음
2.5 % 97.5 % (Intercept) 26.76194879 33.4357723 hp -0.08889465 -0.0475619
잔차(Residuals) 관련된 그래프를 그려 '회귀적합성' 검증하기
-
잔차 = 실제값 - 추정된값
-
잔차가 0 이면 회귀 접합성 타당
-
좋은 모델은 잔차의 합이 0에 가까워지고 잔차가 정규분포에 따를 때
-
잔차 그래프에서 y축에 잔차를 그리고 0을 기준으로 고루 퍼저있어야 좋음
잔차 그래프그리기
-
plot() 에 lm() 객체 넣기
-
Residual vs Fitted => 0주위 골고루 퍼짐 확인
-
Normal Q-Q plot => 데이터가 정규성 만족 확인, 선위에 있는 지 확인
-
Scale-Location => 표준화된 잔차제곱의 근 표시 그래프, 골고루 퍼짐 확인
-
Leverage => 이상값이 있으면 등고선 안에 그려짐 Cook's distance 1넘으면 이상값, 회귀모델에 좋지 않은 점
# 2 x 2 그래프 그리기 par(mfrow = c(2,2)) plot(Lm)
R 에서 잔차 그려 검증하기
# 데이터 로드 df <- read.csv('r-ggagi-data/example_residuals_checking.csv')
head(df, 3)
y1 x1 y2 x2 <dbl> <dbl> <dbl> <dbl> 1 6.44 0.5 9.88 1.7 2 10.19 2.5 5.10 0.8 3 5.03 0.6 7.95 1.3 # x1, y1 관계 분석 Lm.res1 <- lm(y1~x1, data = df) Lm.res1
Call: lm(formula = y1 ~ x1, data = df) Coefficients: (Intercept) x1 1.155 4.971
# x2, y2 관계 분석 Lm.res2 <- lm(y2~x2, data = df) Lm.res2
Call: lm(formula = y2 ~ x2, data = df) Coefficients: (Intercept) x2 1.155 4.971
# 두 그래프 그리기 plot(y1~x1, df, pch=20, cex = 1.5, ylim = c(0, 30), main = 'Data1') plot(y2~x2, df, pch=20, cex = 1.5, ylim = c(0, 30), main = 'Data2')
# 회귀모델 그리기 y1,x1 plot(y1~x1, df, pch = 20, cex=1.5, ylim = c(0,30), main = 'Data1') abline(Lm.res1, col='blue', lwd=2) plot(y2~x2, df, pch = 20, cex=1.5, ylim = c(0,30), main = 'Data2') abline(Lm.res1, col='blue', lwd=2)
# 결정계수와 F통계량 확인 options(scipen = 999) summary(Lm.res1) # Multiple R-squared: 0.9201, p-value: < 0.00000000000000022 => 정상범위
Call: lm(formula = y1 ~ x1, data = df) Residuals: Min 1Q Median 3Q Max -3.8603 -1.5588 -0.4486 1.1981 5.7548 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 1.1552 0.6071 1.903 0.063 . x1 4.9712 0.2093 23.756 <0.0000000000000002 *** --- Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 Residual standard error: 2.2 on 49 degrees of freedom Multiple R-squared: 0.9201, Adjusted R-squared: 0.9185 F-statistic: 564.3 on 1 and 49 DF, p-value: < 0.00000000000000022
summary(Lm.res2) # Multiple R-squared: 0.9802, p-value: < 0.00000000000000022 => 정상범위
Call: lm(formula = y2 ~ x2, data = df) Residuals: Min 1Q Median 3Q Max -2.43449 -0.72323 -0.03214 0.59951 2.54498 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 1.1552 0.2925 3.95 0.00025 *** x2 4.9712 0.1008 49.31 < 0.0000000000000002 *** --- Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 Residual standard error: 1.06 on 49 degrees of freedom Multiple R-squared: 0.9802, Adjusted R-squared: 0.9798 F-statistic: 2431 on 1 and 49 DF, p-value: < 0.00000000000000022
# 잔차 관련 그래프로 확인 # Residuals vs Fittes 그래프 1번 퍼지지 않고 U자로 모여 있음 # Q-Q 선을 따르지 않는 데이터가 많음 par(mfrow = c(2,2)) plot(Lm.res1)
par(mfrow = c(2,2)) plot(Lm.res2)
적합한 회귀모델을 검증하는 것은 다양한 측면에서 살펴봐야 함
키와 몸무게 회귀모델 구하기
# 데이터 로드 df <- read.csv('r-ggagi-data/example_studentlist.csv')
# 회귀모델 구하기 Lm <- lm(df$height~df$weight, data = df)
# 시각화 plot(df$height~df$weight, data = df) abline(Lm, col='red')
# 회귀모델 적합성 검토 summary(Lm)
Call: lm(formula = df$height ~ df$weight, data = df) Residuals: Min 1Q Median 3Q Max -7.900 -4.856 -1.335 3.612 9.569 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 143.1724 7.9440 18.023 0.0000000000142 *** df$weight 0.4399 0.1278 3.441 0.00364 ** --- Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 Residual standard error: 6.061 on 15 degrees of freedom Multiple R-squared: 0.4411, Adjusted R-squared: 0.4039 F-statistic: 11.84 on 1 and 15 DF, p-value: 0.003639
결정계수 Multiple R-squared: 0.4411 낮음(부적합)
p-value: 0.003639 < 0.05 적합
# 잔차(Residuals) 그래프 확인 par(mfrow = c(2,2)) plot(Lm)
Q-Q 그래프 선위에 데이터가 있지 않음
Residuals vs Fitted 와 Scale-Location도 균일 하지 않음
결론 : 회귀모델로 분석은 유보
이유 : 관측치(Observation) 가 너무 적음(최소 30개 이상이어야 함)
2015 KBO 야구 데이터 분석하기
타율에 영향을 미치는 변수 분석
# 모든 선수의 성적 데이터 로드 df <- read.csv('r-ggagi-data/example_kbo2015_player.csv')
str(df)
'data.frame': 337 obs. of 26 variables: $ 순위 : int 1 2 3 4 5 6 7 8 9 10 ... $ 선수명: chr "유한준" "박병호" "홍성갑" "고종욱" ... $ 팀명 : chr "넥센" "넥센" "넥센" "넥센" ... $ AVG : chr "0.364" "0.349" "0.333" "0.324" ... $ G : int 101 106 7 85 44 96 68 99 79 103 ... $ PA : int 436 476 10 328 26 405 253 389 339 436 ... $ AB : int 376 410 9 299 22 370 219 333 295 383 ... $ R : int 82 100 0 59 17 53 40 52 62 68 ... $ H : int 137 143 3 97 7 117 68 100 87 110 ... $ X2B : int 35 29 0 22 2 21 10 22 21 28 ... $ X3B : int 1 1 0 3 0 0 0 1 1 4 ... $ HR : int 19 42 0 8 0 14 8 13 17 14 ... $ TB : int 231 300 3 149 9 180 102 163 161 188 ... $ RBI : int 84 111 2 40 3 65 21 67 53 57 ... $ SAC : int 0 0 0 3 2 0 1 5 3 3 ... $ SF : int 6 3 0 1 0 3 2 6 3 4 ... $ XBH : int 55 72 0 33 2 35 18 36 39 46 ... $ GO : int 97 70 2 73 6 95 60 96 39 80 ... $ AO : int 95 74 0 67 2 105 57 84 75 106 ... $ GO.AO : chr "1.02" "0.95" "-" "1.09" ... $ GW.RBI: int 7 10 0 6 0 2 1 5 1 3 ... $ BB.K : chr "1" "0.42" "0.25" "0.3" ... $ P.PA : chr "4" "4.07" "4.7" "3.89" ... $ ISOP : chr "0.25" "0.383" "0" "0.174" ... $ XR : num 88.4 113.3 1.3 47.9 4.2 ... $ GPA : num 0.351 0.378 0.263 0.293 0.271 0.287 0.293 0.292 0.304 0.285 ...
야구 약어
https://ko.wikipedia.org/wiki/%EC%95%BC%EA%B5%AC_%EA%B8%B0%EB%A1%9D
class(df$AVG) df$AVG <- as.numeric(df$AVG) # 타율 df$GO.AO <- as.numeric(df$GO.AO) # 땅볼 대 플라이볼 비율 df$BB.K <- as.numeric(df$BB.K)# 볼넷 대 삼진 비율 df$P.PA <- as.numeric(df$P.PA) # 투구수 / 타석 df$ISOP <- as.numeric(df$ISOP) # 순장타율(장타율-타율)
'character'
Warning message in eval(expr, envir, enclos): "강제형변환에 의해 생성된 NA 입니다" Warning message in eval(expr, envir, enclos): "강제형변환에 의해 생성된 NA 입니다" Warning message in eval(expr, envir, enclos): "강제형변환에 의해 생성된 NA 입니다" Warning message in eval(expr, envir, enclos): "강제형변환에 의해 생성된 NA 입니다" Warning message in eval(expr, envir, enclos): "강제형변환에 의해 생성된 NA 입니다"
# 홈런(HR)과 다른 변수간 상관계수 Cors <- cor(df$HR, df[, 5:length(df)], use='pairwise.complete.obs') # 피어슨 알고리즘으로 결측치 처리 Cors
A matrix: 1 × 22 of type dbl G PA AB R H X2B X3B HR TB RBI ⋯ XBH GO AO GO.AO GW.RBI BB.K P.PA ISOP XR GPA 0.6573121 0.7607232 0.7519703 0.8012273 0.7815465 0.7756991 0.3089791 1 0.8828075 0.9217014 ⋯ 0.9190164 0.6096195 0.7477335 -0.1618067 0.7889489 0.2839297 0.03248409 0.7813991 0.8815765 0.5505212 # 상관계수 정렬 Cors <- Cors[, order(Cors)] Cors
- GO.AO
- -0.161806712574124
- SAC
- 0.028827778858248
- P.PA
- 0.0324840926562767
- BB.K
- 0.283929662894909
- X3B
- 0.308979087457867
- GPA
- 0.550521232260773
- GO
- 0.609619485246719
- G
- 0.657312087742317
- SF
- 0.676635877811447
- AO
- 0.747733499475882
- AB
- 0.751970324849766
- PA
- 0.760723214863661
- X2B
- 0.775699070914623
- ISOP
- 0.781399092928558
- H
- 0.781546504304732
- GW.RBI
- 0.788948915070849
- R
- 0.801227338861749
- XR
- 0.8815764700245
- TB
- 0.882807451191371
- XBH
- 0.919016366686709
- RBI
- 0.921701367369363
- HR
- 1
# 뜬공 AO 0.7477334994755882 분석 해보기 df$HR[df$HR == 0] <- NA df$HR[df$AO == 0] <- NA # 홈런과 뜬공 데이터 값 0(NA) 제거 df <- na.omit(df)
# 회귀모델 구하기 Lm <- lm(HR~AO, data = df) Lm # y = -0.5244 + 0.1541 x (홈런 10개당 뜬공 1.5개)
Call: lm(formula = HR ~ AO, data = df) Coefficients: (Intercept) AO -0.5244 0.1541
# F통계량과 결정계수 # Multiple R-squared : 0.4156 애매함 - 부적합 # p-value : 0.00000000000000022 < 0.05 적합 summary(Lm)
Call: lm(formula = HR ~ AO, data = df) Residuals: Min 1Q Median 3Q Max -14.2728 -2.8553 -0.4085 2.2129 31.1208 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) -0.52444 0.90894 -0.577 0.565 AO 0.15410 0.01502 10.260 <0.0000000000000002 *** --- Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 Residual standard error: 5.932 on 148 degrees of freedom Multiple R-squared: 0.4156, Adjusted R-squared: 0.4117 F-statistic: 105.3 on 1 and 148 DF, p-value: < 0.00000000000000022
# 잔차 그래프 확인 # 1번 0 주위로 일정한 패턴 없이 분산 - 적합 # 2번 Q-Q 선에 많은 점들이 모여 있음 - 정규분포 적합 # 3,4번 특이한 사항이 없으 - 적합 par(mfrow = c(2,2)) plot(Lm)
결정계수 값이 조금 애매 하긴 했어도 F통계량 및 잔차 그래프가 정규분포를 잘 따름
다중 선형 회귀모델(Multiple linear regression)
-
보통의 사회현상은 종속변수에 여러 독립변수가 영향을 미침
Y=β0+β1X1+β2X2+β3X3+...+βpXp+ϵ -
각 변수들은 서로 독립
-
반대로 각각의 설명변수x1,x2,… 와 종속변수 y는 관계가 있어야함
-
단 현실적으로는 100% 만족하기 힘든 가정
-
회귀계수는 다른 변수가 고정되었을때 해당 변수의 단위변화율
-
계산 자체는 단순회귀분석과 마찬가지로 최소제곱법을 사용
-
독립변수가 3개면 4차원 그래프 필요 => 수치를 통해 해석
-
회귀계수가 0이 되지 않을 확률 확인 => 기울기 0
mtcars 데이터셋 다중선형회귀분석
마력(hp)에 실린더수(cyl) + 차체무게(wt) 영향 분석
# 데이터 로드 df <- mtcars str(df)
'data.frame': 32 obs. of 11 variables: $ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ... $ cyl : num 6 6 4 6 8 6 8 4 4 6 ... $ disp: num 160 160 108 258 360 ... $ hp : num 110 110 93 110 175 105 245 62 95 123 ... $ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ... $ wt : num 2.62 2.88 2.32 3.21 3.44 ... $ qsec: num 16.5 17 18.6 19.4 17 ... $ vs : num 0 0 1 1 0 1 0 1 1 1 ... $ am : num 1 1 1 0 0 0 0 0 0 0 ... $ gear: num 4 4 4 3 3 3 3 4 4 4 ... $ carb: num 4 4 1 1 2 1 4 2 2 4 ...
# 회귀모델 각각 구해보기 Lm_t1 <- lm(hp~cyl, data = df) Lm_t2 <- lm(hp~wt, data = df)
Lm_t1 Lm_t2
Call: lm(formula = hp ~ cyl, data = df) Coefficients: (Intercept) cyl -51.05 31.96 Call: lm(formula = hp ~ wt, data = df) Coefficients: (Intercept) wt -1.821 46.160
# 독립변수 추가 Lm <- lm(hp~cyl+wt, data = df)
Lm # y = -51.81 + 31.39x1 + 1.33x2
Call: lm(formula = hp ~ cyl + wt, data = df) Coefficients: (Intercept) cyl wt -51.81 31.39 1.33
# 검증하기 # Multiple R-squared: 0.6931 # p-value: 0.00000003641 # 회귀계수 0 될 확률 Pr(>|t|) => 0.05보다 작은 값이 나와야 함 wt 값 0.9 => 필요없는 변수 summary(Lm)
Call: lm(formula = hp ~ cyl + wt, data = df) Residuals: Min 1Q Median 3Q Max -53.98 -25.75 -10.93 20.88 130.95 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) -51.806 26.231 -1.975 0.0579 . cyl 31.388 6.343 4.949 0.0000293 *** wt 1.330 11.577 0.115 0.9093 --- Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 Residual standard error: 39.27 on 29 degrees of freedom Multiple R-squared: 0.6931, Adjusted R-squared: 0.6719 F-statistic: 32.75 on 2 and 29 DF, p-value: 0.00000003641
wt 변수 제거, summary()를 통해 통계량을 살펴보면서 다중회귀 분석
지구 최고온도에 영향을 미치는 독립변수로 다중회귀분석하기
-
airquality 내장 데이터셋 사용
-
뉴욕의 1973년 5월부터 9월까지의 대기상태 정보
-
최고온도(Temp) = 오존량(Ozone) + 태양방사선량(Solor.R) + 평균풍속(Wind)
str(airquality)
'data.frame': 153 obs. of 6 variables: $ Ozone : int 41 36 12 18 NA 28 23 19 8 NA ... $ Solar.R: int 190 118 149 313 NA NA 299 99 19 194 ... $ Wind : num 7.4 8 12.6 11.5 14.3 14.9 8.6 13.8 20.1 8.6 ... $ Temp : int 67 72 74 62 56 66 65 59 61 69 ... $ Month : int 5 5 5 5 5 5 5 5 5 5 ... $ Day : int 1 2 3 4 5 6 7 8 9 10 ...
# 데이터 확인 head(airquality, 5)
Ozone Solar.R Wind Temp Month Day <int> <int> <dbl> <int> <int> <int> 1 41 190 7.4 67 5 1 2 36 118 8.0 72 5 2 3 12 149 12.6 74 5 3 4 18 313 11.5 62 5 4 5 NA NA 14.3 56 5 5 # 변수간 관계 그리기 # Ozone과 Temp의 관계가 의미있어보임 plot(airquality)
# 다중회귀 분석 실시 df = airquality
# 회귀모델 구하기 # y = 72.418579 + 0.171966 * x1 + 0.007276 * x2 - 0.322945 * x3 Lm <- lm(df$Temp~df$Ozone+df$Solar.R+df$Wind, data = df) Lm
Call: lm(formula = df$Temp ~ df$Ozone + df$Solar.R + df$Wind, data = df) Coefficients: (Intercept) df$Ozone df$Solar.R df$Wind 72.418579 0.171966 0.007276 -0.322945
# 회귀모델 검증 # Multiple R-squared : 0.4999 비적합 # p-value : 0.0000000000000004729 적합 # Pr(>|t|) Solar.R : 0.345 , df$Wind : 0.169 => 0이될 가능성 높음 summary(Lm)
Call: lm(formula = df$Temp ~ df$Ozone + df$Solar.R + df$Wind, data = df) Residuals: Min 1Q Median 3Q Max -20.942 -4.996 1.283 4.434 13.168 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 72.418579 3.215525 22.522 < 0.0000000000000002 *** df$Ozone 0.171966 0.026390 6.516 0.00000000242 *** df$Solar.R 0.007276 0.007678 0.948 0.345 df$Wind -0.322945 0.233264 -1.384 0.169 --- Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 Residual standard error: 6.834 on 107 degrees of freedom (42 observations deleted due to missingness) Multiple R-squared: 0.4999, Adjusted R-squared: 0.4858 F-statistic: 35.65 on 3 and 107 DF, p-value: 0.0000000000000004729
2015 KBO 야구 데이터 다중선형회귀분석
# 데이터 로드 # R 4.0 부터 stringsAsFactors = F가 default 3.6버전에선 T가 default df <- read.csv('r-ggagi-data/example_kbo2015_player.csv', na='-') str(df)
'data.frame': 337 obs. of 26 variables: $ 순위 : int 1 2 3 4 5 6 7 8 9 10 ... $ 선수명: chr "유한준" "박병호" "홍성갑" "고종욱" ... $ 팀명 : chr "넥센" "넥센" "넥센" "넥센" ... $ AVG : num 0.364 0.349 0.333 0.324 0.318 0.316 0.311 0.3 0.295 0.287 ... $ G : int 101 106 7 85 44 96 68 99 79 103 ... $ PA : int 436 476 10 328 26 405 253 389 339 436 ... $ AB : int 376 410 9 299 22 370 219 333 295 383 ... $ R : int 82 100 0 59 17 53 40 52 62 68 ... $ H : int 137 143 3 97 7 117 68 100 87 110 ... $ X2B : int 35 29 0 22 2 21 10 22 21 28 ... $ X3B : int 1 1 0 3 0 0 0 1 1 4 ... $ HR : int 19 42 0 8 0 14 8 13 17 14 ... $ TB : int 231 300 3 149 9 180 102 163 161 188 ... $ RBI : int 84 111 2 40 3 65 21 67 53 57 ... $ SAC : int 0 0 0 3 2 0 1 5 3 3 ... $ SF : int 6 3 0 1 0 3 2 6 3 4 ... $ XBH : int 55 72 0 33 2 35 18 36 39 46 ... $ GO : int 97 70 2 73 6 95 60 96 39 80 ... $ AO : int 95 74 0 67 2 105 57 84 75 106 ... $ GO.AO : num 1.02 0.95 NA 1.09 3 0.9 1.05 1.14 0.52 0.75 ... $ GW.RBI: int 7 10 0 6 0 2 1 5 1 3 ... $ BB.K : num 1 0.42 0.25 0.3 0.29 0.45 0.78 0.63 0.31 0.46 ... $ P.PA : num 4 4.07 4.7 3.89 4.08 3.98 4.19 3.85 4.14 4.22 ... $ ISOP : num 0.25 0.383 0 0.174 0.091 0.17 0.155 0.189 0.251 0.204 ... $ XR : num 88.4 113.3 1.3 47.9 4.2 ... $ GPA : num 0.351 0.378 0.263 0.293 0.271 0.287 0.293 0.292 0.304 0.285 ...
# 문자열 숫자형으로 변경 df$AVG <- as.numeric(df$AVG) # 타율 df$GO.AO <- as.numeric(df$GO.AO) # 땅볼 대 플라이볼 비율 df$BB.K <- as.numeric(df$BB.K)# 볼넷 대 삼진 비율 df$P.PA <- as.numeric(df$P.PA) # 투구수 / 타석 df$ISOP <- as.numeric(df$ISOP) # 순장타율(장타율-타율)
# 홈런(HR)과 다른 변수간 상관계수 Cors <- cor(df$HR, df[,5:length(df)], use='pairwise.complete.obs') # 피어슨 알고리즘으로 결측치 처리 Cors
A matrix: 1 × 22 of type dbl G PA AB R H X2B X3B HR TB RBI ⋯ XBH GO AO GO.AO GW.RBI BB.K P.PA ISOP XR GPA 0.6573121 0.7607232 0.7519703 0.8012273 0.7815465 0.7756991 0.3089791 1 0.8828075 0.9217014 ⋯ 0.9190164 0.6096195 0.7477335 -0.1618067 0.7889489 0.2839297 0.03248409 0.7813991 0.8815765 0.5505212 # 상관 계수 정렬 Cors <- Cors[,order(Cors)] Cors
- GO.AO
- -0.161806712574124
- SAC
- 0.028827778858248
- P.PA
- 0.0324840926562767
- BB.K
- 0.283929662894909
- X3B
- 0.308979087457867
- GPA
- 0.550521232260773
- GO
- 0.609619485246719
- G
- 0.657312087742317
- SF
- 0.676635877811447
- AO
- 0.747733499475882
- AB
- 0.751970324849766
- PA
- 0.760723214863661
- X2B
- 0.775699070914623
- ISOP
- 0.781399092928558
- H
- 0.781546504304732
- GW.RBI
- 0.788948915070849
- R
- 0.801227338861749
- XR
- 0.8815764700245
- TB
- 0.882807451191371
- XBH
- 0.919016366686709
- RBI
- 0.921701367369363
- HR
- 1
# 상관계수 높은 5개 변수 다중회귀로 분석 R (득점) df$HR[df$HR == 0] <- NA df$RBI[df$RBI == 0] <- NA # 타점 df$XBH[df$XBH == 0] <- NA # 장타 df$TB[df$TB == 0] <- NA # 루타 df$XR[df$XR == 0] <- NA # 추정득점 => 득점이되는 이벤트가 많아서 선형가중한것 df$R[df$R == 0] <- NA # 득점
# 회귀모델 구하기 Lm <- lm(HR ~ RBI + XBH + TB + XR + R, data = df) Lm
Call: lm(formula = HR ~ RBI + XBH + TB + XR + R, data = df) Coefficients: (Intercept) RBI XBH TB XR R -0.43714 0.15582 0.53837 -0.09486 0.15782 -0.12392
# 검증해보기 # Multiple R-squared : 0.873 적합 # p-value : < 0.00000000000000022 적합 # Pr(>|t|) 적합 summary(Lm)
Call: lm(formula = HR ~ RBI + XBH + TB + XR + R, data = df) Residuals: Min 1Q Median 3Q Max -7.1729 -1.5779 0.1418 1.3689 10.7785 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) -0.43714 0.45244 -0.966 0.33557 RBI 0.15582 0.03477 4.482 0.00001497787021 *** XBH 0.53837 0.07196 7.482 0.00000000000665 *** TB -0.09486 0.03033 -3.128 0.00213 ** XR 0.15782 0.06328 2.494 0.01377 * R -0.12392 0.03806 -3.256 0.00141 ** --- Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 Residual standard error: 2.803 on 144 degrees of freedom (187 observations deleted due to missingness) Multiple R-squared: 0.873, Adjusted R-squared: 0.8686 F-statistic: 198 on 5 and 144 DF, p-value: < 0.00000000000000022
-