预测房价:回归问题——R语言
+ _/ P4 l# F/ K5 e4 J# b在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。
v: [: m+ k1 b6 E( [) `) }: l1 _! u; f- H
问题描述
1 R& `& X+ [8 X* J1 y8 M我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。" s' |3 H, O! o' l+ F0 X% M/ Q6 q( g
本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。
: u* R1 @7 \. p3 N; s9 _, I数据特征:
3 s+ _2 j' I& J5 Y+ j6 B( l! B+ I人均犯罪率。6 e9 Z3 Q, v% X' O" U% C. u( @
占地面积超过25,000平方英尺的住宅用地比例。% |! N) p! Z2 }/ x' l6 s0 p2 _
每个城镇非零售业务的比例。
9 y% E7 t6 n9 w, u* l1 XCharles River虚拟变量(如果管道限制河流则= 1;否则为0)。$ W1 b8 ?# B0 P1 I- W1 @
一氧化氮浓度(每千万份)。# h( G( \2 r1 W& }) S4 K9 ~
每栋住宅的平均房间数。. b" p$ T: S$ N7 M' t" F; G
1940年以前建造的自住单位比例。: P C( G& W' {, U* x P
到波士顿五个就业中心的加权距离。
& w# A6 L# Z- h4 P& P S径向高速公路的可达性指数。& v$ D7 Q& J$ c4 v
每10,000美元的全额物业税率。' n( K# K2 z6 m& k$ i2 h% Z* ^" V2 @
城镇的学生与教师比例。
( c2 n$ z7 v# T( Z/ `1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。: R! @- C: e. @# ]
人口比例较低的百分比。
' e2 D8 I8 t4 q$ }1. 加载波士顿房价数据8 E: x! o% m; I! K
library(keras)
& c4 i" E4 M# v# }+ r3 \/ x- ^6 g
4 b9 X; _$ H! D( {" s$ Lboston_housing <- dataset_boston_housing()
3 m+ s, l; @# a9 M+ z% k2 m' k! y% i6 c2 q$ z3 R! t7 ]. Y( q+ k
c(train_data, train_labels) %<-% boston_housing$train) r- O- k! t4 U8 v, E
c(test_data, test_labels) %<-% boston_housing$test
5 }. E7 Q: ?( Z% u. S3 h% x. w1 ^) ^0 g: b: d5 ?* h) R, s' D% S& F* _
每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。 - {( d1 |( S2 ~$ ~' }# }5 t/ F
# Test data is *not* used when calculating the mean and std.
& H0 R) _7 E2 |6 n4 P8 B
/ o* B' A! p; l0 u1 y6 P f# Normalize training data N7 x8 p I A8 E- y
train_data <- scale(train_data)
3 w4 y+ i* _8 { r" [+ Q
4 U3 f- u1 S9 W* c( J2 a3 O# Use means and standard deviations from training set to normalize test set2 V2 u, m* t9 N6 G2 x2 C( h
col_means_train <- attr(train_data, "scaled:center") ' ?* }6 d+ [; p! {
col_stddevs_train <- attr(train_data, "scaled:scale")) J" p, ~) A! a2 Z0 B, d
test_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)
( ^$ x2 e* W! N* @4 r* d
! W) m- [$ b9 c5 Q- Q3 `* l3. 构建网络创建模型 " ~( a+ f8 U3 L8 R4 A+ G
build_model <- function() {
& z# f$ s- G, {0 j! i# K4 R; }9 X5 V
model <- keras_model_sequential() %>%
! {& c1 ^0 Q: x0 {6 J+ [! |* o6 u7 a layer_dense(units = 64, activation = "relu",; ]8 S5 ?1 Z. K# ~
input_shape = dim(train_data)[2]) %>%
. T7 U6 p0 s# c. ]+ I layer_dense(units = 64, activation = "relu") %>%
& l( i; h% m* b) r: S2 V layer_dense(units = 1), W# `5 i% L4 g$ M: M% \9 S; n, A
' T3 Y# I+ w4 t. x( Q$ o7 q
model %>% compile(- V$ n9 Q# c! T. W1 s* r
loss = "mse",
8 x, W& E+ L, U' g9 ? optimizer = optimizer_rmsprop(),
: N5 k; u9 B* _8 t g* u metrics = list("mean_absolute_error")
0 A! y6 r' a& _: U8 k )
4 ] n! O2 ?$ H3 q: l& P+ {: x
0 ^) V; x j6 ?; ]2 K5 G model( }! S0 X# t# p( a! J
}
2 f% h, p- t( E3 Q$ q# F1 ?
* B0 G4 _1 p( |* C" P& A1 X+ ^model <- build_model()
- s$ G2 }. j- k/ |6 |model %>% summary()
E5 l2 S1 f+ V ~( O+ N
' z0 B& F! j4 V; e" A- a网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型
( u) U5 I) B! \% V+ Z% ~) p# Display training progress by printing a single dot for each completed epoch.
( }7 Y+ C1 h" G8 o R# k/ jprint_dot_callback <- callback_lambda(
- k5 @, \+ V5 {, s on_epoch_end = function(epoch, logs) {
8 y/ J0 c% F( q4 G' Y1 A if (epoch %% 80 == 0) cat("\n")3 G9 {5 e4 x! ~. ?* P; J
cat(".")
- v+ g7 p: s$ I% K }2 @' h8 T; V* O1 e
)
8 |5 ?1 }- h( R" f! A" n
: b5 q9 _# h5 W; S& m3 k$ w8 G6 u4 Aepochs <- 500
" f; [; ?8 Y+ ^7 t+ o' l! K( {4 p6 |. k3 z2 c; z
# Fit the model and store training stats' L7 M7 B$ p+ C
history <- model %>% fit(
l5 g7 F% G& K train_data,
; U0 C1 G) S: v ` train_labels,
& z S( R8 r$ _3 U4 x' X* Q epochs = epochs,
3 o# c* F- [0 P8 _) g& N; L- a validation_split = 0.2,
8 J* K$ z8 H" K" Z verbose = 0,
' c, ^8 O8 f; @# a callbacks = list(print_dot_callback)
- {, P! i: B; H; Q3 P)) c- Y/ H. h1 C
1 Q2 u; \! f+ Z+ E4 J
library(ggplot2)6 w% u# h% X6 k! s8 p% e- {! u
0 ]& u: ~ b8 l1 m2 ^plot(history, metrics = "mean_absolute_error", smooth = FALSE) +
1 C' W6 X6 M# V: Y coord_cartesian(ylim = c(0, 5))) V D% `% z, k& \/ ^' q
# @+ ]+ Y- B- l- S- a# Q1 o1 b # o- U0 S* r$ {" A1 P- q
& s0 k% v1 U n5 ?" L
小结
$ h. Z* I4 x! H8 |! l1)回归常用的损失函数是均方误差(MSE)。; w# X, Z2 i9 O
2)常见的回归指标是平均绝对误差(MAE)。
: w& _, Z8 m% a+ T& V" q3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。7 T) t, W$ s5 {
4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。' `% s/ Y7 p6 C/ j6 B7 J
5 ^3 b2 N2 E; I, r; E
" S! p. [1 u$ Y7 M2 B# u( h. @+ B) }+ O" H4 M7 y
|