预测房价:回归问题——R语言; R; v3 o% K+ \
在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。9 b; Z4 L1 \1 y; C- E2 S# K
/ K4 g- U! E/ W5 s问题描述
& {& ^/ d- Z. {( E& y我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。2 j0 E5 F) z6 M8 K$ F" {( a8 T8 Q
本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。, ~* f1 h/ o3 k) A. I+ t: B+ s5 _ G
数据特征:
8 S( O, m3 a% I ]+ }- ~人均犯罪率。
6 v2 L; g( h4 w9 m( a5 ^! N6 r# g占地面积超过25,000平方英尺的住宅用地比例。4 |3 b. t5 }. j% v- t9 W
每个城镇非零售业务的比例。
9 |! T& m. b% UCharles River虚拟变量(如果管道限制河流则= 1;否则为0)。3 S6 b) p( z0 L1 w- X& M; A
一氧化氮浓度(每千万份)。% D) p& p9 q+ n& Z
每栋住宅的平均房间数。
/ N+ ]- |/ r( i+ I# Z1940年以前建造的自住单位比例。
; b9 d: F( Q# x- e' s5 h5 U1 T到波士顿五个就业中心的加权距离。5 {/ h: b8 }. B% u" P, k- A% |1 E! d
径向高速公路的可达性指数。2 S3 {4 ~. _1 l; b! T2 O
每10,000美元的全额物业税率。
) A2 E! o' \- _: D城镇的学生与教师比例。
" c! n5 ]- d+ H1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。
) s9 u; @# T- h2 w人口比例较低的百分比。
4 n6 B( P0 W2 E" y# M! ^3 `1. 加载波士顿房价数据
. C: b' T7 y8 n) i$ F& @library(keras)" h& ~ m9 h8 o5 o3 i
' @% \. }/ h3 A8 D3 Zboston_housing <- dataset_boston_housing()7 ?1 C0 s0 l( l' O2 T+ Q X$ x
. N( T; X! s+ ?# f, w: mc(train_data, train_labels) %<-% boston_housing$train
) o: [3 h( l( O* ^, J" K* _6 D' rc(test_data, test_labels) %<-% boston_housing$test
2 a8 c; O& h8 Y. m
. u- v' C6 ~/ B; P- r0 g! Y' q每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。 - C/ n5 ^: d2 y9 O2 r# P* X
# Test data is *not* used when calculating the mean and std.
& E: d/ W, ~+ X# v% F+ |' X
0 e# P' `/ Z$ X# Normalize training data
& n' ^( V+ ?2 y3 W, h" A$ m% ttrain_data <- scale(train_data)
+ }) M* \% `7 @( O i. h& n. @
! O" g: ]& G1 _# Use means and standard deviations from training set to normalize test set4 X$ E& ?8 h: l$ V! K+ g& d c4 q9 ^
col_means_train <- attr(train_data, "scaled:center") ' M& T" i' o$ m, v
col_stddevs_train <- attr(train_data, "scaled:scale")% }, y* ~' ?' T5 g2 f; ]* t% |* v- p0 N
test_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)
! \0 d! q: V! K7 I" n4 j. |# E5 f# H- [: D
3. 构建网络创建模型 Q# g3 a+ N4 q" h7 z+ r
build_model <- function() {
5 F" q, [# v; g }0 Y" X
9 X4 X. W7 {% c. M p0 }0 q R model <- keras_model_sequential() %>%9 k+ E0 j- e, X5 y) w
layer_dense(units = 64, activation = "relu",
# Z! J* I* P7 r, ^, B* A1 r input_shape = dim(train_data)[2]) %>%$ E: w1 v* \( _+ ]
layer_dense(units = 64, activation = "relu") %>%4 G) |- r- f" J5 a L
layer_dense(units = 1)
: E3 \! }' `+ |1 r6 E
9 t' E; g% i/ e( ` model %>% compile(
3 ~5 u2 p9 T! W! I- ` loss = "mse",
# @# W# k- h% |& p optimizer = optimizer_rmsprop(),
+ o$ ?" T7 m( F) X4 {/ K metrics = list("mean_absolute_error")7 ], `& U' s2 i/ A, j
)
1 O/ p' X# d9 k0 ^8 Z& c: ?3 Q! X9 T
model
8 S+ r' _8 p: i$ \0 S& _" }}9 G! K7 C+ _" M+ D
! E$ `; q- y8 G# ?: I$ Emodel <- build_model()2 B6 q0 [% e' B9 t# m
model %>% summary()
' i! h& {0 z2 j7 m( E1 I' n
4 q9 Z; C# B* U& d, q3 E$ u网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型
' L! v0 F( q& ~# Display training progress by printing a single dot for each completed epoch.2 v# T! q& k4 M$ O
print_dot_callback <- callback_lambda(
* G' a) ?* f' I' U. V$ s4 v on_epoch_end = function(epoch, logs) {
. r" D8 T: g+ A' [+ B6 E! z if (epoch %% 80 == 0) cat("\n")
0 B* p- }) r8 @0 p& l cat(".")2 L/ R- I0 ?3 H9 ?9 p& t+ H* O
}
3 o4 R) S8 k" O2 U. Z+ ?9 h)
' {# B, t/ u! @" E4 {9 V
# b+ _- P$ a7 ~" C4 s5 M4 nepochs <- 500! r( w0 }. p* H' [, Q; J9 Y
( P8 a h7 B+ q i0 J( L! t( F$ R# Fit the model and store training stats4 k/ a5 S- w8 V& \4 U/ Q3 ?
history <- model %>% fit(6 W- D3 x; _$ i! H( ^& u- V& B, r
train_data,
! ^5 E/ v" G6 w1 G8 W1 l train_labels,
, N! \( _) i7 S0 {" M! D ]4 d4 a5 @ epochs = epochs,. s& y) m- q+ j: u: s
validation_split = 0.2,' O5 B, ]9 d: M7 F& k$ R; o
verbose = 0,' ]+ p; k" E/ ?
callbacks = list(print_dot_callback)
9 R7 [- C0 V; i( I( N)* p0 U# h _$ z6 \. _
* [' E) [% o' j/ F Vlibrary(ggplot2)! N! c9 @9 |1 ^ d& X# U
7 k# W( s& D' U5 h1 F
plot(history, metrics = "mean_absolute_error", smooth = FALSE) +
, M6 Z3 a5 w/ }! i; r. E coord_cartesian(ylim = c(0, 5))7 Q- Q `2 V6 E. o, q1 `1 a
* f! `2 o! v9 y$ s0 E 3 Z+ n9 k# j* A/ }" K
. _9 Z0 i. ?" }7 h3 L$ l/ Z小结# z" ?) n" n8 t
1)回归常用的损失函数是均方误差(MSE)。" k, U& W+ Y7 r/ [( p/ {* q
2)常见的回归指标是平均绝对误差(MAE)。3 h4 r/ K% y6 @& r, h9 o
3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。
# q S) T0 ]$ h! ~4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。1 v! t' C' N B
8 f& ^7 W& E* p( h1 w E: B0 {0 [
% v2 O* a0 u1 s# a* ?
7 a9 k; Q. I3 ~4 K, n w |