본문 바로가기
배우는 것들/R

데이터과학을 위한 통계 -7

by Ho.virus 2021. 3. 1.

4.6.2 영향값

 

쿡의 거리는 데이터의 영향력을 가시화하는 그래프이다.

house = read.csv("house_sales.csv", sep = " ", header = T,stringsAsFactors = F)
house[house$ZipCode == -1,"ZipCode"] = NA
house = na.omit(house)
house_lm = lm(AdjSalePrice ~ SqFtTotLiving + SqFtLot + Bathrooms + Bedrooms + BldgGrade, data = house, na.action = na.omit)


house_98105 = house[house$ZipCode == 98105,]

lm_98105 = lm(AdjSalePrice ~ SqFtTotLiving + SqFtLot + Bathrooms + Bedrooms + BldgGrade, data = house_98105)
std_resid = rstandard(lm_98105)
cooks_D = cooks.distance(lm_98105)
hatvalues = hatvalues(lm_98105)
plot(hatvalues,std_resid,cex = 10*sqrt(cooks_D))
abline(h = c(-2.5,2.5),lty = 2)


library("ggplot2")

df = data.frame(
  resid = residuals(lm_98105),
  pred = predict(lm_98105))
 
 

 

cex 인수를 통해 플롯의 크기를 결정할 수 있다. 기본 함수만으로도 구현 가능.

 

4.6.3 이분산성, 비정규성, 오차간 상관

잔차의 분포는 통계적 추론(검정)에 유의미한 결과를 미친다.

가설검정이 유효하려면 잔차는 다음과 같은 가정을 따라야 한다.

  1. 동일한 분산이다.
  2. 정규분포를 따른다.
  3. 잔차들이 서로 독립이다.

데이터 과학에서 중요한 것은 잔차에 대한 가정을 기반으로 예측값의 신뢰구간을 계산하는 것이다.

df = data.frame(
  resid = residuals(lm_98105),
  pred = predict(lm_98105))

ggplot(df, aes(pred, abs(resid)))+
  geom_point() +
  geom_smooth()
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

lm_98105 모델의 잔차는 동일한 분산을 가지고 있지 않다. = 이분산성을 가지고 있다.

그래프는 가격이 너무 높거나 낮은 주택에 대해 잘 설명하지 못한다는것을 나타낸다.

4.6.4 편잔차 그림과 비선형성

predict 인수에서 type = ‘terms’ 옵션은 예측값=yhat 이 아닌, 회귀항 = Xi * Bhat 을 보여준다.

아무것도 넣지 않았을 때에는 Yhat을 보여준다.

전체를 고려한 회귀분석의 잔차를 각 회귀항마다 전부 더해준다. 단일 변수에 대해 전체를 고려한 잔차를 더한것이 편잔차이다.

terms = predict(lm_98105, type = 'terms')

partial_resid = resid(lm_98105) + terms


df = data.frame(SqFtTotLiving = house_98105[, 'SqFtTotLiving'],
                Terms = terms[, 'SqFtTotLiving'],
                PartialResid = partial_resid[, 'SqFtTotLiving'])
ggplot(df, aes(SqFtTotLiving , PartialResid)) +
  geom_point(shape = 1) + scale_shape(solid = F) +
  geom_smooth(linetype = 2) + 
  geom_line(aes(SqFtTotLiving , Terms))
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
 
 

 

이 편잔차 그림은 SqFtTotLiving 변수가 주택가격에 얼마나 영향을 미치는지 알 수 있다.

SqFtTotLiving가 예측값에 큰 영향을 미치고 있다면 전체를 고려한 잔차를 더해도 기존의 회귀선에서 크게 벗어나지 않을 것이다.

만약 잔차가 정규성을 띄는 오차의 성질을 가지고있다면, 편잔차 그림이 어떠한 경향성을 띄지 않을 것이다.

만약 SqFtTotLiving 만으로 설명되지 않은것이 있거나 변수의 형태(n차항)가 적절하지 않다면 일정한 경향성을 띄고 나타날 것이다.

