预测房价:回归问题——R语言! x" s# G+ Q9 Z, q
在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。: ^ s5 O( o/ c7 E$ R3 s+ [; M
2 O% e1 e+ Q" Q* q) x, p( B
问题描述
1 V7 M U) i" P1 S我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。* E/ t0 `3 _% U& [- i- j
本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。
: n8 @; O+ F; D7 [ N( I Q) `数据特征:
7 u; u. {! r0 M ?人均犯罪率。6 `1 Z# t/ }4 A0 d- h- l' X6 [
占地面积超过25,000平方英尺的住宅用地比例。; }- w" k1 W* d' N# F
每个城镇非零售业务的比例。' i! ?% X$ I" ]; H/ R7 i/ _& w
Charles River虚拟变量(如果管道限制河流则= 1;否则为0)。% L7 f6 Z% ~- ?# [* a+ f4 B6 l
一氧化氮浓度(每千万份)。
; K$ ?8 u) i. c0 [" _每栋住宅的平均房间数。
- e8 v9 V7 G% ^% @2 B j1940年以前建造的自住单位比例。
7 M# l, [% a$ P, f- o: J到波士顿五个就业中心的加权距离。
" g9 ~; H& M1 C! s径向高速公路的可达性指数。0 j' W1 I# `8 C
每10,000美元的全额物业税率。4 S4 O* s6 Y% N0 ^
城镇的学生与教师比例。$ L+ G0 u$ `& f$ `( K
1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。
5 U3 f+ [: f+ A$ q人口比例较低的百分比。) k: r" r* V4 m& Q. {; R- \
1. 加载波士顿房价数据" C4 X3 i' G/ V: D$ f
library(keras)
3 Z( Y; m! o- \, S3 a7 R+ R4 R8 k' t4 c
boston_housing <- dataset_boston_housing()# n; [9 |& H- X* b" y
% r: {0 ]9 U( m& E6 m5 `8 j& Ac(train_data, train_labels) %<-% boston_housing$train
! o _: I$ Y( A1 @9 m cc(test_data, test_labels) %<-% boston_housing$test
0 K* F' I, Y1 o0 V% T1 c1 x
8 T) |0 ]. X' {2 R每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。 . k4 Q" @9 _+ c2 ]& y
# Test data is *not* used when calculating the mean and std.
- e5 X& s6 j% b# M0 j5 H" o! g
) K2 d( Q6 Z0 k/ s6 }; a4 X# Normalize training data
3 [7 h4 o% w- b, _9 Ntrain_data <- scale(train_data)
, ^, M* `' B! m( E: ^- z; ]
H8 C+ |8 E* g H/ D2 h# Use means and standard deviations from training set to normalize test set& g. r" f) _+ k: a( K: j# T6 f: n
col_means_train <- attr(train_data, "scaled:center") - Y: ?% b1 ~, M- J
col_stddevs_train <- attr(train_data, "scaled:scale")
; i3 V6 T: p& w2 V6 u9 `4 U# Utest_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train): I# `& r* ]0 w5 r( G% Z3 H
3 \' J/ R3 P A0 b. Y8 t3 s Q3. 构建网络创建模型
1 [9 T( L/ D' H! W1 ebuild_model <- function() {, w$ R+ L* z2 l' k* H+ n% \8 ~6 X
0 V x$ x, O. ]+ R9 e
model <- keras_model_sequential() %>%
3 U/ L9 x" {! P$ F, r layer_dense(units = 64, activation = "relu",) M0 a/ e; i& Y4 d% m1 `
input_shape = dim(train_data)[2]) %>%9 F2 D5 m, E0 b' Y, }% x% h
layer_dense(units = 64, activation = "relu") %>%
8 e& l, H9 ?. y: x" B layer_dense(units = 1)
) {1 D3 E1 Z1 n+ j% C ~; C% ^9 D6 Z( m D/ u$ g+ _/ {
model %>% compile(! [: {% H" r3 Z
loss = "mse",! D4 {5 z0 o& L: A, l; _4 ^
optimizer = optimizer_rmsprop()," \" v' J; p' F0 n) B: [9 F
metrics = list("mean_absolute_error")- g q. Q: }' Y: U$ C- A$ i
)' h `5 s6 N! m- y
, u& W; ^1 g% J% j u3 ]
model
! ]( ^2 j* c+ l' f6 E}
( q& T x( x1 l# D Y
7 X" Z& _2 H9 t1 g! u* R% Z' J% X( P7 [3 Mmodel <- build_model()
Z( E1 U9 l3 ~model %>% summary()) t6 Q/ n* H" o
# `8 _7 S4 E F8 O, F网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型4 O" ~! `, X* ?/ j* X
# Display training progress by printing a single dot for each completed epoch.
* x B$ q O6 ?8 g4 \print_dot_callback <- callback_lambda(
- t1 [0 N) w) @' l7 o) T) B n* r on_epoch_end = function(epoch, logs) {
* k# p4 a3 ]* E: ^2 U5 {8 A$ d3 V! r" F if (epoch %% 80 == 0) cat("\n"). D- _6 d/ r M8 J1 W2 M
cat(".")
9 k6 }& M' T$ \+ r# p; l6 u, t }
; l$ L9 a' V. g; K K* c N) 3 Q% E U R1 p( {8 V8 J
. f; g+ A/ V! u* wepochs <- 500
3 T- o7 ?7 m- P) n3 ?$ M( @# W0 d) M( t6 r2 p8 G6 X
# Fit the model and store training stats/ o2 p8 c8 w. p8 N$ V" _
history <- model %>% fit(
) w! G% G4 a2 s' v8 r' A train_data,
4 e5 k/ Q% C/ Z/ T6 P4 y train_labels,
" F5 n2 k: G! x/ D1 f' a% F epochs = epochs,3 w: q6 I% C! f4 e
validation_split = 0.2,
7 x! y+ v* M/ i3 I! n6 { verbose = 0,
$ D7 ^* ]( Y- S( m& F callbacks = list(print_dot_callback), {( K$ d/ p; P. |* d0 p
)6 N4 e8 h! { r5 I W- L2 A+ G+ ~- b
5 e6 u. ~% C6 k3 r: X1 Flibrary(ggplot2)
* a$ e+ P& }8 E- a: B: \4 J! j: q* O. H9 r$ b6 B6 E
plot(history, metrics = "mean_absolute_error", smooth = FALSE) +6 s0 M' |" [0 l$ M
coord_cartesian(ylim = c(0, 5))
! N% p6 S: z4 V: {! O: {; I$ V; m) G3 h$ A$ [- {5 R6 k
. C- R' D0 g* C; l+ |
# C# Q8 X {2 W0 v9 ?$ y' y D
小结' c! [0 s X h' P0 K* G2 D
1)回归常用的损失函数是均方误差(MSE)。: K3 q2 F& |* O( @: F* D
2)常见的回归指标是平均绝对误差(MAE)。* z) Z3 U N3 I& b" ^3 K8 N; o# N
3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。
2 c! h& U# ~" N' c$ L1 @; p4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。 c9 f: C& A% L
4 j. n* F; v& V
5 |6 N, r8 e' `6 n5 j# Y& w9 Q" v* S2 q c
|