预测房价:回归问题——R语言
4 u5 S# X4 k" i0 v, y在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。! P! P* u, V3 P# I0 ^, c
. S$ K c. e6 B" W0 ]; F
问题描述* E& o* ^0 g/ E) e, h
我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。$ c: Q& ~5 Y2 w- F! v
本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。: r. k3 S" U5 `
数据特征:4 N6 S' T; x/ G; o: ~# [
人均犯罪率。
. Y% f9 U' [* N* s |占地面积超过25,000平方英尺的住宅用地比例。7 O7 e2 L( f1 h- A4 ~, A
每个城镇非零售业务的比例。
( b# a& K* D; z' M7 ECharles River虚拟变量(如果管道限制河流则= 1;否则为0)。; }. f. u1 l( C( A# P9 C; R4 l a: V8 ?
一氧化氮浓度(每千万份)。1 q# N l3 S8 C9 |! h
每栋住宅的平均房间数。1 A) Z: k l5 a& P7 O
1940年以前建造的自住单位比例。
7 u) }7 |. x# |7 o# F, f8 c$ F+ T到波士顿五个就业中心的加权距离。
o: g( a% z" |6 [# ~径向高速公路的可达性指数。! m5 m! I7 B4 _ u- p5 Q
每10,000美元的全额物业税率。5 P* N2 o: n8 C: K' @9 y5 @* N
城镇的学生与教师比例。: c+ L6 s* q" V4 d) f: B8 Y# V
1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。
9 U- y, c' Y0 @人口比例较低的百分比。
, G* h" `' P+ I/ s# D* m1. 加载波士顿房价数据
6 a8 N' [7 a8 M7 x& G+ X0 ] y; Z- Elibrary(keras)
% Z X/ L: c8 ]
6 c7 ]. H+ ^* ?4 N9 I5 ]boston_housing <- dataset_boston_housing()
o p, `% I5 i& C- @* M* b7 O+ l
) b5 ?3 X% N( b4 ^7 |- M' |c(train_data, train_labels) %<-% boston_housing$train& D2 d- F( p1 L
c(test_data, test_labels) %<-% boston_housing$test
: o. K% N C: X& ~2 P, z+ E: ~& g
$ c) Y% [# C/ S4 T每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。
6 D+ X. x5 u; D3 a# Test data is *not* used when calculating the mean and std.
0 C* _7 C: @5 S5 O% J
* j0 b, W: P$ I# Normalize training data
2 ^0 a+ u+ V; V i6 ?: }9 ntrain_data <- scale(train_data)
% I& `$ O H/ A' X2 n" {* E+ f7 ?: q& @8 s
# Use means and standard deviations from training set to normalize test set6 n. I' I2 p0 r# J3 M) g" _/ Y
col_means_train <- attr(train_data, "scaled:center") / L( |. a, _% }- ]4 T
col_stddevs_train <- attr(train_data, "scaled:scale")
9 T" I3 _/ s) {' R! ]test_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)
8 R* U" O! L5 l, K) _" b5 y6 x. [0 k
3. 构建网络创建模型
4 {6 ~, m6 Q2 ~build_model <- function() {
8 e D% q4 M4 h
1 q7 Q. b, J4 k' \$ s6 ] model <- keras_model_sequential() %>%
) H2 ~/ J* u/ c layer_dense(units = 64, activation = "relu",5 i1 V) u- H5 F/ G7 E1 O$ T
input_shape = dim(train_data)[2]) %>%% T$ `) B. z" F1 R/ _
layer_dense(units = 64, activation = "relu") %>%- h, e& M8 P% Y7 h: A# C
layer_dense(units = 1); V, e' Y8 H4 f0 b' N
9 h& [5 Y, E9 z% z' P3 T model %>% compile(7 J, h2 N' t% s8 b( U
loss = "mse",
, J2 P+ C3 X1 J7 t0 ?: n. N$ ^ f optimizer = optimizer_rmsprop(),9 @5 D0 |. B3 W
metrics = list("mean_absolute_error")
9 @" L. h6 ~0 c& V )
- K. z8 J9 s( k4 r/ T k3 f& \' r+ Y- K0 Z/ b
model T/ L) F7 l4 f* k. g% `7 q1 A
}
& Z. ^, }7 L2 j4 q# M7 `% l) ]/ u' _7 ]3 }: f: W
model <- build_model()) g7 Q; w+ c6 P: ]3 T3 e% r4 J
model %>% summary()
t0 S0 s. s' f* I% c
/ g7 X! ~' |* U0 z+ d T网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型
" w' S4 L f, K5 k+ w# Display training progress by printing a single dot for each completed epoch.9 l2 ~! A5 \- s* ~
print_dot_callback <- callback_lambda(8 N# A- S: ~$ f& T/ u6 T& K
on_epoch_end = function(epoch, logs) {
% G$ E- n% Q! H z( J if (epoch %% 80 == 0) cat("\n"). k0 v1 G& J7 J$ \7 o
cat("."), u, m0 Q7 |7 L7 w/ i
}
7 ?) ~' i" K! ?: j)
. r G, o- i8 _, q" ~
! N, |' A/ P& s& `" A" P- oepochs <- 500) z, l0 J) x5 R7 [8 W
9 q, `* }" B3 U$ Z) v# Fit the model and store training stats" k4 t Q7 ]+ k" `
history <- model %>% fit() W) W& K2 U7 [& i! t$ [ G
train_data,
: y+ [* N& [$ m5 S, Q D; v train_labels,
) g9 Q4 ]7 R! g1 v+ D1 G) H* H/ m epochs = epochs,
$ \) V6 m: T! S+ T% e9 } validation_split = 0.2,5 h' K$ g. S& j# q( i+ _
verbose = 0,
# D. S+ n1 P2 y2 W callbacks = list(print_dot_callback)
+ e; {1 f+ u+ X6 C, O)
6 \+ Y# z8 r/ u3 R! _
+ ~/ J5 }# S4 a2 a& |* C( }library(ggplot2)& n. n- @. |7 w/ E. Z- p; k7 ?
% f, l9 {6 m& u* ^# w5 H0 \
plot(history, metrics = "mean_absolute_error", smooth = FALSE) +
! J" e; {/ |% v& a6 } coord_cartesian(ylim = c(0, 5))
# }: ^; C# L# \8 i C+ a6 P6 r- f6 t x
![]()
5 j* u z) D% q: Z9 O; Z' m+ H7 Q# p* k+ R# i4 D$ F
小结
- e" H+ }0 \8 y1)回归常用的损失函数是均方误差(MSE)。
, b4 k! E8 J- s% R+ K5 g1 c ~2)常见的回归指标是平均绝对误差(MAE)。
b8 r. i( j+ S! o3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。* o( j6 r* e+ R$ x1 F
4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。+ ~6 L( k+ {6 V/ s2 A
3 W8 n2 Z6 ?4 B: L
6 A. Y, B! O$ M4 t4 B1 O8 G1 ^* E6 j
; H/ z8 a* P$ z4 o) p
|