SlideShare a Scribd company logo
1 of 33
다중회귀분석 Multi-Regression Analyse
“미국의 집값에 영향을 미치는 요인들에 대한 분석”
House Pricing
1. 독립변수에 대한 설명
(1) 자료에 대한 요약
i. 모든 변수들 간의 상관관계
# date 변수를 numeric 으로 바꾸기
date_numeric <- substr(kc_house$date, 1, 8) # 20141124 형태로 연도날짜 문자부분만
추출
is.numeric(date_numeric) # FALSE
date_numeric <- as.numeric(date_numeric)
is.numeric(date_numeric) # TRUE
kc_house$date <- date_numeric # 기존의 date 를 새로운 numeric date 로 대체
View(kc_house)
house_cor <- cor(kc_house) # 모든 변수들의 서로서로 간의 상관관계를 계산
#
library(psych)
house_cortest <- psych::corr.test(kc_house)
DT::datatable(house_cortest)
View(house_cortest)
library(Hmisc)
Hmisc::rcorr(as.matrix(attitude))
round(house_cor, 2) # 소숫점 둘째자리까지 round
pairs(house_cor,
pch = 19,
bg = c("red", "green", "blue")) # 행렬모양 산점도
corrplot(house_cor)
# 상관원계수가 클수록 크기가 크고 색깔이 진하다
# 양수면 파란색, 음수면 붉은색
corrplot(house_cor, method = "number") # 수와 색깔로 표현
col <- colorRampPalette(c("#BB4444", "#EE9988", "#FFFFFF", "#77AADD",
"#4477AA"))
corrplot(house_cor,
method = "color", # 색깔로 표현
col = col(200), # 색상 200 개 선정
type = "lower", # 왼쪽 아래 행렬만 표기
order = "hclust", # 유사한 상관계수끼리 군집화
addCoef.col = "black", # 상관계수 색깔
tl.col = "black", # 변수명 색깔
tl.srt = 45, # 변수명 45 도 기울임
diag = FALSE) # 대각행렬 제외
i-1. 상관계수를 세 그룹으로 나누어 표현
Plot1. price, bedrooms, bathrooms, sqft_living and sqft lot
Plot2. price, floors, waterfront, view, condition and grade
Plot 3. price, yr built, lat and long
< 결과 >
# 상관관계가 높은 변수들 ( > 0.5)
# sqft_lot15 - sqft_lot : 0.72 # 둘다 삭제
# bathrooms - floors : 0.50 # 변환(모델링)
# bathrooms - yr_built : 0.51 # bathrooms 채택
# bathrooms - bedrooms : 0.52 # 변환(모델링)
# price - bathrooms : 0.53
# sqft_living15 - bathrooms : 0.57 # bathrooms 채택
# sqft_living15 - price : 0.59
# grade - bathrooms : 0.66 # bathrooms 변환
# grade - price : 0.67
# grade - sqft_living15 : 0.71 # grade 채택
# sqft_living - bedrooms : 0.58 # 변환(모델링)
# sqft_living - bathrooms : 0.75 # 변환(모델링)
# sqft_living - price : 0.70
# sqft_living - sqft_living15 : 0.76 # sqft_living 채태
# sqft_living - grade : 0.76 # sqft_living 변환
# sqft_above - floors : 0.52 # floors 채택
# sqft_above - bathrooms : 0.69 # bathrooms 채택
# sqft_above - price : 0.61
# sqft_above - sqft_living15 : 0.73 # 둘다 삭제
# sqft_above - grade : 0.76 # grade 채택
# sqft_above - sqft_living : 0.88 # sqft_living 채택
# zipcode - long : -0.56 # zipcode 채택
채택변수 : bedrooms, bathrooms, sqft_living, floors, view, grade
ii. price 상위 25% 집을 지도에 표시
house_map + ggplot2::geom_point(data = high_25_loc,
aes(x = long, y = lat),
colour="red")
iii. zipcode 별로 집의 위치와 밀도를 지도에 표시
zipcode_1_10_loc <- kc_house[(kc_house$zipcode >=98001)&(kc_house$zipcode
<=98010), c("long", "lat")] #집코드별로 그룹화
zipcode_11_20_loc <- kc_house[(kc_house$zipcode >=98011)&(kc_house$zipcode
<=98020), c("long", "lat")]
zipcode_21_30_loc <- kc_house[(kc_house$zipcode >=98021)&(kc_house$zipcode
<=98030), c("long", "lat")]
zipcode_31_40_loc <- kc_house[(kc_house$zipcode >=98031)&(kc_house$zipcode
<=98040), c("long", "lat")]
zipcode_41_50_loc <- kc_house[(kc_house$zipcode >=98041)&(kc_house$zipcode
<=98050), c("long", "lat")]
house_map <- get_googlemap(center = c(lon =-122.1, lat =47.5),
zoom =10) %>% ggmap
house_map + ggplot2::geom_point(data = zipcode_1_10_loc,
aes(x = long, y = lat),
colour="red") +
ggplot2::geom_point(data = zipcode_11_20_loc,
aes(x = long, y = lat),
colour="orange") +
ggplot2::geom_point(data = zipcode_21_30_loc,
aes(x = long, y = lat),
colour="yellow") +
ggplot2::geom_point(data = zipcode_31_40_loc,
aes(x = long, y = lat),
colour="green") +
ggplot2::geom_point(data = zipcode_41_50_loc,
aes(x = long, y = lat),
colour="blue")
# zipcode group 이런식으로 집을 ggmap 과 ggplot2 패키지를 이용 그림에 표현해줌
zipcode__1_loc <- kc_house[kc_house$zipcode == grep("1$", kc_house$zipcode, value
= TRUE), c("long", "lat")]
zipcode__2_loc <- kc_house[kc_house$zipcode == grep("2$", kc_house$zipcode, value
= TRUE), c("long", "lat")]
zipcode__3_loc <- kc_house[kc_house$zipcode == grep("3$", kc_house$zipcode, value
= TRUE), c("long", "lat")]
house_map + ggplot2::geom_point(data = zipcode__1_loc,
aes(x = long, y = lat),
colour="red") +
ggplot2::geom_point(data = zipcode__2_loc,
aes(x = long, y = lat),
colour="orange") +
ggplot2::geom_point(data = zipcode__3_loc,
aes(x = long, y = lat),
colour="yellow")
(2) 채택한 독립변수
- room_newnum : 집의 크기에 영향을 미치는 변수들(bathrooms, bedrooms, floors, sqft_living)
을 하나의 변수로 모델링
- waterfront : 해안가(waterfront) 여부
- view : 집을 보러온 횟수
- grade : 집에 대한 전반적인 평가척도
- X1 ~ X12 : price가 비슷한 zipcode 별 group화
i. room_newnum : 집의 크기에 영향을 미치는 변수들(bathrooms, bedrooms, floors,
sqft_living)을 하나의 변수로 모델링
- 분석방법 : 상관분석
# bedrooms, bathrooms, floors 데이터모델링하기
cor(kc_house$bedrooms, kc_house$price) # 0.308
cor(kc_house$bathrooms, kc_house$price) # 0.525
cor(kc_house$floors, kc_house$price) # 0.257
cor(kc_house$sqft_living, kc_house$price) # 0.702
cor(kc_house$sqft_lot, kc_house$price) # 0.090 # 제외!
kc_house_data$room_newnum = kc_house$bedrooms*0.308+ kc_house$bathrooms*0.525+
kc_house$floors*0.257+ kc_house$sqft_living*0.702
<데 이터 모델링 식>
kc_house_data$room_newnum = kc_house$bedrooms*0.308
+ kc_house$bathrooms*0.525
+ kc_house$floors*0.257
+ kc_house$sqft_living*0.702
cor(kc_house$room_newnum, kc_house$price) # 0.702
ii. waterfront : 해안가(waterfront) 여부
- 분석방법 : 양측 가설검정 (t-test)
# 해안가(=1) group 의 위치
waterfront_T <- kc_house[kc_house$waterfront ==1, c("long", "lat")]
# 해안가가 아닌(=0) group 의 위치
waterfront_F <- kc_house[kc_house$waterfront ==0, c("long", "lat")]
house_map <- get_googlemap(center = c(lon =-122.1, lat =47.5), zoom =10) %>% ggmap
house_map + ggplot2::geom_point(data = waterfront_T,
aes(x = long, y = lat),
colour="red") + ggplot2::geom_point(
data = waterfront_F,
aes(x = long, y = lat),
colour="orange")
# 해안가(=1) group 의 price
waterfront_T_price <- kc_house[kc_house$waterfront ==1, "price"]
# 해안가가 아닌(=0) group 의 price
waterfront_F_price <- kc_house[kc_house$waterfront ==0, "price"]
summary(waterfront_T_price[[1]])
summary(waterfront_F_price[[1]])
t.test(waterfront_T_price[[1]], waterfront_F_price[[1]])
boxplot(waterfront_T_price[[1]], waterfront_F_price[[1]])
결과
Welch Two Sample t-test
data: waterfront_T_price[[1]] and waterfront_F_price[[1]]
t = 12.876, df = 162.23, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
956963.3 1303661.6
sample estimates:
mean of x mean of y
1661876.0 531563.6
귀무가설 : 두 그룹의 평균은 같다
대립가설 : 두 그룹의 평균은 같지 않다
p-value < 0.000 이므로, 유의수준 a=0.05에서 귀무가설을 기각한다. 즉, 해안가에 위치한 집들
의 평균 집값과 해안가에 위치하지 않은 집들의 평균 집값이 다르다고 볼 수 있다.
iii. view : 집을 보러온 횟수
- 분석방법 : 여러 집단 간의 차이검정(ANOVA, scheffe.test)
view0_price <- kc_house[kc_house$view ==0,"price"]
length(view0_price[[1]]) # 19489
view1_price <- kc_house[kc_house$view ==1,"price"]
length(view1_price[[1]]) # 332
view2_price <- kc_house[kc_house$view ==2,"price"]
length(view2_price[[1]]) # 963
view3_price <- kc_house[kc_house$view ==3,"price"]
length(view3_price[[1]]) # 510
view4_price <- kc_house[kc_house$view ==4,"price"]
length(view4_price[[1]]) # 319
mean(view0_price[[1]]) # 496564.2
mean(view1_price[[1]]) # 812280.8
mean(view2_price[[1]]) # 792400.9
mean(view3_price[[1]]) # 971965.3
mean(view4_price[[1]]) # 1463711
view_price <- c(view0_price[[1]], view1_price[[1]], view2_price[[1]],
view3_price[[1]], view4_price[[1]])
length(view_price) # 21613
length(group) # 21613
group <- c(rep(0, 19489),
rep(1, 332),
rep(2, 963),
rep(3, 510),
rep(4, 319))
cbind(view_price, group)
boxplot(view_price ~ group, ylab = "Price", xlab = "View")
describe.by(view_price, group) # 그룹별기술통계량계산 # mad
ANO_R <- aov(view_price ~ group)
anova(ANO_R)
library(agricolae)
scheffe.test(ANO_R, "group", alpha =0.05, console = TRUE)
LSD.test(ANO_R, "group", alpha =0.05, console = TRUE)
duncan.test(ANO_R, "group", alpha =0.05, console = TRUE)
결과
> head( cbind(view_price, group) )
view_price group
[1,] 221900 0
[2,] 538000 0
[3,] 180000 0
[4,] 604000 0
[5,] 510000 0
[6,] 1225000 0
> tail( cbind(view_price, group) )
view_price group
[21608,] 580000 4
[21609,] 2300000 4
[21610,] 1149000 4
[21611,] 900000 4
[21612,] 2230000 4
[21613,] 3567000 4
> describe.by(view_price, group) # 그룹별 기술통계량 계산 # mad
Descriptive statistics by group
group: 0
vars n mean sd median trimmed mad min max range skew
kurtosis se
X1 1 19489 496564.2 287133.3 432500 456422 203857.5 75000 5570000 5495000 3.11
21.58 2056.78
------------------------------------------------------------------------------
group: 1
vars n mean sd median trimmed mad min max range skew
kurtosis se
X1 1 332 812280.8 510949.7 690944 722550.6 308714.4 217000 3650000 3433000 2.26
6.65 28042.01
------------------------------------------------------------------------------
group: 2
vars n mean sd median trimmed mad min max range skew kurtosis
se
X1 1 963 792400.9 510105 675000 714267.2 318759 169317 7062500 6893183 3.57 27.65
16437.91
------------------------------------------------------------------------------
group: 3
vars n mean sd median trimmed mad min max range skew
kurtosis se
X1 1 510 971965.3 612692.2 802500 892245.3 450710.4 154000 7700000 7546000 3.38
28.12 27130.47
------------------------------------------------------------------------------
group: 4
vars n mean sd median trimmed mad min max range skew
kurtosis se
X1 1 319 1463711 952209.6 1185000 1320949 667170 252000 6885000 6633000 1.84
4.87 53313.5
> scheffe.test(ANO_R, "group", alpha = 0.05, console = TRUE)
Study: ANO_R ~ "group"
Scheffe Test for view_price
Mean Square Error : 113513294940
group, means
view_price std r Min Max
0 496564.2 287133.3 19489 75000 5570000
1 812280.8 510949.7 332 217000 3650000
2 792400.9 510105.1 963 169317 7062500
3 971965.3 612692.2 510 154000 7700000
4 1463711.2 952209.6 319 252000 6885000
Alpha: 0.05 ; DF Error: 21611
Critical Value of F: 2.372343
Harmonic Mean of Cell Sizes 543.6342
Minimum Significant Difference: 62951.16
Means with the same letter are not significantly different.
Groups, Treatments and means
a 4 1464000
b 3 972000
c 1 812300
c 2 792400
d 0 496600
집을 보러온 횟수가 1번인 경우와 2번인 경우의 평균은 유의미한 차이가 발견되지 않아, 비슷
한 그룹이라고 봐도 무방하다. 집을 보러온 횟수가 많을수록 집의 평균값이 높아지는 경향이
있다.
iv. grade : 집에 대한 전반적인 평가척도
- 분석방법 : 상관관계 분석
> cor.test(kc_house$grade, kc_house$price)
Pearson's product-moment correlation
data: kc_house$grade and kc_house$price
t = 131.76, df = 21611, p-value < 2.2e-16
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
0.6599749 0.6747621
sample estimates:
cor
0.6674343
p-value < 2.2e-16 이므로 상관관계 분석에 대한 결과가 유의미하다. 즉, grade변수와 price 변
수 사이에 상관계수는 0.667 이며, 비교적 강한 양의 상관관계가 있다고 볼 수 있다.
plot(kc_house$grade, kc_house$price, ylab = "Price", xlab = "Grade")
v. X1 ~ X12 : price가 비슷한 zipcode 별 group화
# zipcode 별 price 의평균을 group 화
kc_house_DT <- as.data.table(kc_house)
zipcode_price_group <- kc_house_DT[ , list(n = .N,
Mean = mean(price)),
by = list(zipcode,
school_el, school_mi,
school_hi, school_to)]
head(zipcode_price_group)
zipcode_price_group[sort(zipcode_price_group$Mean, decreasing =
TRUE),c("zipcode","Mena")]
zipcode_price_group_DT <- as.data.table(zipcode_price_group)
zipcode_price_group_DT <- zipcode_price_group_DT[order(Mean, decreasing =
TRUE) , ]
summary(zipcode_price_group_DT)
# Mean
# Min. : 234284
# 1st Qu.: 354126
# Median : 491952
# Mean : 560774
# 3rd Qu.: 645438
# Max. : 2160607
zipcode_group_1 <- zipcode_price_group_DT[1, "zipcode"]
zipcode_group_2 <- zipcode_price_group_DT[2, "zipcode"]
zipcode_group_3 <- zipcode_price_group_DT[3, "zipcode"]
zipcode_group_4 <- zipcode_price_group_DT[4, "zipcode"]
zipcode_group_5 <- zipcode_price_group_DT[5, "zipcode"]
zipcode_group_6 <- zipcode_price_group_DT[6:11, "zipcode"]
zipcode_group_7 <- zipcode_price_group_DT[12:13, "zipcode"]
zipcode_group_8 <- zipcode_price_group_DT[14:25, "zipcode"]
zipcode_group_9 <- zipcode_price_group_DT[26:34, "zipcode"]
zipcode_group_10 <- zipcode_price_group_DT[35:48, "zipcode"]
zipcode_group_11 <- zipcode_price_group_DT[49:61, "zipcode"]
zipcode_group_12 <- zipcode_price_group_DT[62:70, "zipcode"]
dummies <- data.frame(matrix(nrow = nrow(kc_house), ncol =12))
dummies[,1] <- ifelse(kc_house$zipcode == zipcode_group_1, 1, 0)
dummies[,2] <- ifelse(kc_house$zipcode == zipcode_group_2, 1, 0)
dummies[,3] <- ifelse(kc_house$zipcode == zipcode_group_3, 1, 0)
dummies[,4] <- ifelse(kc_house$zipcode == zipcode_group_4, 1, 0)
dummies[,5] <- ifelse(kc_house$zipcode == zipcode_group_5, 1, 0)
dummies[,6] <- ifelse(kc_house$zipcode == zipcode_group_6, 1, 0)
dummies[,7] <- ifelse(kc_house$zipcode == zipcode_group_7, 1, 0)
dummies[,8] <- ifelse(kc_house$zipcode == zipcode_group_8, 1, 0)
dummies[,9] <- ifelse(kc_house$zipcode == zipcode_group_9, 1, 0)
dummies[,10] <- ifelse(kc_house$zipcode == zipcode_group_10, 1, 0)
dummies[,11] <- ifelse(kc_house$zipcode == zipcode_group_11, 1, 0)
dummies[,12] <- ifelse(kc_house$zipcode == zipcode_group_12, 1, 0)
for(i in1:12){
dummies[,i] <- ifelse(kc_house$cluster == zipcode_group_i, 1, 0)
}
kc_house_data <- cbind(kc_house, dummies)
결과
> head(zipcode_price_group)
zipcode school_el school_mi school_hi school_to n Mean
1: 98001 16 4 6 26 362 280804.7
2: 98002 7 4 3 14 199 234284.0
3: 98003 10 6 5 21 280 294111.3
4: 98004 5 3 4 12 317 1355927.1
5: 98005 5 3 5 13 168 810164.9
6: 98006 9 3 2 14 498 859684.8
(3) 채택하지 못한 독립변수
- house_age : 주택이 오래된 정도 (2017 – yr_built)
- renovated_TF : renovate의 여부
- school_to : zipcode group 별 학교수
- season_price : 집이 팔린 계절별(봄/여름/가을/겨울)
i. house_age : 주택이 오래된 정도 (2017 – yr_built)
- 분석방법 : 상관관계 분석
summary(kc_house$yr_built)
# Min. 1st Qu. Median Mean 3rd Qu. Max.
# 1900 1951 1975 1971 1997 2015
house_age =2017- kc_house$yr_built
summary(house_age)
# Min. 1st Qu. Median Mean 3rd Qu. Max.
# 2.00 20.00 42.00 45.99 66.00 117.00
cor(house_age, kc_house$price) -0.054
cor.test(house_age, kc_house$price)
plot(house_age, kc_house$price)
결과
Pearson's product-moment correlation
data: house_age and kc_house$price
t = -7.9517, df = 21611, p-value = 1.93e-15
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
-0.06729506 -0.04070886
sample estimates:
cor
-0.05401153
p-value가 0.000값이므로 유의수준 a=0.05에서 상관계수의 값은 유의미하다. 따라서 집이 지어
진 연도와 price와 상관관계가 거의 없다고 볼 수 있다.
ii. renovated_TF : renovate의 여부
- 분석방법 : 양측 가설검정 (t-test)
# renovate 된 group 의 집값이 renovate 안된 group 의 집값보다 높다
renovate_house <- kc_house[kc_house$yr_renovated !=0, "price"] # renovate 된
집들의가격
not_renovate_house <- kc_house[kc_house$yr_renovated ==0, "price"] # renovate
안된 집들의가격
t.test(renovate_house[[1]], not_renovate_house[[1]])
# p-value < 2.2e-16 이 므로 두 그룹의 평균은 같 지 않다. (H0 기 각)
# mean of x mean of y
# 760379.0 530360.8
Welch Two Sample t-test
결과 >
data: renovate_house[[1]] and not_renovate_house[[1]]
t = 11.36, df = 939.86, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
190280.9 269755.5
sample estimates:
mean of x mean of y
760379.0 530360.8
p-value값이 0.000이므로 t.test 결과, renovate된 집과 renovate가 되지 않은 집 사이의 평균
값에는 차이가 나타났다.
하지만 회귀검정 과정에서 이 변수를 제외하였을 때의 R-square값이 이 변수를 추가하였을 때
의 R-square값보다 높았기 때문에 회귀모형 변수로 채택하지 않았다.
iii. school_to : zipcode group 별 학교수
kc_house <- readxl::read_excel(path = "kc_house_data.xlsx",
sheet = 1,
col_names = TRUE)
zipcode_school <- readxl::read_excel(path = "zipcode_school.xlsx",
sheet = 1,
col_names = TRUE)
str(zipcode_school)
head(zipcode_school)
kc_house_DT <- as.data.table(kc_house)
# 원데이터 kc_house 와 zipcode_school 데이터를 join 해서 kc_house 에 넣어줌
kc_house <- merge(kc_house, zipcode_school, by = "zipcode", all = TRUE)
View(kc_house)
# 학교수 내림차순으로 zipcode 정렬
x <- kc_house[order(kc_house$school_to, decreasing = TRUE) ,
c("zipcode","school_to")]
unique(x) # 중복값 제거
# price 내림차순으로 zipcode 정렬
kc_house[order(kc_house$price, decreasing = TRUE) , c("price","zipcode")]
cor(zipcode_price_group[,2][[1]], zipcode_price_group[,7][[1]]) # el - price #
-0.2
cor(zipcode_price_group[,3][[1]], zipcode_price_group[,7][[1]]) # mi - price #
-0.2
cor(zipcode_price_group[,4][[1]], zipcode_price_group[,7][[1]]) # hi - price #
-0.3
cor(zipcode_price_group[,5][[1]], zipcode_price_group[,7][[1]]) # to - price #
-0.3
cor.test(zipcode_price_group[,2][[1]], zipcode_price_group[,7][[1]]) # el -
price # -0.2
cor.test(zipcode_price_group[,3][[1]], zipcode_price_group[,7][[1]]) # mi -
price # -0.2
cor.test(zipcode_price_group[,4][[1]], zipcode_price_group[,7][[1]]) # hi -
price # -0.3
cor.test(zipcode_price_group[,5][[1]], zipcode_price_group[,7][[1]]) # to -
price # -0.3
학교 수가 많을수록 집값이 다소 하락하는 경향을 보인다. 하지만 상관관계가 0.2~0.3 으로
낮게 나왔기 때문에 초등학교, 중학교, 고등학교, 전체 학교의 숫자는 price 에 큰 영향을
미치지 않는다고 볼 수 있다.
iv. season_price : 집이 팔린 계절별(봄/여름/가을/겨울)
- 분석방법 : 여러집단 사이의 차이검정 (ANOVA, scheffe, test)
head(date_numeric)
# 새로운변수생성
kc_house$date_numeric = date_numeric
# 집이팔린날짜가
# 봄(3,4,5 월) / 여름(6,7,8 월) / 가을(9,10,11 월) / 겨울(12,1,2 월) 별로 price 그룹화
spr_price <- kc_house[grep("....03..|....04..|....05..", date_numeric), "price"]
sum_price <- kc_house[grep("....06..|....07..|....08..", date_numeric), "price"]
fal_price <- kc_house[grep("....09..|....10..|....11..", date_numeric), "price"]
win_price <- kc_house[grep("....12..|....01..|....02..", date_numeric), "price"]
mean(spr_price[[1]])
mean(sum_price[[1]])
mean(fal_price[[1]])
mean(win_price[[1]])
length(spr_price[[1]]) + length(sum_price[[1]]) + length(fal_price[[1]]) +
length(win_price[[1]])
# 21613 "전체를다가져왔는지확인" OK
seson_price <- c(spr_price[[1]], sum_price[[1]], fal_price[[1]], win_price[[1]])
group <- c(rep(1, length(spr_price[[1]])),
rep(2, length(sum_price[[1]])),
rep(3, length(fal_price[[1]])),
rep(4, length(win_price[[1]])))
length(group) # 21613
cbind(seson_price, group)
boxplot(seson_price ~ group)
describe.by(seson_price, group) # 그룹별기술통계량계산
ANO_R<-aov(seson_price ~ group)
anova(ANO_R)
scheffe.test(ANO_R, "group", alpha =0.05, console = TRUE)
LSD.test(ANO_R, "group", alpha =0.05, console = TRUE)
duncan.test(ANO_R, "group", alpha =0.05, console = TRUE)
t.test(fal_price[[1]], win_price[[1]])
결과
> head( cbind(seson_price, group) )
seson_price group
[1,] 538000 1
[2,] 180000 1
[3,] 310000 1
[4,] 530000 1
[5,] 650000 1
[6,] 485000 1
> tail( cbind(seson_price, group) )
seson_price group
[21608,] 330000 4
[21609,] 230000 4
[21610,] 645000 4
[21611,] 414500 4
[21612,] 347500 4
[21613,] 350000 4
> describe.by(seson_price, group) # 그룹별 기술통계량 계산
Descriptive statistics by group
group: 1
vars n mean sd median trimmed mad min max range skew
kurtosis se
X1 1 6520 543036.7 363293.6 455700 486463.7 228765.2 78000 7062500 6984500 4
34.18 4499.19
------------------------------------------------------------------------------
group: 2
vars n mean sd median trimmed mad min max range skew
kurtosis se
X1 1 6331 543183.9 377206.2 450000 480799 222390 75000 5570000 5495000 3.72
24.97 4740.7
------------------------------------------------------------------------------
group: 3
vars n mean sd median trimmed mad min max range skew kurtosis
se
X1 1 5063 536213 365608 450000 480103.4 222390 82500 7700000 7617500 5.02 60.6
5138.21
------------------------------------------------------------------------------
group: 4
vars n mean sd median trimmed mad min max range skew
kurtosis se
X1 1 3699 534896.4 358372.5 447500 477146.5 218683.5 83000 3800000 3717000 3.22
16.54 5892.4
> anova(ANO_R)
Analysis of Variance Table
Response: seson_price
Df Sum Sq Mean Sq F value Pr(>F)
group 1 2.4117e+11 2.4117e+11 1.7894 0.181
Residuals 21611 2.9127e+15 1.3478e+11
> scheffe.test(ANO_R, "group", alpha = 0.05, console = TRUE)
Study: ANO_R ~ "group"
Scheffe Test for seson_price
Mean Square Error : 134777455496
group, means
seson_price std r Min Max
1 543036.7 363293.6 6520 78000 7062500
2 543183.9 377206.2 6331 75000 5570000
3 536213.0 365608.0 5063 82500 7700000
4 534896.4 358372.4 3699 83000 3800000
Alpha: 0.05 ; DF Error: 21611
Critical Value of F: 2.60532
Harmonic Mean of Cell Sizes 5133.59
Minimum Significant Difference: 20258.36
Means with the same letter are not significantly different.
Groups, Treatments and means
a 2 543200
a 1 543000
a 3 536200
a 4 534900
계절(봄/여름/가을/겨울)에 따른 그룹의 평균에서 유의미한 차이가 나타나지 않았다. 따라서, 계
절에 따른 price에는 차이가 없다고 볼 수 있다.
3. 자료 분석
A. 분석 방법
i. 회귀 모형
ii. 회귀모형에 들어갈 데이터 전처리
# date 변수를 numeric 으로 바꾸기
date_numeric <- substr(kc_house_data$date, 1, 8) # 20141124 형태로 연도날짜
문자부분만 추출
date_numeric <- as.numeric(date_numeric)
is.numeric(date_numeric) # TRUE
kc_house_data$date <- date_numeric # 기존의 date 를 새로운 numeric date 로 대체
집값 ~ 크기를 나타내는 변수(bathsrooms, bedrooms, floors, sqft_living)
+ 해안가 여부(waterfront _ T/F)
+ 집을 보러온 횟수(view _ 0/1/2/3/4)
+ 집 평가척도(grade)
+ zipcode group(총 12개)에 대한 더미변수
house_lm = lm(kc_house_data$price ~ room_newnum + waterfront + view +
grade + X1 + X2 + X3 + X4 + X5 + X6 + X7 + X8 + X9 + X10 + X11 + X12,
data = kc_house_data)
# 크기를 나타내는 변수들을 묶어주기
kc_house_data$room_newnum = kc_house$bedrooms*0.308 + kc_house$bathrooms*0.525 +
kc_house$floors*0.257 + kc_house$sqft_living*0.702
cor(kc_house$room_newnum, kc_house$price) # 0.702
View(kc_house_data)
iii. zipcode 별로 price에 대한 정규성 검정
# by(A, B, shapiro.test) # B에 있는 모든 집단의 A값에 대해 정규성 검정을 한다
A <- by(kc_house$price, kc_house$zipcode, shapiro.test)
## p-value > 0.05인 zipcode group
###
# kc_house$zipcode: 98002
#
# Shapiro-Wilk normality test
#
# data: dd[x, ]
# W = 0.99639, p-value = 0.9243
###
# kc_house$zipcode: 98108
#
# Shapiro-Wilk normality test
#
# data: dd[x, ]
# W = 0.99176, p-value = 0.3707
###
B. 분석 결과
i. Stepwise에 의한 영향력이 있는 변수의 선별
.
Call:
lm(formula = kc_house_data$price ~ room_newnum + waterfront +
view + grade + X1 + X2 + X3 + X4 + X5 + X6 + X7 + X8 + X9 +
X10 + X11 + X12, data = kc_house_data)
Residuals:
Min 1Q Median 3Q Max
-1168280 -111183 -11201 93153 4695648
(2) Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -428984.61 11000.94 -38.995 < 2e-16 ***
room_newnum 219.91 3.37 65.248 < 2e-16 ***
waterfront 596633.57 17493.97 34.105 < 2e-16 ***
view 73086.65 2054.59 35.572 < 2e-16 ***
grade 78201.44 1841.75 42.460 < 2e-16 ***
X1 1210393.45 28972.94 41.777 < 2e-16 ***
X2 631557.38 11627.49 54.316 < 2e-16 ***
X3 359493.57 12361.11 29.083 < 2e-16 ***
X4 467049.42 12554.92 37.200 < 2e-16 ***
X5 335753.53 19958.60 16.822 < 2e-16 ***
X6 187139.64 12507.13 14.963 < 2e-16 ***
X7 118286.47 11234.48 10.529 < 2e-16 ***
X8 64278.26 11002.59 5.842 5.23e-09 ***
X9 85789.09 10854.34 7.904 2.84e-15 ***
X10 -32043.68 12036.78 -2.662 0.00777 **
X11 -103019.44 10948.51 -9.409 < 2e-16 ***
X12 -152845.27 13182.95 -11.594 < 2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 203600 on 21596 degrees of freedom
Multiple R-squared: 0.6926, Adjusted R-squared: 0.6924
(1) F-statistic: 3041 on 16 and 21596 DF, p-value: < 2.2e-16
ii. 회귀분석 결과 분석
1단계 : 회귀모형은 통계적으로 타당한가?
귀무가설 : 회귀모형은 타당하지 않다.
대립가설 : 회귀모형은 타당하다.
(1) F-statistic: 3041 on 16 and 21596 DF, p-value: < 2.2e-16
(1)의 출력 결과물을 보면 p-value 값이 0.000 이므로 귀무가설을 기각한다.
1단계의 결론 : 대립가설, 회귀모형은 타당하다
2단계 : 독립변수 각각은 종속변수에게 영향을 주는가?
귀무가설 : 독립변수는 종속변수에게 영향을 주지 않는다.
대립가설 : 독립변수는 종속변수에게 영향을 준다.
(2) Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -428984.61 11000.94 -38.995 < 2e-16 ***
room_newnum 219.91 3.37 65.248 < 2e-16 ***
waterfront 596633.57 17493.97 34.105 < 2e-16 ***
view 73086.65 2054.59 35.572 < 2e-16 ***
grade 78201.44 1841.75 42.460 < 2e-16 ***
X1 1210393.45 28972.94 41.777 < 2e-16 ***
X2 631557.38 11627.49 54.316 < 2e-16 ***
X3 359493.57 12361.11 29.083 < 2e-16 ***
X4 467049.42 12554.92 37.200 < 2e-16 ***
X5 335753.53 19958.60 16.822 < 2e-16 ***
X6 187139.64 12507.13 14.963 < 2e-16 ***
X7 118286.47 11234.48 10.529 < 2e-16 ***
X8 64278.26 11002.59 5.842 5.23e-09 ***
X9 85789.09 10854.34 7.904 2.84e-15 ***
X10 -32043.68 12036.78 -2.662 0.00777 **
X11 -103019.44 10948.51 -9.409 < 2e-16 ***
X12 -152845.27 13182.95 -11.594 < 2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(2)의 출력 결과물을 보면 유의확률(Pr(>|t|))이 0.000 에 가까우므로 귀무가설을 기각하여,
유의수준인 0.05 구간에서 독립변수는 종속변수에게 영향을 준다는 대립가설을 채택한다.
2단계의 결론 : 독립변수는 종속변수에게 영향을 준다.
변수선택 : 단계 선택법(Stepwise Selection)방법 선택
step(회귀분석결과물, direction = c("forward", "backward", "both"))
model.stepwise = step(house_lm, direction = "both")
summary(model.stepwise)
3단계 : 변수선택 (결론출력)
독립변수의회귀계수(coefficient of Regression) : 0.6926
4단계 : 회귀모형의설명력 = 독립변수의설명
Multiple R-squared : 0.6926
0.6926 * 100 = 69.2%
설명계수인 R-squared 를 출력한 결과가 price 의 다름을 약 69.2%를 설명한다.
단, 고려해야할 점이 있다. 만약, 최종회귀모형에 독립변수가 2개이상 포함이 되면
첫째, 회귀계수의 해석을 확인해야 한다. 독립변수1은 나머지 독립변수들이 고정되어 있을
때에(통제) 1의기본단위가 1 증가하면 종속변수는 약 얼마 증가/감소하는지 고려해야 한다.
둘째, 다중공선성(Multicollinearity)을 확인해야 한다. 독립변수들간의 선형의 관계는 없어야
한다.
예를 들어, VIF(Varaince Inflation Factor) : 10 이상이면 다중공선성이 존재한다고 판단하며,
독립변수들 간에 선형의 관계가 존재함을 알 수 있다. 만약 이러한 결과가 나온다면
독립변수들 중에 빼는 것을 검토한다.
다중공선성(Multicollinearity)을 확인
library(car)
car::vif(model.stepwise)
> car::vif(model.stepwise)
room_newnum waterfront view grade X1 X2 X3
X4
2.465253 1.194046 1.292139 2.442943 1.009935 1.018493 1.025663
1.009917
X5 X6 X7 X8 X9 X10 X11
X12
1.003873 1.005920 1.012795 1.005337 1.003162 1.003162 1.003869
1.002985
모든 변수들에 대한 VIF 값이 10 이하이므로 독립변수 간의 다중공선성은 존재하지 않는다.
회귀모형의 설명력 : Adjusted R-Square
Adjusted R-squared: 0.6924
독립변수들의 영향력 크기 비교
library(lm.beta)
lm.beta::lm.beta(attitude.lm)
> lm.beta::lm.beta(model.stepwise)
Call:
lm(formula = kc_house_data$price ~ room_newnum + waterfront +
view + grade + X1 + X2 + X3 + X4 + X5 + X6 + X7 + X8 + X9 +
X10 + X11 + X12, data = kc_house_data)
Standardized Coefficients::
(Intercept) room_newnum waterfront view grade X1 X2
X3
0.00000000 0.38651375 0.14060267 0.15255635 0.25038342 0.15839614 0.20680922
0.11112192
X4 X5 X6 X7 X8 X9 X10
X11
0.14104423 0.06359071 0.05661791 0.03997667 0.02209983 0.02986607 -0.01005961 -
0.03556859
X12
-0.04380771
4. 예측
kc_house_final <-
kc_house_data[,c("room_newnum","waterfront","view","grade","X1","X2","X3","X4","X5","X6","X7","X
8","X9","X10","X11","X12")]
# predict(회귀분석결과, newdata = data.frame(complaints = ))
predict(model.stepwise, newdata = data.frame(kc_house_final[1:5,]), interval = "predict")
View(kc_house_data)
1) 예측값
> predict(model.stepwise, newdata = data.frame(kc_house_final[1:6,]), interval = "predict") # 점추
정?
fit lwr upr
1 219839.6 -186103.7 625782.8
2 285515.2 -120405.3 691435.7
3 268629.0 -137296.2 674554.2
4 493984.5 87995.8 899973.1
2) 실제값
zipcode id date price
1 98001 302000375 20140814 169100
2 98001 6181400920 20150430 286651
3 98001 2005950050 20140527 260000
4 98001 8956200070 20140905 447500
5. 최종 결론
표준화된 회귀계수에 의해서, price에 가장 영향을 미치는 변수는 집의 크기와 관련된 변
수들(화장실수, 침실수, 층수, 평수)와 grade라는 것을 알 수 있다.
변수명 변수 설명 표준화된 상관계수
room_newnum
집의 크기와 관련된 변수들을 한가지
의 변수로 모델링 한 변수
(화장실수, 침실수, 층수, 평수)
0.387
grade
Kingcounty grading system에 의한
집에 대한 평가척도
0.250
6. 미비점 및 개선방향
- 집 크기에 영향을 받는 변수들(bathrooms, bedrooms, floors, sqft_living)을 하나의 데이터로 모델
링하는 과정에서 가중치 선정방법이 미흡했던 것 같다. 이러한 변수들이 실제로 집값에 영향을
미치는 정도에 따라서 가중치를 선정하려고 했으나, 논문자료에서 이에 대한 정보를 찾지 못했다.
그래서 차선책으로 각 변수들에 대한 상관계수를 곱해서 더해주는 방식을 선택했다. 이 방법은
현재 주어진 자료에서만 유효하므로, 다음에 기회가 된다면 전체 집값에 유의미한 모델링을 해보
고 싶다.
- 집 별로 평수의 차이가 있는데 단위 평수당 가격을 고려하지 않고 단순히 zipcode별 집값에 대
한 분석을 진행하였다. 따라서 평수당 가격보다는 지역의 요인에 중점을 두었으며, 누락되는 부분
이 충분히 있었을 것이라고 판단된다.
- 주어진 데이터 이외에 새로운 변수들을 만들어내려고 노력하였는데, 많은 변수들(School,
Seasonality 등)이 price에 유의미한 영향을 주지 않아 채택하지 못했다. 변수를 세부그룹으로 나
누거나 이상치를 제거하는 등 데이터 전처리 과정을 거친다면 채택하지 못한 변수들과 price 사
이에 유의미한 상관관계를 찾을 수 있을 것이라고 생각한다. 전체적으로 데이터를 전처리 하는
과정이 부족하였던 점이 아쉬웠다.
- 관련 논문을 찾아보다가 집값이 비싸질수록 화장실수, 평수 등과 같은 물리적인 특성보다 해안
가, 학교 수, 백화점과의 거리 등의 입지적인 특성에 더욱 영향을 많이 받는다는 연구결과를 알게
되었다. 집값이 비싼 집들과 비싸지 않은 집들을 각각 분석해서 여러 가지의 회귀모형을 선정해
보는 것도 좋은 프로젝트가 되었을 것 같다.
종속변수에 대한 시계열 자료
house_price_ts <- ts(kc_house$price, start = c(2014, 182), end = c(2015, 182),
frequency = 365)
plot(house_price_ts, ylab = "Kingcounty House Price", xlab = "Year.Month",
xlim = c(2014.5, 2015.5))
par(mfrow = c(1,2))
acf(house_price_ts) # 파란색 점선 밑에 그래프가 있어야 유의한것이다!
pacf(house_price_ts)
ndiffs(house_price_ts) # 0
# 아주 강력한 function! auto.arima
houseBest <- auto.arima(x = house_price_ts)
houseBest
par(mfrow = c(1,2))
library(scales)
forecast(houseBest, h = 5) -> houseforecast # 80%, 95% 신뢰구간이 같이 나옴
plot(houseforecast)
House pricing prediction in R(Regression Project)
House pricing prediction in R(Regression Project)

