壹、研究主題

房價地圖與房市分析與預測–以新竹為例

貳、前言

近年房市變化頻繁,關於房市的新聞也常常是熱門討論議題,我們希望可以製作一個簡易的房價查詢互動地圖介面(參照另一個檔案:fina_map.html),讓使用者可以依自身需求篩選想要的房價相關資料,同時提供房價預測的結果以供參考,其中會包含可以自由選擇想要變數的篩選器,以及相對應的趨勢圖等。

參、流程

一、資料清洗

資料來源:內政部的公開房價資料,以不動產買賣資料為主,擷取新竹縣市從民國106年到111年五月發佈的公開房價資料。

新竹地區分為:新竹市及新竹縣鄉鎮市共14區。

刪除及增加資料:公開資料網頁下載的資料共有33個欄位變數,在交易標的之中只截取有包含”房“的資料,增加用交易年月日加以計算出的屋齡欄位,其餘一變數的選擇將目前用不到的資料刪除。資料如下:

df = read.csv("_data.csv")
df$交易年月日 = sapply(df$交易年月日, function(x)as.integer(x))
df$交易年月日 = sapply(df$交易年月日, function(x)floor(x/10000))
df2 = df[1:5,]
DT::datatable(df2)

畫房價走勢圖,以新竹市為例:

line = read.csv("trend.csv") 
line <- line %>% mutate(year = as.character(year))
ggplot(line,aes(x = year,y = unit_price,color = county, group = county))+
  geom_line() +
  geom_point() + theme_bw()

二、房價預測-模型建立(多元回歸)

資料準備:我們選擇與房價相關的主要的七個變數為——

price: “總價元“

x1: “主建物面積”, x2: “屋齡”, x3: “陽台面積”,

x4: “建物現況格局-房”, x5: “建物現況格局-廳”,

x6: “建物現況格局-衛”, x7: “車位總價元”, x8: “car”(有無車位),

資料如圖:

df = read.csv("_data.csv")
df = na.omit(df)
df_new = df %>% mutate(car = ifelse(車位總價元!=0,1,0))
set_use = df_new[,c("主建物面積","房屋年齡","陽台面積",
                 "建物現況格局.房","建物現況格局.廳",
                 "建物現況格局.衛","車位總價元","car","總價元")]
colnames(set_use) = c("x1","x2","x3","x4","x5","x6","x7","x8","price")
set_use = set_use[1:5,]
DT::datatable(set_use)

建立影響房價的多因素的多元線性迴歸模型:

模型的建立:

price=α + β_0 + β_1x1+β_2x2 + β_3x3 + β_4x4 + β_5x5 + β_6x6 + β_7x7 + β_8x8 + ε , 公式中的:β_0,β_1,β_3,β_4,β_5,β_6,β_7,β_8 為未知變數估計值,ε為隨機誤差,且認為ε服從常態分佈。對於公式中未知引數的估計採用最小二乘法,求相關係數R^2,並做顯著性檢驗,證明模型的建立是正確的。

為了確定商品房銷售價格與各變數之間的關係,分別作出price與x_i 的散點圖:

plot(set_use)

利用rcorr()得到相關矩陣並整理得:

df = read.csv("_data.csv")
df = na.omit(df)
df_new = df %>% mutate(car = ifelse(車位總價元!=0,1,0))
set_use = df_new[,c("主建物面積","房屋年齡","陽台面積",
                 "建物現況格局.房","建物現況格局.廳",
                 "建物現況格局.衛","車位總價元","car","總價元")]
colnames(set_use) = c("x1","x2","x3","x4","x5","x6","x7","x8","price")
correlation = rcorr(as.matrix(set_use))
corrplot(corr=correlation$r,sig.level=0.05,
         method = "color",type="upper",addCoef.col="grey"
         ,tl.col="black")

綜上結果可知,在α=0.05的條件下,x1,x7與price的相關性較好。 對變數進行多元迴歸方程,結果如下:

df = read.csv("_data.csv")
df = na.omit(df)
df_new = df %>% mutate(car = ifelse(車位總價元!=0,1,0))
set_use = df_new[,c("主建物面積","房屋年齡","陽台面積",
                 "建物現況格局.房","建物現況格局.廳",
                 "建物現況格局.衛","車位總價元","car","總價元")]
colnames(set_use) = c("x1","x2","x3","x4","x5","x6","x7","x8","price")
reg1 = lm(formula = price ~ x1
            + x2 + x3 + x4 +x5+ x6 + x7 + x8
            , data = set_use)
summary(reg1)
## 
## Call:
## lm(formula = price ~ x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8, data = set_use)
## 
## Residuals:
##        Min         1Q     Median         3Q        Max 
## -208300487   -3217265   -1090839    1596025  277437530 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  5.538e+06  1.638e+05  33.805  < 2e-16 ***
## x1           4.871e+04  2.688e+02 181.240  < 2e-16 ***
## x2          -6.859e+04  4.912e+03 -13.964  < 2e-16 ***
## x3           2.234e+05  6.533e+03  34.199  < 2e-16 ***
## x4          -4.295e+05  5.877e+04  -7.309 2.77e-13 ***
## x5          -3.010e+05  7.251e+04  -4.152 3.31e-05 ***
## x6           5.693e+05  5.834e+04   9.758  < 2e-16 ***
## x7           4.590e+00  6.043e-02  75.954  < 2e-16 ***
## x8          -4.523e+06  1.540e+05 -29.372  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 7950000 on 27425 degrees of freedom
## Multiple R-squared:  0.665,  Adjusted R-squared:  0.6649 
## F-statistic:  6804 on 8 and 27425 DF,  p-value: < 2.2e-16

