预测房价:回归问题——R语言# L6 _% q* l' P0 Y
在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。
# Z' I( _3 j% I. w; L1 k$ e9 w7 C1 A- D- t; b+ g6 K: u
问题描述
3 M& k w/ w3 Q7 y5 o/ S; X7 d我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。9 d6 f$ o: f$ B8 L2 T; S
本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。2 |7 B+ f+ p2 {& c3 }7 t
数据特征:
0 O+ W8 I% ?) H: X4 v& r. f) o人均犯罪率。' A: m: Z4 z# U, o
占地面积超过25,000平方英尺的住宅用地比例。
: K: {; {' U1 E; i" z ?每个城镇非零售业务的比例。
7 B3 o2 F" N" u# N6 ~2 ], ^$ I3 BCharles River虚拟变量(如果管道限制河流则= 1;否则为0)。
7 b6 y! q) L) U! J$ q" U! z一氧化氮浓度(每千万份)。6 K8 h6 j; h) v6 M0 h; {$ Q
每栋住宅的平均房间数。2 \2 o$ ?: R9 J+ V
1940年以前建造的自住单位比例。/ W/ @. P8 h i+ z
到波士顿五个就业中心的加权距离。7 m4 |4 o0 p- H" K' n: `; W. d
径向高速公路的可达性指数。 C7 k% a$ i9 m2 W* v( `8 [" W- X
每10,000美元的全额物业税率。; @9 H0 B) J4 Y4 E+ P; s K/ h) S
城镇的学生与教师比例。
% X2 Y$ x& ~. n) ?& F1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。
# k+ ~8 T0 h: V0 B) n9 E# v人口比例较低的百分比。! x5 g1 R9 y" V9 \$ v
1. 加载波士顿房价数据2 V. ~3 o; Q0 `5 Z0 q1 c
library(keras)
, z+ t0 ^# E7 ^8 L$ }; h" X& o, a
* c4 P$ o5 G, Fboston_housing <- dataset_boston_housing()
6 ^9 u* z5 F7 b) f1 j- I# E' x
' X4 m) b1 b, V& W$ A+ Rc(train_data, train_labels) %<-% boston_housing$train
h. z+ f, j% Xc(test_data, test_labels) %<-% boston_housing$test. m0 \) w5 c1 Y' @
9 R3 E. f5 q! _3 b
每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。 * v: {' W& f$ w5 C+ s% w4 C. d" r
# Test data is *not* used when calculating the mean and std.) T0 U' S4 Z1 E- z8 D+ N* U
1 n. L1 U3 I1 x s, l4 A$ o# Normalize training data
( [* ^0 k& e8 k ttrain_data <- scale(train_data) , A& ?9 v" {$ X
$ V6 Z' J3 z* t5 Y+ b9 Q9 I
# Use means and standard deviations from training set to normalize test set
4 ]- o7 z, ?9 \' V( j/ `' @7 i/ hcol_means_train <- attr(train_data, "scaled:center")
1 l! F' m8 \/ z8 M% rcol_stddevs_train <- attr(train_data, "scaled:scale")8 b: {# |$ C) R
test_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)
" ^' _5 D& I3 y% w/ n" x# O, X* K5 c$ C S* @
3. 构建网络创建模型
& b- w% z5 k9 A7 I5 N. O8 N: U; Cbuild_model <- function() {0 O/ Q/ E% Z. \! M6 a4 E" h) e8 a
" a; j9 I5 y' H4 K
model <- keras_model_sequential() %>%
, c$ ^" C' X1 h( J7 a layer_dense(units = 64, activation = "relu",
( p$ I7 j6 b# \( V6 L! d- M, y input_shape = dim(train_data)[2]) %>%
/ B1 w+ z1 @2 b layer_dense(units = 64, activation = "relu") %>%
1 c3 f0 D6 G" p6 O4 P/ f layer_dense(units = 1)& v; C" Z: r2 W. t: d( U4 t2 i* g5 D
1 K4 y ~( e# m; u9 ?
model %>% compile(
: h1 G2 |4 D4 d" R& t6 n2 U: q4 c loss = "mse",3 c! u/ Y/ T5 l
optimizer = optimizer_rmsprop(),9 i' a) u; t5 S% g
metrics = list("mean_absolute_error")
; H' P" q n$ g )) c1 k' j9 |" b& s: C& ?/ B5 x
, n( ]5 H4 O! _; B# }4 Q& n1 w model/ H7 i5 u1 T3 o7 P' u' R
}5 h4 V5 S2 l U$ t- T& `' w
7 a7 k4 {( ?' X0 emodel <- build_model()
9 T1 q2 L& f) h. umodel %>% summary()" [, o, R: V: |$ L* A
3 e% m6 R2 m+ z% z1 b网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型
" q, Y2 U7 M; U# Display training progress by printing a single dot for each completed epoch.
2 d' V, e |0 e* W' x" \* Zprint_dot_callback <- callback_lambda(0 x, A9 }( q0 ~! ~0 u, @: e
on_epoch_end = function(epoch, logs) {
$ O; C9 o: K' V" O6 a if (epoch %% 80 == 0) cat("\n")4 G/ {1 k/ o- o4 E1 c+ t# z
cat(".")$ h. C/ D7 n; Y3 I' v6 c
}
$ M/ v9 V* Z" E$ @: T; H)
* A% [0 a2 e; H. v% j8 k( J E" ]6 p z F
epochs <- 500
' p1 h( g, ]4 k+ q1 Z; m. v; N$ h: |, M' D+ ]9 L
# Fit the model and store training stats4 K9 I& w. b5 E; X
history <- model %>% fit(
0 A/ ]! B& ?% y2 \. E1 T C train_data,
4 J8 @% q' l6 A# ?0 S train_labels,. X; o" w8 L% R8 K) q6 b( H
epochs = epochs,3 e0 x# i/ m$ x) k9 d
validation_split = 0.2,! _1 j+ z+ N5 ^9 t
verbose = 0,
J0 t! X7 L* G* I: ^) R! ^ callbacks = list(print_dot_callback)% K# P* G/ R2 l" \9 L6 L. k2 n. R
)2 L) Q7 F& _: K6 i& o. G2 X8 R
9 V; p! {, ~2 D" k
library(ggplot2)& Z) p+ J7 a& N2 n
) h9 N8 i! S b( L, B. nplot(history, metrics = "mean_absolute_error", smooth = FALSE) +
0 @/ E$ H9 ]5 c( c* z3 k; g coord_cartesian(ylim = c(0, 5))
8 H" f6 m( J# L2 R3 b
/ X: `. `, M" P; a2 `![]()
( f, A Z$ N$ J/ u V3 w N3 R* p6 u5 M4 a, p" E' q
小结
4 x: e7 H' ]. Z; R1 t# U1)回归常用的损失函数是均方误差(MSE)。
9 D3 r3 D" A( ~( J* d0 f8 M* V5 a1 s2)常见的回归指标是平均绝对误差(MAE)。( k) G' B. p1 U5 w
3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。
5 R. E8 E5 N" v$ p% G4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。. R* ~- N3 _* K9 B
! M5 m: i7 {9 I5 ], u8 a. j0 v) g* B. }7 E
& u. n* N7 R' W |