More Related Content

Similar to House pricing prediction in R(Regression Project)

R 스터디 첫번째
R 스터디 첫번째R 스터디 첫번째
R 스터디 첫번째Jaeseok Park
 
Sicp 2.2 계층 구조 데이터와 닫힘 성질
Sicp 2.2 계층 구조 데이터와 닫힘 성질Sicp 2.2 계층 구조 데이터와 닫힘 성질
Sicp 2.2 계층 구조 데이터와 닫힘 성질aceigy6322
 
해커에게 전해들은 머신러닝 #1
해커에게 전해들은 머신러닝 #1해커에게 전해들은 머신러닝 #1
해커에게 전해들은 머신러닝 #1Haesun Park
 
세그먼트 트리 느리게 업데이트하기 - Sogang ICPC Team, 2020 Winter
세그먼트 트리 느리게 업데이트하기 - Sogang ICPC Team, 2020 Winter세그먼트 트리 느리게 업데이트하기 - Sogang ICPC Team, 2020 Winter
세그먼트 트리 느리게 업데이트하기 - Sogang ICPC Team, 2020 WinterSuhyun Park
 

Similar to House pricing prediction in R(Regression Project) (7)

R_datamining
R_dataminingR_datamining
R_datamining
 
Rdatamining
Rdatamining Rdatamining
Rdatamining
 
