预测房价:回归问题——R语言- N O1 X8 I: y, j( u
在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。+ K# h/ p9 Y4 U5 y
+ q- _) [8 J9 B! }4 }问题描述3 P% `/ Y3 a$ p( d
我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。
# M2 E+ A$ [+ t. ?9 M S* f0 ?4 Y, F本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。% I% K5 e+ i- `2 ?
数据特征:
) o" x0 s/ P& f& \$ `1 K# n" X' A人均犯罪率。
2 j4 c3 \8 n7 K1 e- F" B: {) D占地面积超过25,000平方英尺的住宅用地比例。
3 F+ o4 t5 m7 F1 z$ Y每个城镇非零售业务的比例。' a# W3 u1 G( u) y |
Charles River虚拟变量(如果管道限制河流则= 1;否则为0)。
; M: }1 P3 K1 D3 l3 q2 Q2 t一氧化氮浓度(每千万份)。
# P! X0 T7 t1 u" V* |9 h每栋住宅的平均房间数。
0 z& A8 _4 }0 ~1 U1940年以前建造的自住单位比例。7 g. W9 j( z9 b2 [3 d2 r4 i
到波士顿五个就业中心的加权距离。 j6 V* a/ Y# _2 e% H( S3 I/ G
径向高速公路的可达性指数。
; F2 ^- E3 _, T+ V, ?每10,000美元的全额物业税率。( Q/ j2 f" @) D J- n
城镇的学生与教师比例。4 e% Y% z/ n4 d4 y: F1 ^! p% E
1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。5 Q' Y% ^- ], Y. S" `
人口比例较低的百分比。
4 W8 M' X2 A( |. H# K" `1. 加载波士顿房价数据* |9 @3 d8 l- ^( H5 O+ o# w
library(keras)3 J7 S& T' ]6 v
+ I- O2 `: R! _6 b: W- wboston_housing <- dataset_boston_housing(); w6 P) l' b0 |$ Q" s% I: }
5 u2 P" E9 [( yc(train_data, train_labels) %<-% boston_housing$train
% ]" j7 M* q; |2 dc(test_data, test_labels) %<-% boston_housing$test3 p% ^" ` {$ i! \* Q
% D) v4 l j, U. q; G" o+ ^
每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。 0 l3 T1 Z3 p7 [2 E
# Test data is *not* used when calculating the mean and std.; @8 z0 a1 @: g [1 |9 S
z& I! k6 M, L- j- z( L# Normalize training data: D3 v( ~4 R! J! t
train_data <- scale(train_data)
: F6 c" y1 D* G+ u( O) a9 ?' T. b$ U7 N$ {' L
# Use means and standard deviations from training set to normalize test set: L9 w3 r, N8 N' e
col_means_train <- attr(train_data, "scaled:center")
1 y( p4 e8 G6 a/ rcol_stddevs_train <- attr(train_data, "scaled:scale")
( x2 G. k$ a9 u% B: D* Jtest_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)
: r# p. n1 R) a( B$ ]5 l8 M' }
3 M; D- Q: d0 N( N3. 构建网络创建模型 3 H* ?' F7 x! {: h9 {
build_model <- function() {+ X, `" r+ e1 Z) h
! `% K, o$ h; E6 C$ p
model <- keras_model_sequential() %>%7 C; h& Q, I7 y4 q L
layer_dense(units = 64, activation = "relu",
5 s* a( z5 k6 I$ w& ` n input_shape = dim(train_data)[2]) %>%
; i% X& M* S; M* M( u layer_dense(units = 64, activation = "relu") %>%
4 k/ g' k H0 O2 s, Q E3 o layer_dense(units = 1)2 U& ]+ b/ A# V @7 a. Z. ]
# [1 r L u0 v* K: D+ N
model %>% compile(3 E( r) F+ Z1 }) F
loss = "mse",) I0 O" j0 ^7 G$ r
optimizer = optimizer_rmsprop(),6 b) W% G1 z, A; X) j" ~
metrics = list("mean_absolute_error")
* z# Y, Q. C* E0 p6 ]5 ? )
2 p; L; Y" {( E, L6 H, x
# U+ `7 M) }. R( d, R model o0 x: ` f. U3 L# G4 `
}; J& a- @3 k/ z9 y, K
9 d7 T3 v3 e% m2 F* C2 |; {0 Ymodel <- build_model(), x" k$ | A6 p) M* _1 b o0 H
model %>% summary()9 a6 {0 W# A7 }) R0 b; c
% V7 }+ ~- U6 T, {
网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型
; O/ K& Q* N: v/ r2 ~" U: j' p# Display training progress by printing a single dot for each completed epoch.& P3 r4 n% H. S! Y" n$ l
print_dot_callback <- callback_lambda(
% y; C6 f/ R8 I& R7 Z3 P; G$ B on_epoch_end = function(epoch, logs) {. \, o8 F* G. K% ?! ^9 v
if (epoch %% 80 == 0) cat("\n"); w. s: W7 Z0 h+ R
cat("."). i# R* G5 ]9 z; B
}
$ ?; R* o9 u- l+ P3 p j: ~5 O+ H: x0 W; V)
4 Y9 }/ D3 g+ N3 E8 i8 e7 Z2 s I
; K" y: e; z+ h8 h1 V. K4 x/ \epochs <- 500/ g A# S" x: \+ S2 T7 s
( U3 h. d C2 E% E& Q# Fit the model and store training stats
. f' p( E% a2 d0 X* p+ n dhistory <- model %>% fit(
\; {8 p5 x0 A- M; q) Z- R: V train_data,
! ^1 m* ]- _. `% x4 Y train_labels,3 K" f- c6 ]4 V& f5 g; e
epochs = epochs,
2 Y9 K4 y; n' Z validation_split = 0.2,/ [. R; A' Q D
verbose = 0,
- ~" ]6 [& J- E' x0 g! s0 l$ [ callbacks = list(print_dot_callback)
- C( Z0 }, A9 e- b, a)
2 I) @6 F7 q# I& k5 s9 u' O: H) t$ ^7 a
library(ggplot2)
" {. ?( u1 V" }: b
5 C$ o2 O, i& O/ P+ T+ h" x4 kplot(history, metrics = "mean_absolute_error", smooth = FALSE) +
+ ^3 |4 ]' h* h coord_cartesian(ylim = c(0, 5))
# V' n( m% v( L% ]/ A; z0 [- K, ]4 X, A
: K* M. l2 F, C) o% a
& R! U3 G; [, R7 P) z- Q) E( I; c% I
小结
3 @, E0 a' x3 d2 {) Q1)回归常用的损失函数是均方误差(MSE)。 ?- W5 S# f4 k' u
2)常见的回归指标是平均绝对误差(MAE)。
9 @ F2 X/ h9 D/ b. R. y3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。
$ k* j( \: m7 L& p1 c" V4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。
* ~; c) c) X9 a3 B0 W8 c/ d' `( \' s( |( M4 M( C t+ Z
' e# W% c" G) G) m+ [. j
}+ `- D% V. a, f1 l4 v$ G
|