대략 1000제곱피트보다 작은 평수의 집에 대해서는 가격을 원래보다 낮게 추정하고 있고, 2000~3000 제곱피트의 집에 대해서는 더 높게 추정하고 있다.

SqFtTotLiving은 비선형성을 가지고 있으므로 n차항으로의 변수변환을 고려할 수 있다.

4.7.1 다항식

poly 함수를 이용해 이차다항식을 새로 피팅한다.

뭔가 더 깔끔한 방법으로 할 수 있을것 같은데 무식한 나는 그냥 복붙 통짜 코딩… ㅎ

house_lm2 = lm(AdjSalePrice ~ poly(SqFtTotLiving, 2) + SqFtLot + Bathrooms + Bedrooms + BldgGrade, data = house, na.action = na.omit)

lm_98105_2 = lm(AdjSalePrice ~ poly(SqFtTotLiving,2) + SqFtLot + Bathrooms + Bedrooms + BldgGrade, data = house_98105, na.action = na.omit)


terms2 = predict(lm_98105_2, type = 'terms')
colnames(terms2) = c('SqFtTotLiving' , 'SqFtLot' ,'Bathrooms', 'Bedrooms' ,'BldgGrade'  )
partial_resid2 = resid(lm_98105_2) + terms2

df2 = data.frame(SqFtTotLiving = house_98105[, 'SqFtTotLiving'],
                Terms = terms2[, 'SqFtTotLiving'],
                PartialResid = partial_resid2[, 'SqFtTotLiving'])

ggplot(df2, aes(SqFtTotLiving , PartialResid)) +
  geom_point(shape = 1) + scale_shape(solid = F) +
  geom_smooth(linetype = 2) + 
  geom_line(aes(SqFtTotLiving , Terms))
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

선형 회귀일때의 편잔차 곡선보다 더 편잔차의 곡선에 가깝다는것을 알 수 있다.

4.7.2 스플라인

앞서 배운 스플라인 패키지와 함수를 이용한다.

library(splines)

knots = quantile(house_98105$SqFtTotLiving, p = c(.25,.5,.75))
lm_spline = lm(AdjSalePrice ~ bs(SqFtTotLiving, knots = knots, degree = 3) + SqFtLot + Bathrooms + Bedrooms + BldgGrade, data = house_98105)

terms3 = predict(lm_spline , type = 'terms')

colnames(terms3) =colnames(terms)
partial_resid3 = resid(lm_spline) + terms3

df3 = data.frame(SqFtTotLiving = house_98105[, 'SqFtTotLiving'],
                 Terms = terms3[, 'SqFtTotLiving'],
                 PartialResid = partial_resid3[, 'SqFtTotLiving'])


ggplot(df3, aes(SqFtTotLiving , PartialResid)) +
         geom_point(shape = 1) + scale_shape(solid = F) +
         geom_smooth(linetype = 2) + 
         geom_line(aes(SqFtTotLiving , Terms))
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

다항회귀보다 더 매끄럽게 매칭된다. 하지만 이것이 스플라인 회귀가 더 좋다는것을 의미하는것은 아니다. 1000제곱피트 미만의 주택 가격이 경제적 상식과 맞지않는다. 교란변수인 zipcode 때문일 수 있다.

4.7.3 일반화 가법모형

스플라인의 노드를 자동으로 찾아주는 일반화가법 모형은 패키지의 오류로 실행하지 못했다… 해외에도 나와 같은 오류를 겪는분이 몇 있는데 해결방법이 너무 복잡하기에 패스하기로 ㅎㅎ

library(mgcv)
lm_gam = gam(AdjSalePrice ~ s(SqFtTotLiving) + SqFtLot + Bathrooms + Bedrooms + BldgGrade, data = house_98105)

 

'배우는 것들 > R' 카테고리의 다른 글

R - ggplot 이중 축, 범례 생성 코드  (0) 2023.02.01
R 복습.  (0) 2021.08.03
데이터 과학을 위한 통계 - 6  (0) 2021.02.08
데이터 과학을 위한 통계 - 5  (0) 2021.01.31
데이터 과학을 위한 통계 - 4  (0) 2021.01.29