R 스터디 첫번째
R 스터디 첫번째R 스터디 첫번째
R 스터디 첫번째
 
Sicp 2.2 계층 구조 데이터와 닫힘 성질
Sicp 2.2 계층 구조 데이터와 닫힘 성질Sicp 2.2 계층 구조 데이터와 닫힘 성질
Sicp 2.2 계층 구조 데이터와 닫힘 성질
 
해커에게 전해들은 머신러닝 #1
해커에게 전해들은 머신러닝 #1해커에게 전해들은 머신러닝 #1
해커에게 전해들은 머신러닝 #1
 
세그먼트 트리 느리게 업데이트하기 - Sogang ICPC Team, 2020 Winter
세그먼트 트리 느리게 업데이트하기 - Sogang ICPC Team, 2020 Winter세그먼트 트리 느리게 업데이트하기 - Sogang ICPC Team, 2020 Winter
세그먼트 트리 느리게 업데이트하기 - Sogang ICPC Team, 2020 Winter
 
R 시작해보기
R 시작해보기R 시작해보기
R 시작해보기
 

More from Adonis Han

LDA : latent Dirichlet Allocation (Fairies NLP Series) - Korean Ver.
LDA : latent Dirichlet Allocation (Fairies NLP Series) - Korean Ver.LDA : latent Dirichlet Allocation (Fairies NLP Series) - Korean Ver.
LDA : latent Dirichlet Allocation (Fairies NLP Series) - Korean Ver.Adonis Han
 