結果:

對係數進行顯著性檢驗,由結果可知,β_i的P值小於0.05,故可以拒絕原假設,認為這些變數效果明顯, 對方程進行檢驗,而相關係數R^2=0.6649,P值小於0.05,故拒絕原假設,即認為y與各個變數之間存線上性關係。

總結:

目前得到得到最優的多元線性模型為: \[ f(總價元) = 5.538*10^6 + 4.871*10^4*x1-6.859*10^4*x2+2.234*10^5*x3-4.295*10^5*x4-3.010*10^5*x5 -5.693*10^5*x6 + 4.590*x7-4.523*10^6*x8\]

三、房價地圖

利用chrome的goecode by Awesome擴充功能,將最新一季公開資料匯入,幫助求出經緯度,再利用 leaflet ()畫出標有地點的地圖:

data <- read.csv("house.csv")
data <- data %>% dplyr::mutate(date3 = as.Date(date))
shared_data <- SharedData$new(data)
leaflet(shared_data) %>%
  leaflet::addTiles() %>%
  leaflet::addMarkers(popup = data$address) %>%
  setView(121.0,24.83123, zoom = 12)

加入篩選欄位,包括交易日期、總價、行政區、建物型態、有無電梯

showtext.auto(enable = TRUE)
filter_slider("date", "交易日期", shared_data, ~date3, width = "100%")
filter_slider("總價", "總價", shared_data, ~總價, width = "100%")
filter_select(
  id = "district",
  label = "行政區",
  sharedData = shared_data,
  group = ~district)
filter_select(
    id = "main_use",
    label = "建物型態",
    sharedData = shared_data,
    group = ~main_use)
filter_checkbox(
    id = "elevator",
    label = "有無電梯",
    sharedData = shared_data,
    group = ~elevator)

分析各年各行政區售出建物型態:

bar <- read.csv("_house_type.csv") 
bar <- bar %>% mutate(year = as.character(year))
plot_ly(bar , labels = ~建物型態,  values= ~count, showlegend = FALSE) %>% 
    add_pie(marker = list(colors = colors)) 

歷史平均價格面量圖:

TW=st_read("TOWN_MOI_1100415.shp",quiet = TRUE)
data = read.csv("average.csv")
hsinchu = TW[TW$COUNTYNAME == "新竹市"| TW$COUNTYNAME == "新竹縣",]
hsinchu.map=hsinchu[c("TOWNNAME", "geometry")]
hsinchu.map$TOWNNAME <- as.character(hsinchu.map$TOWNNAME)
hsinchu.map.data=left_join(hsinchu.map,data,by= c("TOWNNAME"= "county"))
ggplot(data = hsinchu.map.data) +
  geom_sf(aes(fill = unit_price)) +
  geom_sf_text(aes(label = TOWNNAME), size = 2) +
  scale_fill_distiller(palette = "Spectral", name = "平均單價元平方公尺") +
  labs(title="新竹縣市各區域平均房價", x ="經度", y = "緯度")

肆、問題回答

Where you get your project ideas?

臨抽宿舍之際,我沒有抽到下學期的宿舍,我開始在各大租房網站,查找下學期要找的租屋。這時候我發現在論壇中,三年內的新竹租房價上漲了許多,這不禁讓我思考這是否與新竹的房價有關。由此開始了專題主題,搜索房價相關資料後,我們發現新竹縣市地區的房價漲幅以科技園區最為嚴重。在調查資料的時候,我們想將新竹縣市各地的房價資料進行垂直與水平的比對,我們想知道10年內各地區的房價是否都上漲,還有各地區的房價差距。另外由於租房網站會顯示房間數跟是否有車位的選項,所以我們在做完以上的分析後,也稍微檢測一下這些變數對房價的影響,並對其進行預測。

What R techniques have been used?

Base function:

  • as_tibble()

  • %>% mutate()

  • %>% filter()

  • %>% summarise()

  • %>% group_by()

  • sapply()

  • Which()

  • subset()

  • lm()

  • rcorr()

  • ggplot() + geom_point() + geom_line()

How many new packages and functions are used?

1.packages

  • showtext

  • leaflet

  • flexdashboard

  • crosstalk

  • sf

  • gridExtra

  • viridis

  • fields

2.new functions

  • filter_slider

  • filter_select

  • filter_checkbox

  • leaflet() %>% leaflet::addTiles() %>% leaflet::addMarkers() %>% setView()

What is the most difficult part of your analysis?

最困難的地方:

由於我們是從政府公開資料平台下載新竹縣市各地區的房價資料,其可用來分析的變數資料種類太少,又與房價的相關性偏低,不像kaggle下載的資料包有相當多與房價相關性高的變數,因此我們在統計結果中,難以解釋變數帶來的影響,而回歸模型也可能誤差很大。另外,我們有觀察到新竹偏鄉的交易量過於稀少,這也導致我們在分區分析時,沒有足夠的資料進行各區域房價的回歸預測。

最花時間的部分:

為了呈現優美的網頁,我們花很多時間研究如何用leaflet工具去繪製互動式地圖以及利用「台灣鄉鎮市區界線」shapefile檔繪製新竹平均房價的面量圖。我們因此可以學習如何將統計資料與地圖需資料結合,拓展對於R程式語言的學習與應用。