4.2.5 가중회귀
날짜처리 패키지를 설치하고 house의 거래날짜를 기준으로 가중치로 설정한다.
최근 거래에 더 큰 영향을 받는 모델이 만들어지도록.
library("lubridate")
##
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
##
## date, intersect, setdiff, union
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$year = year(house$DocumentDate)
house$weight = house$year - 2005
lm함수의 weigh 인수를 통해 가중치를 설정하고 출력한다.
house_wt = lm(AdjSalePrice ~ SqFtTotLiving + SqFtLot + Bathrooms + Bedrooms + BldgGrade, data = house, weight = house$weight)
round(cbind(house_lm = house_lm$coefficients,
house_wt = house_wt$coefficients), digits = 3)
## house_lm house_wt
## (Intercept) -521924.722 -584265.244
## SqFtTotLiving 228.832 245.017
## SqFtLot -0.061 -0.292
## Bathrooms -19438.099 -26079.171
## Bedrooms -47781.153 -53625.404
## BldgGrade 106117.210 115259.026
기존 회귀분석 결과와는 살짝 다르다.
4.4 회귀에서의 요인변수
4.4.1 가변수 표현
주거 형태에 관한 요인변수 = Factor 변수를 회귀에서 표현하자.
head(house[, 'PropertyType'])
## [1] "Multiplex" "Single Family" "Single Family" "Single Family"
## [5] "Single Family" "Townhouse"
prop_type_dummie = model.matrix(~PropertyType -1, data = house)
head(prop_type_dummie)
## PropertyTypeMultiplex PropertyTypeSingle Family PropertyTypeTownhouse
## 1 1 0 0
## 2 0 1 0
## 3 0 1 0
## 4 0 1 0
## 5 0 1 0
## 6 0 0 1
가능한 값은 “Multiplex”, “Single Family”, “Townhouse” 세가지 이다. -1 인수를 추가해 “원-핫 인코딩” 이라는 표현방법을 쓴다. 이 인수를 추가하지 않으면 “Multiplex” 인자가 절편으로 취급된다.
이렇게 표현한 데이터를 포함시켜 회귀해보자.
lm(AdjSalePrice ~ SqFtTotLiving + SqFtLot + Bathrooms + Bedrooms + BldgGrade + PropertyType, data = house)
##
## Call:
## lm(formula = AdjSalePrice ~ SqFtTotLiving + SqFtLot + Bathrooms +
## Bedrooms + BldgGrade + PropertyType, data = house)
##
## Coefficients:
## (Intercept) SqFtTotLiving
## -4.469e+05 2.234e+02
## SqFtLot Bathrooms
## -7.041e-02 -1.597e+04
## Bedrooms BldgGrade
## -5.090e+04 1.094e+05
## PropertyTypeSingle Family PropertyTypeTownhouse
## -8.469e+04 -1.151e+05
summary(lm(AdjSalePrice ~ SqFtTotLiving + SqFtLot + Bathrooms + Bedrooms + BldgGrade + PropertyType, data = house))
##
## Call:
## lm(formula = AdjSalePrice ~ SqFtTotLiving + SqFtLot + Bathrooms +
## Bedrooms + BldgGrade + PropertyType, data = house)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1193447 -118654 -20333 86579 9477505
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -4.469e+05 2.236e+04 -19.986 < 2e-16 ***
## SqFtTotLiving 2.234e+02 4.130e+00 54.091 < 2e-16 ***
## SqFtLot -7.041e-02 6.122e-02 -1.150 0.25
## Bathrooms -1.597e+04 3.810e+03 -4.193 2.77e-05 ***
## Bedrooms -5.090e+04 2.538e+03 -20.058 < 2e-16 ***
## BldgGrade 1.094e+05 2.457e+03 44.533 < 2e-16 ***
## PropertyTypeSingle Family -8.469e+04 1.665e+04 -5.088 3.66e-07 ***
## PropertyTypeTownhouse -1.151e+05 1.816e+04 -6.340 2.34e-10 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 261000 on 22681 degrees of freedom
## Multiple R-squared: 0.5415, Adjusted R-squared: 0.5414
## F-statistic: 3827 on 7 and 22681 DF, p-value: < 2.2e-16
“Multiplex”는 나머지 두 변수에 의해 암묵적으로 정의되기 때문에 (“Single Family” == 0, “Townhouse” == 0 일 때) 표시되지 않는다.
다른 조건이 같을 때 “Single Family” 는 “Multiplex”에 비해 주택가격이 85000정도 낮고, “Townhouse”는 115000정도 가격이 낮다.
4.4.2 다수의 수준을 같는 요인 변수들
위와 같은 요인변수와는 달리, 가능한 level이 많은 요인변수가 있다. ZipCode를 잔차의 중간값을 기준으로 5개의 그룹으로 묶는다.
library("dplyr")
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
zipgroup의 잔차의 중간값을 계산하고, 이를 이용해 주택의 가격순으로 정렬해 우편번호에 1~5까지의 그룹 값을 매긴다.
zip_groups = house %>%
mutate(resid = residuals(house_lm)) %>%
group_by(ZipCode) %>%
summarize(med_resid = median(resid),
cnt = n()) %>%
arrange(med_resid) %>%
mutate(cum_cnt = cumsum(cnt),
ZipGroup = ntile(cum_cnt, 5))
house = house %>%
left_join(select(zip_groups,ZipCode,ZipGroup), by = 'ZipCode')
head(house$ZipGroup)
## [1] 3 3 3 3 3 4
ZipCode가 포함되지 않은 상태 시행한 회귀모델과의 잔차이다. 예측값보다 더 높은 잔차를 가지는 우편번호가 더 높은 수치를 갖도록 설정했다.
4.5 회귀방정식 해석
4.5.3 교란변수
교란변수란 Y에 큰 영향을 미치지만 모델에 포함이 안되어있어 모델의 정확성을 낮추는 변수를 말한다.
예를들면 주택 거래에서는 주택의 위치(지역)이 가격에 큰 영향을 미치지만 포함이 되어있지 않아 교란변수일 가능성이 있다.
교란변수 일 수 있는 ’주택의 위치’를 대리변수를 이용해 우편번호로 표현한다.
앞서 추가한 변수인 ZipGroup을 사용한다.
house$ZipGroup = as.factor(house$ZipGroup)
lm(AdjSalePrice ~ SqFtTotLiving + SqFtLot + Bathrooms + Bedrooms + BldgGrade + PropertyType + ZipGroup, data = house, na.action = na.omit)
##
## Call:
## lm(formula = AdjSalePrice ~ SqFtTotLiving + SqFtLot + Bathrooms +
## Bedrooms + BldgGrade + PropertyType + ZipGroup, data = house,
## na.action = na.omit)
##
## Coefficients:
## (Intercept) SqFtTotLiving
## -6.744e+05 2.115e+02
## SqFtLot Bathrooms
## 4.763e-01 5.482e+03
## Bedrooms BldgGrade
## -4.128e+04 9.927e+04
## PropertyTypeSingle Family PropertyTypeTownhouse
## 2.101e+04 -7.747e+04
## ZipGroup2 ZipGroup3
## 5.421e+04 1.175e+05
## ZipGroup4 ZipGroup5
## 1.785e+05 3.391e+05
* 연산자를 통해 상호작용을 표현할 수 있다. 집의 크기와 집의 위치는 상호작용이 있을것이라고 생각하는게 합리적이므로 SqFtTotLiving*ZipGroup를 인수로 넣어 상호작용을 포함한 회귀분석을 한다.
lm(AdjSalePrice ~ SqFtTotLiving*ZipGroup + SqFtLot + Bathrooms + Bedrooms + BldgGrade + PropertyType, data = house, na.action = na.omit)
##
## Call:
## lm(formula = AdjSalePrice ~ SqFtTotLiving * ZipGroup + SqFtLot +
## Bathrooms + Bedrooms + BldgGrade + PropertyType, data = house,
## na.action = na.omit)
##
## Coefficients:
## (Intercept) SqFtTotLiving
## -4.923e+05 1.174e+02
## ZipGroup2 ZipGroup3
## -1.719e+04 2.247e+04
## ZipGroup4 ZipGroup5
## 1.760e+04 -1.557e+05
## SqFtLot Bathrooms
## 7.252e-01 -5.348e+03
## Bedrooms BldgGrade
## -4.172e+04 1.055e+05
## PropertyTypeSingle Family PropertyTypeTownhouse
## 1.554e+04 -5.646e+04
## SqFtTotLiving:ZipGroup2 SqFtTotLiving:ZipGroup3
## 3.561e+01 3.907e+01
## SqFtTotLiving:ZipGroup4 SqFtTotLiving:ZipGroup5
## 7.059e+01 2.299e+02
4.6 회귀진단
4.6.1 특잇값
표준화 잔차를 조사해 특잇값을 찾을 수 있다.
rstandrd함수를 이용해 표준화 잔차를 구하고, 그 순서대로 정렬한다.
house_98105 = house[house$ZipCode == 98105,]
lm_98105 = lm(AdjSalePrice ~ SqFtTotLiving + SqFtLot + Bathrooms + Bedrooms + BldgGrade, data = house_98105)
sresid = rstandard(lm_98105)
idx = order(sresid)
sresid[idx[1]]
## 20431
## -4.326732
표준오차보다 4배 이상 차이가 난다 (잔차/표준오차 이므로)
house_98105[idx[1],c('AdjSalePrice' , 'SqFtTotLiving' , 'SqFtLot' , 'Bathrooms' , 'Bedrooms' , 'BldgGrade')]
## AdjSalePrice SqFtTotLiving SqFtLot Bathrooms Bedrooms BldgGrade
## 20431 119748 2900 7276 3 6 7
이 레코드의 거래값은 119748이다.
predict(house_lm, newdata = house_98105[idx[1],c('AdjSalePrice' , 'SqFtTotLiving' , 'SqFtLot' , 'Bathrooms' , 'Bedrooms' , 'BldgGrade')])
## 20431
## 539067.4
예측된 거래값은 539067이다. 기존 데이터들에서 크게 벗어나있는 레코드이며 특잇값이라고 할 수 있다.
'배우는 것들 > R' 카테고리의 다른 글
R 복습. (0) | 2021.08.03 |
---|---|
데이터과학을 위한 통계 -7 (0) | 2021.03.01 |
데이터 과학을 위한 통계 - 5 (0) | 2021.01.31 |
데이터 과학을 위한 통계 - 4 (0) | 2021.01.29 |
데이터 과학을 위한 통계학 - 3 (0) | 2021.01.24 |