(Kor ver.)NLP embedding(word2vec) tutorial & implementation(Tensorflow)
(Kor ver.)NLP embedding(word2vec) tutorial & implementation(Tensorflow)(Kor ver.)NLP embedding(word2vec) tutorial & implementation(Tensorflow)
(Kor ver.)NLP embedding(word2vec) tutorial & implementation(Tensorflow)Adonis Han
 
how to understand and implement the "WAVENET"
how to understand and implement the "WAVENET"how to understand and implement the "WAVENET"
how to understand and implement the "WAVENET"Adonis Han
 
[kor ver.]패턴인식을 위한 인공신경망 Caps-net 구현
[kor ver.]패턴인식을 위한 인공신경망 Caps-net 구현 [kor ver.]패턴인식을 위한 인공신경망 Caps-net 구현
[kor ver.]패턴인식을 위한 인공신경망 Caps-net 구현 Adonis Han
 
[kor ver.]Global GO (Bigdata-Cloud computing project - mainly in MVC model2)
[kor ver.]Global GO (Bigdata-Cloud computing project - mainly in MVC model2)[kor ver.]Global GO (Bigdata-Cloud computing project - mainly in MVC model2)
[kor ver.]Global GO (Bigdata-Cloud computing project - mainly in MVC model2)Adonis Han
 
