预测房价:回归问题——R语言
& w7 y$ ?0 M- h! W7 F$ X$ U/ O在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。
6 V& W- M8 x# x
: K& _1 O/ ]/ @0 L问题描述7 O1 Q3 E9 ]* \- M( g
我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。
# F9 m7 T' G3 Q7 ^( n本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。- m& h' I, l. K. Q' A( w
数据特征:0 J3 X8 j+ S, c3 ]! t
人均犯罪率。
$ f3 \& Y2 M0 b6 @占地面积超过25,000平方英尺的住宅用地比例。
6 \1 I- f$ s- t每个城镇非零售业务的比例。
6 O; a8 {: y) zCharles River虚拟变量(如果管道限制河流则= 1;否则为0)。
$ ~7 m4 ~# h: l一氧化氮浓度(每千万份)。4 ^3 _% @% s5 F+ Y8 b! p- [
每栋住宅的平均房间数。
4 F8 G% i# @- Q! o' O. O$ R/ S# }; R1940年以前建造的自住单位比例。; ^& a% Q" ~! t1 q! |( y' n
到波士顿五个就业中心的加权距离。
; T h0 ^- z+ ^% Q' H1 I" G4 g5 Q径向高速公路的可达性指数。. a" s0 o2 f/ z. c# l# z
每10,000美元的全额物业税率。. k4 O8 F; Y: G4 e- F) o* E7 L
城镇的学生与教师比例。3 k1 Y: {) M& @" W4 T
1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。
7 b! I) x; m: G$ k: ^. l人口比例较低的百分比。
l& z4 ~ |2 x) Z1. 加载波士顿房价数据% e- {- [! \* ?( D6 F- z
library(keras)
* V* T$ Y- z8 p/ y( K. V
1 D6 c, y+ u6 p' mboston_housing <- dataset_boston_housing()
1 B* A V5 j) k1 W! _4 E; X) N7 c7 K: L' ^" x7 t4 F* d# |0 x/ {+ S
c(train_data, train_labels) %<-% boston_housing$train
& `0 t# O% f) G: N1 }, W1 nc(test_data, test_labels) %<-% boston_housing$test4 F% N+ f+ o+ N
% V4 i' w" Z% r' E L
每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。 . {7 M: [! @: L" ]$ W. R" h/ M. \
# Test data is *not* used when calculating the mean and std.
8 `3 \2 P/ M# g( Y; G+ B
' y# v# ^0 I& [( Q# Normalize training data7 x& t4 \2 \6 E1 J
train_data <- scale(train_data) 9 N0 _) `6 `( c/ O
/ _* W, P1 b5 [! d
# Use means and standard deviations from training set to normalize test set! H' f2 ^8 f; N
col_means_train <- attr(train_data, "scaled:center") # F& V- I7 x2 g) @. @
col_stddevs_train <- attr(train_data, "scaled:scale")
3 ~- ?% x' ~4 m8 ~% J' ? p2 ttest_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)
7 A- X e+ }. R
2 g8 z/ F: J( W8 |9 a3. 构建网络创建模型
1 `, {$ _1 p/ Vbuild_model <- function() {
- g( ^+ Z8 \9 d. y, R! R4 S$ e
model <- keras_model_sequential() %>%( C3 p# M! F% W) x5 B* t
layer_dense(units = 64, activation = "relu",& `8 U- E* X9 E5 i9 B( H" S% V0 T: ], U
input_shape = dim(train_data)[2]) %>%
% ?8 o# g3 _; q, W& q layer_dense(units = 64, activation = "relu") %>%
# Y' u! T1 z3 Y layer_dense(units = 1)( J8 _( X0 n( d' E0 }+ Q
! X6 C, Y/ }9 V& l$ [8 B+ q
model %>% compile(
+ y" d, M& M+ ^& o: m loss = "mse",
- Z/ F% t" g* S* n v r8 Z optimizer = optimizer_rmsprop(),9 I6 W! {2 m. ]# }3 w/ R
metrics = list("mean_absolute_error")
. F5 {$ y7 e6 H' Q: }+ i+ P )5 m' u8 T4 N$ [7 P( V3 N) m
) M3 Y+ I+ P) y5 q
model
) u9 T# G% s; a}( O8 ~- e! Q! h
4 b7 ]+ {7 O$ w9 D2 O
model <- build_model()
" D6 c* b* @4 P8 Q2 r( Xmodel %>% summary()
" o& }: [0 P! j' Y, c) o% a7 ~, \
网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型0 V% e! P0 _" Q& T
# Display training progress by printing a single dot for each completed epoch.
4 P% L1 \. ^- @print_dot_callback <- callback_lambda(; Q6 a1 ]* y; e9 p
on_epoch_end = function(epoch, logs) {4 p' A* |* {6 J) X
if (epoch %% 80 == 0) cat("\n") D9 \' }" f0 i) O
cat(".")$ M% H) W* q2 @
}) K7 F% B. d" F- [2 W
)
0 X7 D; e0 k' w9 _7 D: ?9 p4 w: e% ^$ O9 Z
epochs <- 500
# Q; ?6 y9 O' }4 _6 r" W. w% s6 I9 C0 c7 I
# Fit the model and store training stats
/ J8 w- r, j6 T/ L" N6 m$ Ghistory <- model %>% fit(8 |; H6 P/ ~ b! W# t+ z4 ?! H3 I
train_data,
' F1 A% _) V3 Y- G7 J0 o6 I; k train_labels,5 J0 u& p3 N3 ~- a
epochs = epochs, @) w# A6 l1 u9 ?- o% L; n
validation_split = 0.2,
1 v* H5 M9 V" w6 a verbose = 0,0 f/ M1 M2 |0 M" x. C
callbacks = list(print_dot_callback)
) \% x. ~/ v% f5 R* q)
G+ y1 b$ U0 ?/ s0 q3 R; I3 O G G& h9 F* u) n
library(ggplot2)! |* ]9 ]' E1 ^1 ^5 P* ~
8 j5 J! W% K) e& v: ^plot(history, metrics = "mean_absolute_error", smooth = FALSE) +% [% K6 b* G# p+ v
coord_cartesian(ylim = c(0, 5))& A* g! |8 ~8 r0 T+ t% n2 _
8 R9 @; H' r, p3 c: ]+ Y4 `7 `![]()
* C/ s# ]- A: q6 D: y" U- }' N8 M/ F( `4 w0 o* p( A6 b4 Z
小结
8 n" q5 t8 Z# D! h4 ]$ ]1)回归常用的损失函数是均方误差(MSE)。, l; k. X# d, l2 S k+ R
2)常见的回归指标是平均绝对误差(MAE)。
- x7 {- S S. g+ A; @- \! Y3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。" s! O6 Q: b# C i9 o
4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。
" C4 `6 [% d+ B9 N; m3 s8 }9 v
9 L* d& W8 M& |8 B( b/ v2 N2 n2 G2 y, i4 |7 u- Y3 E
9 U2 W9 C- M! I+ n7 J |