预测房价:回归问题——R语言
9 ]; Y" U; {/ W' u" L在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。
3 t! F0 j; H) L5 U! U, m$ a! x# G% f& ?
问题描述
( V% X" M* ?4 S) W R$ t* O我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。. A4 H8 c! g U2 O- N( J; e" K
本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。) }* K# j4 b, F6 W7 L4 b1 L
数据特征:+ K- P: z; K, y
人均犯罪率。/ L, W5 r( q' [2 F
占地面积超过25,000平方英尺的住宅用地比例。+ o5 X+ y: T. W% b; O+ I x
每个城镇非零售业务的比例。
. R; \( }) h1 \) _: zCharles River虚拟变量(如果管道限制河流则= 1;否则为0)。
3 r9 |# x8 z& @, `$ `& a/ s' c一氧化氮浓度(每千万份)。
% W6 q# Q& D: { y8 f: H, |) ]每栋住宅的平均房间数。( |: }! e `" e, X
1940年以前建造的自住单位比例。% F5 _ l6 j" H8 \8 o0 e
到波士顿五个就业中心的加权距离。 _0 k4 h, y6 l( `! L0 n
径向高速公路的可达性指数。
5 j7 b8 t5 u3 `2 V每10,000美元的全额物业税率。
. l/ E6 f5 }: E; c& Z城镇的学生与教师比例。
. d3 H+ s V% z1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。
+ x1 U) E/ M' V2 N4 ]9 Q! I( B人口比例较低的百分比。3 | S7 h* G$ M' Z
1. 加载波士顿房价数据 X. i7 ~. m$ ]: o! J& Z9 ~9 l) {
library(keras)
$ j0 K; p T7 a1 o- {' C
- J3 i2 b( R- m$ \boston_housing <- dataset_boston_housing()7 @- k( M! z+ Y( U+ x$ m( w
0 u* _- u Z; {* R" `" ?5 pc(train_data, train_labels) %<-% boston_housing$train7 V. ~, o* h" k4 }" w" X8 {
c(test_data, test_labels) %<-% boston_housing$test1 Y' D `$ Q% J1 ?% m# X9 ~' i
- V' [1 N! A& s0 P) V) E+ S' T
每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。
) R0 U& [$ @/ _# N2 D# Test data is *not* used when calculating the mean and std./ O# P" T7 _# j1 r5 t' P
( i. W' E/ y; V# m
# Normalize training data. @ c( V9 @2 w9 z
train_data <- scale(train_data) ; G* X1 L5 T' p: V7 c
3 M5 U2 ^1 Q9 d) A( p( e; w, z9 e
# Use means and standard deviations from training set to normalize test set
/ E g5 a. j3 r1 C2 qcol_means_train <- attr(train_data, "scaled:center") ( O5 R* i. {; C
col_stddevs_train <- attr(train_data, "scaled:scale")
. r6 |: h3 |" H# C; q4 k7 f4 ctest_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)
( q4 F6 J2 a# k7 _, t7 H9 C
2 \. h" j9 Z5 g) W4 G3. 构建网络创建模型 6 r2 v8 z7 V2 n
build_model <- function() {
9 D$ K+ e% `- n( y+ I- Y# a N* B+ \
5 F, Y1 j, K0 w, @: Z# \2 Y model <- keras_model_sequential() %>%* F) s3 c# I! p2 f
layer_dense(units = 64, activation = "relu",3 K/ k( [( q# {9 ~8 z
input_shape = dim(train_data)[2]) %>%$ d @5 z% H3 E. i: T, G7 s* g
layer_dense(units = 64, activation = "relu") %>%: k- m7 S( Q* r$ K- H' Y9 @
layer_dense(units = 1)+ e1 ^/ u; O0 ?) M6 z) e. u; Q
2 o8 `' G5 `7 v* T: k2 s
model %>% compile(
) g5 u) B' a4 H7 t2 k loss = "mse",: O: T# h/ N3 @% Q3 x+ V1 q7 c
optimizer = optimizer_rmsprop(),' y4 ?% g' K4 R8 L( }- \" Q
metrics = list("mean_absolute_error")
* U1 n' T( x: \1 H6 ]( t3 y- K) @ )
/ M' `- g8 f/ @: [/ Q8 ~7 E. Y, k/ U& {& q9 w) y7 p
model
6 r! e( Q6 R+ `$ W1 f}
8 X2 t: F% L2 b, Q. w1 h* P- _$ W3 w. w5 t; ]* Y" ?/ c6 a0 _5 T8 u
model <- build_model()- W$ H2 z( g! k2 Q6 c6 K) ~
model %>% summary()
; w9 S9 w% i1 w6 o$ ~5 R
2 l! Y4 q- [. I% J" C网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型, u3 ~7 h8 D+ }6 ~+ i2 x, ?
# Display training progress by printing a single dot for each completed epoch.
# o$ }- I" V+ x3 mprint_dot_callback <- callback_lambda(
& V7 m! C* `6 n) J# N on_epoch_end = function(epoch, logs) {9 a0 M ]3 K2 S* d* `
if (epoch %% 80 == 0) cat("\n"); _, U; G2 D O% u' l, A
cat(".")* L$ K/ _* c/ x! L# ?8 k
}9 o% Z4 h- F8 k3 v/ @- D4 {
) ; t! ]+ T, [% U; I* s
8 h+ h7 ?& t+ G' }; E' Lepochs <- 500/ y- h5 p0 C3 T
# W, l- N; V5 E, \5 ]5 ]* B$ Q& }
# Fit the model and store training stats( C- ~ d) D+ L9 h- V9 H
history <- model %>% fit(( l! U. d" F* y9 a% ^
train_data,
8 i: ^0 O; v0 @$ ~$ x6 [* | train_labels,+ L# }0 A) o. u$ @/ Y
epochs = epochs,
; ?" x4 D3 X" q1 l1 x+ L. e) u2 E validation_split = 0.2,1 O8 w. z# L3 T- e9 e
verbose = 0,$ A0 c1 N& Q: J& |5 {0 L# }$ E
callbacks = list(print_dot_callback)
8 k Y# H* s9 l* f)
9 J* O; z, U" N% h! x& R+ R: O, W) ^" s8 z c
library(ggplot2)# D: v( L' m4 E9 A
% X1 H6 `! A) n
plot(history, metrics = "mean_absolute_error", smooth = FALSE) +! y4 k0 M+ H' H0 j
coord_cartesian(ylim = c(0, 5))! o+ c: o! w7 M8 {
0 p0 n3 q) P9 s+ R3 m/ U1 I& }" l3 W![]()
, ^- ]+ Y% [! S) {" y7 ?* |4 _1 Z5 B# ?% B5 a/ Y
小结
& K- D6 D/ i0 f1)回归常用的损失函数是均方误差(MSE)。5 m4 v4 `: p5 i/ A, q5 _
2)常见的回归指标是平均绝对误差(MAE)。8 [1 d! s" Z; h" g+ b9 J
3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。
: y2 p, i& Z/ Q' W. x4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。
/ Y% k0 E, z. a8 S8 U* r3 G6 P) e; u2 L9 ]/ o7 X1 i Z) o
& L+ k5 k' m* I( E; ^" _& H4 J
' d& E) l7 I; t( Y6 T9 n0 {
|