Facial detection by CNN(Convolution Neural Network) in Kaggle
Facial detection by CNN(Convolution Neural Network) in KaggleFacial detection by CNN(Convolution Neural Network) in Kaggle
Facial detection by CNN(Convolution Neural Network) in KaggleAdonis Han
 

More from Adonis Han (6)

LDA : latent Dirichlet Allocation (Fairies NLP Series) - Korean Ver.
LDA : latent Dirichlet Allocation (Fairies NLP Series) - Korean Ver.LDA : latent Dirichlet Allocation (Fairies NLP Series) - Korean Ver.
LDA : latent Dirichlet Allocation (Fairies NLP Series) - Korean Ver.
 
(Kor ver.)NLP embedding(word2vec) tutorial & implementation(Tensorflow)
(Kor ver.)NLP embedding(word2vec) tutorial & implementation(Tensorflow)(Kor ver.)NLP embedding(word2vec) tutorial & implementation(Tensorflow)
(Kor ver.)NLP embedding(word2vec) tutorial & implementation(Tensorflow)
 
how to understand and implement the "WAVENET"
how to understand and implement the "WAVENET"how to understand and implement the "WAVENET"
how to understand and implement the "WAVENET"
 
[kor ver.]패턴인식을 위한 인공신경망 Caps-net 구현
[kor ver.]패턴인식을 위한 인공신경망 Caps-net 구현 [kor ver.]패턴인식을 위한 인공신경망 Caps-net 구현
[kor ver.]패턴인식을 위한 인공신경망 Caps-net 구현
 
[kor ver.]Global GO (Bigdata-Cloud computing project - mainly in MVC model2)
[kor ver.]Global GO (Bigdata-Cloud computing project - mainly in MVC model2)[kor ver.]Global GO (Bigdata-Cloud computing project - mainly in MVC model2)
[kor ver.]Global GO (Bigdata-Cloud computing project - mainly in MVC model2)
 
Facial detection by CNN(Convolution Neural Network) in Kaggle
Facial detection by CNN(Convolution Neural Network) in KaggleFacial detection by CNN(Convolution Neural Network) in Kaggle
Facial detection by CNN(Convolution Neural Network) in Kaggle
 

House pricing prediction in R(Regression Project)

  • 1. 다중회귀분석 Multi-Regression Analyse “미국의 집값에 영향을 미치는 요인들에 대한 분석” House Pricing 1. 독립변수에 대한 설명 (1) 자료에 대한 요약 i. 모든 변수들 간의 상관관계 # date 변수를 numeric 으로 바꾸기 date_numeric <- substr(kc_house$date, 1, 8) # 20141124 형태로 연도날짜 문자부분만 추출 is.numeric(date_numeric) # FALSE date_numeric <- as.numeric(date_numeric) is.numeric(date_numeric) # TRUE kc_house$date <- date_numeric # 기존의 date 를 새로운 numeric date 로 대체 View(kc_house) house_cor <- cor(kc_house) # 모든 변수들의 서로서로 간의 상관관계를 계산 # library(psych) house_cortest <- psych::corr.test(kc_house) DT::datatable(house_cortest) View(house_cortest) library(Hmisc) Hmisc::rcorr(as.matrix(attitude)) round(house_cor, 2) # 소숫점 둘째자리까지 round pairs(house_cor, pch = 19, bg = c("red", "green", "blue")) # 행렬모양 산점도 corrplot(house_cor) # 상관원계수가 클수록 크기가 크고 색깔이 진하다 # 양수면 파란색, 음수면 붉은색 corrplot(house_cor, method = "number") # 수와 색깔로 표현 col <- colorRampPalette(c("#BB4444", "#EE9988", "#FFFFFF", "#77AADD", "#4477AA")) corrplot(house_cor, method = "color", # 색깔로 표현 col = col(200), # 색상 200 개 선정 type = "lower", # 왼쪽 아래 행렬만 표기 order = "hclust", # 유사한 상관계수끼리 군집화 addCoef.col = "black", # 상관계수 색깔 tl.col = "black", # 변수명 색깔 tl.srt = 45, # 변수명 45 도 기울임 diag = FALSE) # 대각행렬 제외
  • 2. i-1. 상관계수를 세 그룹으로 나누어 표현 Plot1. price, bedrooms, bathrooms, sqft_living and sqft lot
  • 3.
  • 4. Plot2. price, floors, waterfront, view, condition and grade
  • 5. Plot 3. price, yr built, lat and long < 결과 > # 상관관계가 높은 변수들 ( > 0.5) # sqft_lot15 - sqft_lot : 0.72 # 둘다 삭제 # bathrooms - floors : 0.50 # 변환(모델링) # bathrooms - yr_built : 0.51 # bathrooms 채택 # bathrooms - bedrooms : 0.52 # 변환(모델링) # price - bathrooms : 0.53 # sqft_living15 - bathrooms : 0.57 # bathrooms 채택 # sqft_living15 - price : 0.59 # grade - bathrooms : 0.66 # bathrooms 변환 # grade - price : 0.67 # grade - sqft_living15 : 0.71 # grade 채택 # sqft_living - bedrooms : 0.58 # 변환(모델링)
  • 6. # sqft_living - bathrooms : 0.75 # 변환(모델링) # sqft_living - price : 0.70 # sqft_living - sqft_living15 : 0.76 # sqft_living 채태 # sqft_living - grade : 0.76 # sqft_living 변환 # sqft_above - floors : 0.52 # floors 채택 # sqft_above - bathrooms : 0.69 # bathrooms 채택 # sqft_above - price : 0.61 # sqft_above - sqft_living15 : 0.73 # 둘다 삭제 # sqft_above - grade : 0.76 # grade 채택 # sqft_above - sqft_living : 0.88 # sqft_living 채택 # zipcode - long : -0.56 # zipcode 채택 채택변수 : bedrooms, bathrooms, sqft_living, floors, view, grade ii. price 상위 25% 집을 지도에 표시 house_map + ggplot2::geom_point(data = high_25_loc, aes(x = long, y = lat), colour="red")
  • 7. iii. zipcode 별로 집의 위치와 밀도를 지도에 표시 zipcode_1_10_loc <- kc_house[(kc_house$zipcode >=98001)&(kc_house$zipcode <=98010), c("long", "lat")] #집코드별로 그룹화 zipcode_11_20_loc <- kc_house[(kc_house$zipcode >=98011)&(kc_house$zipcode <=98020), c("long", "lat")] zipcode_21_30_loc <- kc_house[(kc_house$zipcode >=98021)&(kc_house$zipcode <=98030), c("long", "lat")] zipcode_31_40_loc <- kc_house[(kc_house$zipcode >=98031)&(kc_house$zipcode <=98040), c("long", "lat")] zipcode_41_50_loc <- kc_house[(kc_house$zipcode >=98041)&(kc_house$zipcode <=98050), c("long", "lat")] house_map <- get_googlemap(center = c(lon =-122.1, lat =47.5), zoom =10) %>% ggmap house_map + ggplot2::geom_point(data = zipcode_1_10_loc, aes(x = long, y = lat), colour="red") + ggplot2::geom_point(data = zipcode_11_20_loc, aes(x = long, y = lat), colour="orange") + ggplot2::geom_point(data = zipcode_21_30_loc, aes(x = long, y = lat), colour="yellow") +
  • 8. ggplot2::geom_point(data = zipcode_31_40_loc, aes(x = long, y = lat), colour="green") + ggplot2::geom_point(data = zipcode_41_50_loc, aes(x = long, y = lat), colour="blue") # zipcode group 이런식으로 집을 ggmap 과 ggplot2 패키지를 이용 그림에 표현해줌 zipcode__1_loc <- kc_house[kc_house$zipcode == grep("1$", kc_house$zipcode, value = TRUE), c("long", "lat")] zipcode__2_loc <- kc_house[kc_house$zipcode == grep("2$", kc_house$zipcode, value = TRUE), c("long", "lat")] zipcode__3_loc <- kc_house[kc_house$zipcode == grep("3$", kc_house$zipcode, value = TRUE), c("long", "lat")] house_map + ggplot2::geom_point(data = zipcode__1_loc, aes(x = long, y = lat), colour="red") + ggplot2::geom_point(data = zipcode__2_loc, aes(x = long, y = lat), colour="orange") + ggplot2::geom_point(data = zipcode__3_loc, aes(x = long, y = lat), colour="yellow")
  • 9. (2) 채택한 독립변수 - room_newnum : 집의 크기에 영향을 미치는 변수들(bathrooms, bedrooms, floors, sqft_living) 을 하나의 변수로 모델링 - waterfront : 해안가(waterfront) 여부 - view : 집을 보러온 횟수 - grade : 집에 대한 전반적인 평가척도 - X1 ~ X12 : price가 비슷한 zipcode 별 group화 i. room_newnum : 집의 크기에 영향을 미치는 변수들(bathrooms, bedrooms, floors, sqft_living)을 하나의 변수로 모델링 - 분석방법 : 상관분석 # bedrooms, bathrooms, floors 데이터모델링하기 cor(kc_house$bedrooms, kc_house$price) # 0.308 cor(kc_house$bathrooms, kc_house$price) # 0.525 cor(kc_house$floors, kc_house$price) # 0.257 cor(kc_house$sqft_living, kc_house$price) # 0.702 cor(kc_house$sqft_lot, kc_house$price) # 0.090 # 제외! kc_house_data$room_newnum = kc_house$bedrooms*0.308+ kc_house$bathrooms*0.525+ kc_house$floors*0.257+ kc_house$sqft_living*0.702 <데 이터 모델링 식> kc_house_data$room_newnum = kc_house$bedrooms*0.308 + kc_house$bathrooms*0.525 + kc_house$floors*0.257 + kc_house$sqft_living*0.702 cor(kc_house$room_newnum, kc_house$price) # 0.702 ii. waterfront : 해안가(waterfront) 여부 - 분석방법 : 양측 가설검정 (t-test) # 해안가(=1) group 의 위치 waterfront_T <- kc_house[kc_house$waterfront ==1, c("long", "lat")] # 해안가가 아닌(=0) group 의 위치 waterfront_F <- kc_house[kc_house$waterfront ==0, c("long", "lat")] house_map <- get_googlemap(center = c(lon =-122.1, lat =47.5), zoom =10) %>% ggmap house_map + ggplot2::geom_point(data = waterfront_T, aes(x = long, y = lat), colour="red") + ggplot2::geom_point(
  • 10. data = waterfront_F, aes(x = long, y = lat), colour="orange") # 해안가(=1) group 의 price waterfront_T_price <- kc_house[kc_house$waterfront ==1, "price"] # 해안가가 아닌(=0) group 의 price waterfront_F_price <- kc_house[kc_house$waterfront ==0, "price"] summary(waterfront_T_price[[1]]) summary(waterfront_F_price[[1]]) t.test(waterfront_T_price[[1]], waterfront_F_price[[1]]) boxplot(waterfront_T_price[[1]], waterfront_F_price[[1]]) 결과 Welch Two Sample t-test data: waterfront_T_price[[1]] and waterfront_F_price[[1]] t = 12.876, df = 162.23, p-value < 2.2e-16 alternative hypothesis: true difference in means is not equal to 0 95 percent confidence interval: 956963.3 1303661.6 sample estimates: mean of x mean of y 1661876.0 531563.6 귀무가설 : 두 그룹의 평균은 같다 대립가설 : 두 그룹의 평균은 같지 않다 p-value < 0.000 이므로, 유의수준 a=0.05에서 귀무가설을 기각한다. 즉, 해안가에 위치한 집들 의 평균 집값과 해안가에 위치하지 않은 집들의 평균 집값이 다르다고 볼 수 있다. iii. view : 집을 보러온 횟수 - 분석방법 : 여러 집단 간의 차이검정(ANOVA, scheffe.test) view0_price <- kc_house[kc_house$view ==0,"price"] length(view0_price[[1]]) # 19489 view1_price <- kc_house[kc_house$view ==1,"price"] length(view1_price[[1]]) # 332 view2_price <- kc_house[kc_house$view ==2,"price"] length(view2_price[[1]]) # 963 view3_price <- kc_house[kc_house$view ==3,"price"] length(view3_price[[1]]) # 510 view4_price <- kc_house[kc_house$view ==4,"price"] length(view4_price[[1]]) # 319
  • 11. mean(view0_price[[1]]) # 496564.2 mean(view1_price[[1]]) # 812280.8 mean(view2_price[[1]]) # 792400.9 mean(view3_price[[1]]) # 971965.3 mean(view4_price[[1]]) # 1463711 view_price <- c(view0_price[[1]], view1_price[[1]], view2_price[[1]], view3_price[[1]], view4_price[[1]]) length(view_price) # 21613 length(group) # 21613 group <- c(rep(0, 19489), rep(1, 332), rep(2, 963), rep(3, 510), rep(4, 319)) cbind(view_price, group) boxplot(view_price ~ group, ylab = "Price", xlab = "View") describe.by(view_price, group) # 그룹별기술통계량계산 # mad ANO_R <- aov(view_price ~ group) anova(ANO_R) library(agricolae) scheffe.test(ANO_R, "group", alpha =0.05, console = TRUE) LSD.test(ANO_R, "group", alpha =0.05, console = TRUE) duncan.test(ANO_R, "group", alpha =0.05, console = TRUE) 결과 > head( cbind(view_price, group) ) view_price group [1,] 221900 0 [2,] 538000 0 [3,] 180000 0 [4,] 604000 0 [5,] 510000 0 [6,] 1225000 0 > tail( cbind(view_price, group) ) view_price group [21608,] 580000 4 [21609,] 2300000 4 [21610,] 1149000 4 [21611,] 900000 4 [21612,] 2230000 4 [21613,] 3567000 4
  • 12. > describe.by(view_price, group) # 그룹별 기술통계량 계산 # mad Descriptive statistics by group group: 0 vars n mean sd median trimmed mad min max range skew kurtosis se X1 1 19489 496564.2 287133.3 432500 456422 203857.5 75000 5570000 5495000 3.11 21.58 2056.78 ------------------------------------------------------------------------------ group: 1 vars n mean sd median trimmed mad min max range skew kurtosis se X1 1 332 812280.8 510949.7 690944 722550.6 308714.4 217000 3650000 3433000 2.26 6.65 28042.01 ------------------------------------------------------------------------------ group: 2 vars n mean sd median trimmed mad min max range skew kurtosis se X1 1 963 792400.9 510105 675000 714267.2 318759 169317 7062500 6893183 3.57 27.65 16437.91
  • 13. ------------------------------------------------------------------------------ group: 3 vars n mean sd median trimmed mad min max range skew kurtosis se X1 1 510 971965.3 612692.2 802500 892245.3 450710.4 154000 7700000 7546000 3.38 28.12 27130.47 ------------------------------------------------------------------------------ group: 4 vars n mean sd median trimmed mad min max range skew kurtosis se X1 1 319 1463711 952209.6 1185000 1320949 667170 252000 6885000 6633000 1.84 4.87 53313.5 > scheffe.test(ANO_R, "group", alpha = 0.05, console = TRUE) Study: ANO_R ~ "group" Scheffe Test for view_price Mean Square Error : 113513294940 group, means view_price std r Min Max 0 496564.2 287133.3 19489 75000 5570000 1 812280.8 510949.7 332 217000 3650000 2 792400.9 510105.1 963 169317 7062500 3 971965.3 612692.2 510 154000 7700000 4 1463711.2 952209.6 319 252000 6885000 Alpha: 0.05 ; DF Error: 21611 Critical Value of F: 2.372343 Harmonic Mean of Cell Sizes 543.6342 Minimum Significant Difference: 62951.16 Means with the same letter are not significantly different.
  • 14. Groups, Treatments and means a 4 1464000 b 3 972000 c 1 812300 c 2 792400 d 0 496600 집을 보러온 횟수가 1번인 경우와 2번인 경우의 평균은 유의미한 차이가 발견되지 않아, 비슷 한 그룹이라고 봐도 무방하다. 집을 보러온 횟수가 많을수록 집의 평균값이 높아지는 경향이 있다. iv. grade : 집에 대한 전반적인 평가척도 - 분석방법 : 상관관계 분석 > cor.test(kc_house$grade, kc_house$price) Pearson's product-moment correlation data: kc_house$grade and kc_house$price t = 131.76, df = 21611, p-value < 2.2e-16 alternative hypothesis: true correlation is not equal to 0 95 percent confidence interval: 0.6599749 0.6747621 sample estimates: cor 0.6674343 p-value < 2.2e-16 이므로 상관관계 분석에 대한 결과가 유의미하다. 즉, grade변수와 price 변 수 사이에 상관계수는 0.667 이며, 비교적 강한 양의 상관관계가 있다고 볼 수 있다. plot(kc_house$grade, kc_house$price, ylab = "Price", xlab = "Grade")
  • 15. v. X1 ~ X12 : price가 비슷한 zipcode 별 group화 # zipcode 별 price 의평균을 group 화 kc_house_DT <- as.data.table(kc_house) zipcode_price_group <- kc_house_DT[ , list(n = .N, Mean = mean(price)), by = list(zipcode, school_el, school_mi, school_hi, school_to)] head(zipcode_price_group) zipcode_price_group[sort(zipcode_price_group$Mean, decreasing = TRUE),c("zipcode","Mena")] zipcode_price_group_DT <- as.data.table(zipcode_price_group) zipcode_price_group_DT <- zipcode_price_group_DT[order(Mean, decreasing = TRUE) , ] summary(zipcode_price_group_DT) # Mean # Min. : 234284 # 1st Qu.: 354126 # Median : 491952 # Mean : 560774 # 3rd Qu.: 645438 # Max. : 2160607 zipcode_group_1 <- zipcode_price_group_DT[1, "zipcode"] zipcode_group_2 <- zipcode_price_group_DT[2, "zipcode"] zipcode_group_3 <- zipcode_price_group_DT[3, "zipcode"]
  • 16. zipcode_group_4 <- zipcode_price_group_DT[4, "zipcode"] zipcode_group_5 <- zipcode_price_group_DT[5, "zipcode"] zipcode_group_6 <- zipcode_price_group_DT[6:11, "zipcode"] zipcode_group_7 <- zipcode_price_group_DT[12:13, "zipcode"] zipcode_group_8 <- zipcode_price_group_DT[14:25, "zipcode"] zipcode_group_9 <- zipcode_price_group_DT[26:34, "zipcode"] zipcode_group_10 <- zipcode_price_group_DT[35:48, "zipcode"] zipcode_group_11 <- zipcode_price_group_DT[49:61, "zipcode"] zipcode_group_12 <- zipcode_price_group_DT[62:70, "zipcode"] dummies <- data.frame(matrix(nrow = nrow(kc_house), ncol =12)) dummies[,1] <- ifelse(kc_house$zipcode == zipcode_group_1, 1, 0) dummies[,2] <- ifelse(kc_house$zipcode == zipcode_group_2, 1, 0) dummies[,3] <- ifelse(kc_house$zipcode == zipcode_group_3, 1, 0) dummies[,4] <- ifelse(kc_house$zipcode == zipcode_group_4, 1, 0) dummies[,5] <- ifelse(kc_house$zipcode == zipcode_group_5, 1, 0) dummies[,6] <- ifelse(kc_house$zipcode == zipcode_group_6, 1, 0) dummies[,7] <- ifelse(kc_house$zipcode == zipcode_group_7, 1, 0) dummies[,8] <- ifelse(kc_house$zipcode == zipcode_group_8, 1, 0) dummies[,9] <- ifelse(kc_house$zipcode == zipcode_group_9, 1, 0) dummies[,10] <- ifelse(kc_house$zipcode == zipcode_group_10, 1, 0) dummies[,11] <- ifelse(kc_house$zipcode == zipcode_group_11, 1, 0) dummies[,12] <- ifelse(kc_house$zipcode == zipcode_group_12, 1, 0) for(i in1:12){ dummies[,i] <- ifelse(kc_house$cluster == zipcode_group_i, 1, 0) } kc_house_data <- cbind(kc_house, dummies) 결과 > head(zipcode_price_group) zipcode school_el school_mi school_hi school_to n Mean 1: 98001 16 4 6 26 362 280804.7 2: 98002 7 4 3 14 199 234284.0 3: 98003 10 6 5 21 280 294111.3 4: 98004 5 3 4 12 317 1355927.1 5: 98005 5 3 5 13 168 810164.9 6: 98006 9 3 2 14 498 859684.8
  • 17. (3) 채택하지 못한 독립변수 - house_age : 주택이 오래된 정도 (2017 – yr_built) - renovated_TF : renovate의 여부 - school_to : zipcode group 별 학교수 - season_price : 집이 팔린 계절별(봄/여름/가을/겨울) i. house_age : 주택이 오래된 정도 (2017 – yr_built) - 분석방법 : 상관관계 분석 summary(kc_house$yr_built) # Min. 1st Qu. Median Mean 3rd Qu. Max.
  • 18. # 1900 1951 1975 1971 1997 2015 house_age =2017- kc_house$yr_built summary(house_age) # Min. 1st Qu. Median Mean 3rd Qu. Max. # 2.00 20.00 42.00 45.99 66.00 117.00 cor(house_age, kc_house$price) -0.054 cor.test(house_age, kc_house$price) plot(house_age, kc_house$price) 결과 Pearson's product-moment correlation data: house_age and kc_house$price t = -7.9517, df = 21611, p-value = 1.93e-15 alternative hypothesis: true correlation is not equal to 0 95 percent confidence interval: -0.06729506 -0.04070886 sample estimates: cor -0.05401153 p-value가 0.000값이므로 유의수준 a=0.05에서 상관계수의 값은 유의미하다. 따라서 집이 지어 진 연도와 price와 상관관계가 거의 없다고 볼 수 있다. ii. renovated_TF : renovate의 여부 - 분석방법 : 양측 가설검정 (t-test) # renovate 된 group 의 집값이 renovate 안된 group 의 집값보다 높다 renovate_house <- kc_house[kc_house$yr_renovated !=0, "price"] # renovate 된 집들의가격 not_renovate_house <- kc_house[kc_house$yr_renovated ==0, "price"] # renovate 안된 집들의가격 t.test(renovate_house[[1]], not_renovate_house[[1]]) # p-value < 2.2e-16 이 므로 두 그룹의 평균은 같 지 않다. (H0 기 각)
  • 19. # mean of x mean of y # 760379.0 530360.8 Welch Two Sample t-test 결과 > data: renovate_house[[1]] and not_renovate_house[[1]] t = 11.36, df = 939.86, p-value < 2.2e-16 alternative hypothesis: true difference in means is not equal to 0 95 percent confidence interval: 190280.9 269755.5 sample estimates: mean of x mean of y 760379.0 530360.8 p-value값이 0.000이므로 t.test 결과, renovate된 집과 renovate가 되지 않은 집 사이의 평균 값에는 차이가 나타났다. 하지만 회귀검정 과정에서 이 변수를 제외하였을 때의 R-square값이 이 변수를 추가하였을 때 의 R-square값보다 높았기 때문에 회귀모형 변수로 채택하지 않았다. iii. school_to : zipcode group 별 학교수 kc_house <- readxl::read_excel(path = "kc_house_data.xlsx", sheet = 1, col_names = TRUE) zipcode_school <- readxl::read_excel(path = "zipcode_school.xlsx", sheet = 1, col_names = TRUE) str(zipcode_school) head(zipcode_school) kc_house_DT <- as.data.table(kc_house) # 원데이터 kc_house 와 zipcode_school 데이터를 join 해서 kc_house 에 넣어줌 kc_house <- merge(kc_house, zipcode_school, by = "zipcode", all = TRUE) View(kc_house) # 학교수 내림차순으로 zipcode 정렬 x <- kc_house[order(kc_house$school_to, decreasing = TRUE) , c("zipcode","school_to")] unique(x) # 중복값 제거 # price 내림차순으로 zipcode 정렬 kc_house[order(kc_house$price, decreasing = TRUE) , c("price","zipcode")]
  • 20. cor(zipcode_price_group[,2][[1]], zipcode_price_group[,7][[1]]) # el - price # -0.2 cor(zipcode_price_group[,3][[1]], zipcode_price_group[,7][[1]]) # mi - price # -0.2 cor(zipcode_price_group[,4][[1]], zipcode_price_group[,7][[1]]) # hi - price # -0.3 cor(zipcode_price_group[,5][[1]], zipcode_price_group[,7][[1]]) # to - price # -0.3 cor.test(zipcode_price_group[,2][[1]], zipcode_price_group[,7][[1]]) # el - price # -0.2 cor.test(zipcode_price_group[,3][[1]], zipcode_price_group[,7][[1]]) # mi - price # -0.2 cor.test(zipcode_price_group[,4][[1]], zipcode_price_group[,7][[1]]) # hi - price # -0.3 cor.test(zipcode_price_group[,5][[1]], zipcode_price_group[,7][[1]]) # to - price # -0.3 학교 수가 많을수록 집값이 다소 하락하는 경향을 보인다. 하지만 상관관계가 0.2~0.3 으로 낮게 나왔기 때문에 초등학교, 중학교, 고등학교, 전체 학교의 숫자는 price 에 큰 영향을 미치지 않는다고 볼 수 있다. iv. season_price : 집이 팔린 계절별(봄/여름/가을/겨울) - 분석방법 : 여러집단 사이의 차이검정 (ANOVA, scheffe, test) head(date_numeric) # 새로운변수생성 kc_house$date_numeric = date_numeric # 집이팔린날짜가 # 봄(3,4,5 월) / 여름(6,7,8 월) / 가을(9,10,11 월) / 겨울(12,1,2 월) 별로 price 그룹화 spr_price <- kc_house[grep("....03..|....04..|....05..", date_numeric), "price"] sum_price <- kc_house[grep("....06..|....07..|....08..", date_numeric), "price"] fal_price <- kc_house[grep("....09..|....10..|....11..", date_numeric), "price"] win_price <- kc_house[grep("....12..|....01..|....02..", date_numeric), "price"] mean(spr_price[[1]]) mean(sum_price[[1]]) mean(fal_price[[1]]) mean(win_price[[1]]) length(spr_price[[1]]) + length(sum_price[[1]]) + length(fal_price[[1]]) + length(win_price[[1]]) # 21613 "전체를다가져왔는지확인" OK seson_price <- c(spr_price[[1]], sum_price[[1]], fal_price[[1]], win_price[[1]]) group <- c(rep(1, length(spr_price[[1]])), rep(2, length(sum_price[[1]])), rep(3, length(fal_price[[1]])), rep(4, length(win_price[[1]])))
  • 21. length(group) # 21613 cbind(seson_price, group) boxplot(seson_price ~ group) describe.by(seson_price, group) # 그룹별기술통계량계산 ANO_R<-aov(seson_price ~ group) anova(ANO_R) scheffe.test(ANO_R, "group", alpha =0.05, console = TRUE) LSD.test(ANO_R, "group", alpha =0.05, console = TRUE) duncan.test(ANO_R, "group", alpha =0.05, console = TRUE) t.test(fal_price[[1]], win_price[[1]]) 결과 > head( cbind(seson_price, group) ) seson_price group [1,] 538000 1 [2,] 180000 1 [3,] 310000 1 [4,] 530000 1 [5,] 650000 1 [6,] 485000 1 > tail( cbind(seson_price, group) ) seson_price group [21608,] 330000 4 [21609,] 230000 4 [21610,] 645000 4 [21611,] 414500 4 [21612,] 347500 4 [21613,] 350000 4
  • 22. > describe.by(seson_price, group) # 그룹별 기술통계량 계산 Descriptive statistics by group group: 1 vars n mean sd median trimmed mad min max range skew kurtosis se X1 1 6520 543036.7 363293.6 455700 486463.7 228765.2 78000 7062500 6984500 4 34.18 4499.19 ------------------------------------------------------------------------------ group: 2 vars n mean sd median trimmed mad min max range skew kurtosis se X1 1 6331 543183.9 377206.2 450000 480799 222390 75000 5570000 5495000 3.72 24.97 4740.7 ------------------------------------------------------------------------------ group: 3 vars n mean sd median trimmed mad min max range skew kurtosis se
  • 23. X1 1 5063 536213 365608 450000 480103.4 222390 82500 7700000 7617500 5.02 60.6 5138.21 ------------------------------------------------------------------------------ group: 4 vars n mean sd median trimmed mad min max range skew kurtosis se X1 1 3699 534896.4 358372.5 447500 477146.5 218683.5 83000 3800000 3717000 3.22 16.54 5892.4 > anova(ANO_R) Analysis of Variance Table Response: seson_price Df Sum Sq Mean Sq F value Pr(>F) group 1 2.4117e+11 2.4117e+11 1.7894 0.181 Residuals 21611 2.9127e+15 1.3478e+11 > scheffe.test(ANO_R, "group", alpha = 0.05, console = TRUE) Study: ANO_R ~ "group" Scheffe Test for seson_price Mean Square Error : 134777455496 group, means seson_price std r Min Max 1 543036.7 363293.6 6520 78000 7062500 2 543183.9 377206.2 6331 75000 5570000 3 536213.0 365608.0 5063 82500 7700000 4 534896.4 358372.4 3699 83000 3800000 Alpha: 0.05 ; DF Error: 21611 Critical Value of F: 2.60532 Harmonic Mean of Cell Sizes 5133.59
  • 24. Minimum Significant Difference: 20258.36 Means with the same letter are not significantly different. Groups, Treatments and means a 2 543200 a 1 543000 a 3 536200 a 4 534900 계절(봄/여름/가을/겨울)에 따른 그룹의 평균에서 유의미한 차이가 나타나지 않았다. 따라서, 계 절에 따른 price에는 차이가 없다고 볼 수 있다. 3. 자료 분석 A. 분석 방법 i. 회귀 모형 ii. 회귀모형에 들어갈 데이터 전처리 # date 변수를 numeric 으로 바꾸기 date_numeric <- substr(kc_house_data$date, 1, 8) # 20141124 형태로 연도날짜 문자부분만 추출 date_numeric <- as.numeric(date_numeric) is.numeric(date_numeric) # TRUE kc_house_data$date <- date_numeric # 기존의 date 를 새로운 numeric date 로 대체 집값 ~ 크기를 나타내는 변수(bathsrooms, bedrooms, floors, sqft_living) + 해안가 여부(waterfront _ T/F) + 집을 보러온 횟수(view _ 0/1/2/3/4) + 집 평가척도(grade) + zipcode group(총 12개)에 대한 더미변수 house_lm = lm(kc_house_data$price ~ room_newnum + waterfront + view + grade + X1 + X2 + X3 + X4 + X5 + X6 + X7 + X8 + X9 + X10 + X11 + X12, data = kc_house_data)
  • 25. # 크기를 나타내는 변수들을 묶어주기 kc_house_data$room_newnum = kc_house$bedrooms*0.308 + kc_house$bathrooms*0.525 + kc_house$floors*0.257 + kc_house$sqft_living*0.702 cor(kc_house$room_newnum, kc_house$price) # 0.702 View(kc_house_data) iii. zipcode 별로 price에 대한 정규성 검정 # by(A, B, shapiro.test) # B에 있는 모든 집단의 A값에 대해 정규성 검정을 한다 A <- by(kc_house$price, kc_house$zipcode, shapiro.test) ## p-value > 0.05인 zipcode group ### # kc_house$zipcode: 98002 # # Shapiro-Wilk normality test # # data: dd[x, ] # W = 0.99639, p-value = 0.9243 ### # kc_house$zipcode: 98108 # # Shapiro-Wilk normality test # # data: dd[x, ] # W = 0.99176, p-value = 0.3707 ### B. 분석 결과 i. Stepwise에 의한 영향력이 있는 변수의 선별 . Call: lm(formula = kc_house_data$price ~ room_newnum + waterfront + view + grade + X1 + X2 + X3 + X4 + X5 + X6 + X7 + X8 + X9 + X10 + X11 + X12, data = kc_house_data)
  • 26. Residuals: Min 1Q Median 3Q Max -1168280 -111183 -11201 93153 4695648 (2) Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) -428984.61 11000.94 -38.995 < 2e-16 *** room_newnum 219.91 3.37 65.248 < 2e-16 *** waterfront 596633.57 17493.97 34.105 < 2e-16 *** view 73086.65 2054.59 35.572 < 2e-16 *** grade 78201.44 1841.75 42.460 < 2e-16 *** X1 1210393.45 28972.94 41.777 < 2e-16 *** X2 631557.38 11627.49 54.316 < 2e-16 *** X3 359493.57 12361.11 29.083 < 2e-16 *** X4 467049.42 12554.92 37.200 < 2e-16 *** X5 335753.53 19958.60 16.822 < 2e-16 *** X6 187139.64 12507.13 14.963 < 2e-16 *** X7 118286.47 11234.48 10.529 < 2e-16 *** X8 64278.26 11002.59 5.842 5.23e-09 *** X9 85789.09 10854.34 7.904 2.84e-15 *** X10 -32043.68 12036.78 -2.662 0.00777 ** X11 -103019.44 10948.51 -9.409 < 2e-16 *** X12 -152845.27 13182.95 -11.594 < 2e-16 *** --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 Residual standard error: 203600 on 21596 degrees of freedom Multiple R-squared: 0.6926, Adjusted R-squared: 0.6924 (1) F-statistic: 3041 on 16 and 21596 DF, p-value: < 2.2e-16 ii. 회귀분석 결과 분석 1단계 : 회귀모형은 통계적으로 타당한가? 귀무가설 : 회귀모형은 타당하지 않다. 대립가설 : 회귀모형은 타당하다.
  • 27. (1) F-statistic: 3041 on 16 and 21596 DF, p-value: < 2.2e-16 (1)의 출력 결과물을 보면 p-value 값이 0.000 이므로 귀무가설을 기각한다. 1단계의 결론 : 대립가설, 회귀모형은 타당하다 2단계 : 독립변수 각각은 종속변수에게 영향을 주는가? 귀무가설 : 독립변수는 종속변수에게 영향을 주지 않는다. 대립가설 : 독립변수는 종속변수에게 영향을 준다. (2) Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) -428984.61 11000.94 -38.995 < 2e-16 *** room_newnum 219.91 3.37 65.248 < 2e-16 *** waterfront 596633.57 17493.97 34.105 < 2e-16 *** view 73086.65 2054.59 35.572 < 2e-16 *** grade 78201.44 1841.75 42.460 < 2e-16 *** X1 1210393.45 28972.94 41.777 < 2e-16 *** X2 631557.38 11627.49 54.316 < 2e-16 *** X3 359493.57 12361.11 29.083 < 2e-16 *** X4 467049.42 12554.92 37.200 < 2e-16 *** X5 335753.53 19958.60 16.822 < 2e-16 *** X6 187139.64 12507.13 14.963 < 2e-16 *** X7 118286.47 11234.48 10.529 < 2e-16 *** X8 64278.26 11002.59 5.842 5.23e-09 *** X9 85789.09 10854.34 7.904 2.84e-15 *** X10 -32043.68 12036.78 -2.662 0.00777 ** X11 -103019.44 10948.51 -9.409 < 2e-16 *** X12 -152845.27 13182.95 -11.594 < 2e-16 *** --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 (2)의 출력 결과물을 보면 유의확률(Pr(>|t|))이 0.000 에 가까우므로 귀무가설을 기각하여, 유의수준인 0.05 구간에서 독립변수는 종속변수에게 영향을 준다는 대립가설을 채택한다. 2단계의 결론 : 독립변수는 종속변수에게 영향을 준다. 변수선택 : 단계 선택법(Stepwise Selection)방법 선택 step(회귀분석결과물, direction = c("forward", "backward", "both")) model.stepwise = step(house_lm, direction = "both") summary(model.stepwise)
  • 28. 3단계 : 변수선택 (결론출력) 독립변수의회귀계수(coefficient of Regression) : 0.6926 4단계 : 회귀모형의설명력 = 독립변수의설명 Multiple R-squared : 0.6926 0.6926 * 100 = 69.2% 설명계수인 R-squared 를 출력한 결과가 price 의 다름을 약 69.2%를 설명한다. 단, 고려해야할 점이 있다. 만약, 최종회귀모형에 독립변수가 2개이상 포함이 되면 첫째, 회귀계수의 해석을 확인해야 한다. 독립변수1은 나머지 독립변수들이 고정되어 있을 때에(통제) 1의기본단위가 1 증가하면 종속변수는 약 얼마 증가/감소하는지 고려해야 한다. 둘째, 다중공선성(Multicollinearity)을 확인해야 한다. 독립변수들간의 선형의 관계는 없어야 한다. 예를 들어, VIF(Varaince Inflation Factor) : 10 이상이면 다중공선성이 존재한다고 판단하며, 독립변수들 간에 선형의 관계가 존재함을 알 수 있다. 만약 이러한 결과가 나온다면 독립변수들 중에 빼는 것을 검토한다. 다중공선성(Multicollinearity)을 확인 library(car) car::vif(model.stepwise) > car::vif(model.stepwise) room_newnum waterfront view grade X1 X2 X3 X4 2.465253 1.194046 1.292139 2.442943 1.009935 1.018493 1.025663 1.009917 X5 X6 X7 X8 X9 X10 X11 X12 1.003873 1.005920 1.012795 1.005337 1.003162 1.003162 1.003869 1.002985 모든 변수들에 대한 VIF 값이 10 이하이므로 독립변수 간의 다중공선성은 존재하지 않는다. 회귀모형의 설명력 : Adjusted R-Square Adjusted R-squared: 0.6924 독립변수들의 영향력 크기 비교 library(lm.beta) lm.beta::lm.beta(attitude.lm) > lm.beta::lm.beta(model.stepwise)
  • 29. Call: lm(formula = kc_house_data$price ~ room_newnum + waterfront + view + grade + X1 + X2 + X3 + X4 + X5 + X6 + X7 + X8 + X9 + X10 + X11 + X12, data = kc_house_data) Standardized Coefficients:: (Intercept) room_newnum waterfront view grade X1 X2 X3 0.00000000 0.38651375 0.14060267 0.15255635 0.25038342 0.15839614 0.20680922 0.11112192 X4 X5 X6 X7 X8 X9 X10 X11 0.14104423 0.06359071 0.05661791 0.03997667 0.02209983 0.02986607 -0.01005961 - 0.03556859 X12 -0.04380771 4. 예측 kc_house_final <- kc_house_data[,c("room_newnum","waterfront","view","grade","X1","X2","X3","X4","X5","X6","X7","X 8","X9","X10","X11","X12")] # predict(회귀분석결과, newdata = data.frame(complaints = )) predict(model.stepwise, newdata = data.frame(kc_house_final[1:5,]), interval = "predict") View(kc_house_data) 1) 예측값 > predict(model.stepwise, newdata = data.frame(kc_house_final[1:6,]), interval = "predict") # 점추 정? fit lwr upr 1 219839.6 -186103.7 625782.8 2 285515.2 -120405.3 691435.7 3 268629.0 -137296.2 674554.2 4 493984.5 87995.8 899973.1
  • 30. 2) 실제값 zipcode id date price 1 98001 302000375 20140814 169100 2 98001 6181400920 20150430 286651 3 98001 2005950050 20140527 260000 4 98001 8956200070 20140905 447500 5. 최종 결론 표준화된 회귀계수에 의해서, price에 가장 영향을 미치는 변수는 집의 크기와 관련된 변 수들(화장실수, 침실수, 층수, 평수)와 grade라는 것을 알 수 있다. 변수명 변수 설명 표준화된 상관계수 room_newnum 집의 크기와 관련된 변수들을 한가지 의 변수로 모델링 한 변수 (화장실수, 침실수, 층수, 평수) 0.387 grade Kingcounty grading system에 의한 집에 대한 평가척도 0.250 6. 미비점 및 개선방향 - 집 크기에 영향을 받는 변수들(bathrooms, bedrooms, floors, sqft_living)을 하나의 데이터로 모델 링하는 과정에서 가중치 선정방법이 미흡했던 것 같다. 이러한 변수들이 실제로 집값에 영향을 미치는 정도에 따라서 가중치를 선정하려고 했으나, 논문자료에서 이에 대한 정보를 찾지 못했다. 그래서 차선책으로 각 변수들에 대한 상관계수를 곱해서 더해주는 방식을 선택했다. 이 방법은 현재 주어진 자료에서만 유효하므로, 다음에 기회가 된다면 전체 집값에 유의미한 모델링을 해보 고 싶다. - 집 별로 평수의 차이가 있는데 단위 평수당 가격을 고려하지 않고 단순히 zipcode별 집값에 대 한 분석을 진행하였다. 따라서 평수당 가격보다는 지역의 요인에 중점을 두었으며, 누락되는 부분 이 충분히 있었을 것이라고 판단된다.
  • 31. - 주어진 데이터 이외에 새로운 변수들을 만들어내려고 노력하였는데, 많은 변수들(School, Seasonality 등)이 price에 유의미한 영향을 주지 않아 채택하지 못했다. 변수를 세부그룹으로 나 누거나 이상치를 제거하는 등 데이터 전처리 과정을 거친다면 채택하지 못한 변수들과 price 사 이에 유의미한 상관관계를 찾을 수 있을 것이라고 생각한다. 전체적으로 데이터를 전처리 하는 과정이 부족하였던 점이 아쉬웠다. - 관련 논문을 찾아보다가 집값이 비싸질수록 화장실수, 평수 등과 같은 물리적인 특성보다 해안 가, 학교 수, 백화점과의 거리 등의 입지적인 특성에 더욱 영향을 많이 받는다는 연구결과를 알게 되었다. 집값이 비싼 집들과 비싸지 않은 집들을 각각 분석해서 여러 가지의 회귀모형을 선정해 보는 것도 좋은 프로젝트가 되었을 것 같다. 종속변수에 대한 시계열 자료 house_price_ts <- ts(kc_house$price, start = c(2014, 182), end = c(2015, 182), frequency = 365) plot(house_price_ts, ylab = "Kingcounty House Price", xlab = "Year.Month", xlim = c(2014.5, 2015.5)) par(mfrow = c(1,2)) acf(house_price_ts) # 파란색 점선 밑에 그래프가 있어야 유의한것이다! pacf(house_price_ts) ndiffs(house_price_ts) # 0 # 아주 강력한 function! auto.arima houseBest <- auto.arima(x = house_price_ts) houseBest par(mfrow = c(1,2)) library(scales) forecast(houseBest, h = 5) -> houseforecast # 80%, 95% 신뢰구간이 같이 나옴 plot(houseforecast)