预测房价:回归问题——R语言
8 m- ~$ p; q$ _! A+ k* _2 D8 C在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。 W$ X2 j7 F: p
+ B$ W/ D# h O5 H7 G
问题描述' c |7 z9 A/ Q- M
我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。
& Y6 r) z! _+ l: w0 Q$ K5 E' U& R本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。# y8 V6 b. c# a3 I$ v0 L# e. M
数据特征:
; E& R' f4 |. B人均犯罪率。& l7 J% w2 z6 f6 b/ Y
占地面积超过25,000平方英尺的住宅用地比例。: [" y0 s9 P5 r2 G) [( Y3 [
每个城镇非零售业务的比例。' z8 Y8 F( V( g% d" _2 t* U! B! s
Charles River虚拟变量(如果管道限制河流则= 1;否则为0)。
2 b$ E K+ F" Q. `4 ~5 m一氧化氮浓度(每千万份)。$ ~( e( d9 s, }% F# Y
每栋住宅的平均房间数。- h% ~4 C( G* @' B4 W* D1 @9 |% k8 @ t
1940年以前建造的自住单位比例。
Y7 o |2 ]$ W- J3 k到波士顿五个就业中心的加权距离。
1 M: ?' S6 S! n径向高速公路的可达性指数。
, [& _" y1 k( t每10,000美元的全额物业税率。$ Z# N: K* \( e' d- K- w! c
城镇的学生与教师比例。& m( p H7 L* Z5 c, E( T& V4 K
1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。
' _# ~# d# r7 i* w人口比例较低的百分比。
8 X$ _3 t5 a8 j1. 加载波士顿房价数据1 L5 ] a4 \+ o
library(keras)
1 S$ f$ q+ g9 v& e+ A6 F" {3 x" a- O& c$ Y& ]
boston_housing <- dataset_boston_housing()4 r2 k8 c5 C4 A: ~/ F& ^
- E& P( J1 c1 j( q& w; s$ tc(train_data, train_labels) %<-% boston_housing$train
; u6 v: S4 W, B) \) w- x$ Hc(test_data, test_labels) %<-% boston_housing$test; U# f1 u: e5 G1 }+ A
# r, `% ? d0 x6 J
每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。
. }/ l$ ]) G2 k+ f5 u% w5 I1 S# Test data is *not* used when calculating the mean and std.% B& Y2 G1 h8 t, C z# Z3 W
$ M1 d: X# B2 m3 ?0 m9 Z ?: v# Normalize training data- X) o) t% ?: H6 d# o+ L+ @
train_data <- scale(train_data)
- S' r, ~* w: C
- v/ V; S- I) k/ l( C) h# Use means and standard deviations from training set to normalize test set
5 L! A5 _. i1 s8 B( m4 @col_means_train <- attr(train_data, "scaled:center")
2 e& {' Y) p- H+ C6 o \col_stddevs_train <- attr(train_data, "scaled:scale")
1 W$ P v9 j" h0 Q B3 W; ~! Ftest_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)4 \. u# B. L& A* d$ m: X
0 G& V$ _) o ^- E! h& @
3. 构建网络创建模型 - a( P8 v: |% o+ Z8 f# [( N
build_model <- function() {
3 i1 |+ p- m$ `& [1 w$ ]+ N6 Y0 ^, Z# v
model <- keras_model_sequential() %>%4 F# j- j# w; B- _- ?- q
layer_dense(units = 64, activation = "relu",) w+ p; V" Q' X3 G& E
input_shape = dim(train_data)[2]) %>%
9 O* o4 d. T2 c4 s layer_dense(units = 64, activation = "relu") %>%
- n6 H) |* ?# f+ S+ a layer_dense(units = 1)
7 d( S, H$ U0 G; F& b: b! X1 M* `- V5 P5 A* h! v
model %>% compile(
; Q N, B% _+ } C+ [ loss = "mse",
' k- _9 y) @. x$ x* R optimizer = optimizer_rmsprop(),1 F; Y) {4 {: [% I" G+ Y5 Z; J
metrics = list("mean_absolute_error")/ g, J9 m! x6 o
), y8 v8 a6 x/ z4 V4 k
4 o6 s6 \/ Z. I1 _! k
model
9 e, r+ y/ L8 x' I}. |) t3 L! C& s* X# X) T/ l' B( t
# B1 z0 Q" `* Y- _3 f: |
model <- build_model()2 w, S4 m+ z: c9 o. S1 _
model %>% summary()
, T1 s. `) P! f# }0 ^6 X8 g5 B8 ]: Y+ y
网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型& R; p# q* K4 J4 o2 E. ~; F' v
# Display training progress by printing a single dot for each completed epoch.
# g) Y: Z0 X& z+ m" uprint_dot_callback <- callback_lambda(+ D9 n! p' ]: K
on_epoch_end = function(epoch, logs) {: A7 x* E8 ]1 h: n6 ]
if (epoch %% 80 == 0) cat("\n")
% A% a' p! o; G* Y8 g( ^ cat(".")8 ?( f* L& e7 o4 M" h6 m
}. u1 u5 [' `, B# R' W0 C2 s' Q
) : `0 i6 v1 N9 f& r/ q4 ]
$ P5 h: M5 t* q; Nepochs <- 500
+ ~+ r) @3 a$ K( }$ X4 U. B5 Y- ~2 G' {
# Fit the model and store training stats* t! d, W& Q8 t* m: j6 @0 C6 x
history <- model %>% fit(# ]: ~/ ^) l# P) _; t! V
train_data,) o7 v) U8 l" s/ \- W) v1 z
train_labels,
. \ B6 ~$ e& f% h# r" A" E epochs = epochs,9 r1 n# S4 {' j, o" O
validation_split = 0.2,' Z- m q! i1 M Y; |& d
verbose = 0,
$ X7 A6 P' Y1 J callbacks = list(print_dot_callback)
* x: h3 s2 F' a# D)
- U- P" s# A2 z& ^
+ e/ v0 ^) C2 |( ?% ^library(ggplot2)
7 L! e+ m& W. Z6 l& O z/ Z; \/ H( |' C
plot(history, metrics = "mean_absolute_error", smooth = FALSE) +
% W6 T8 m5 i2 K3 A! m$ c7 c/ u coord_cartesian(ylim = c(0, 5))# R n: Q( C2 X/ z. Y
, X0 v2 {8 p8 n+ z5 H2 I
9 k' V% P/ G. }- c' a
3 M; C( c& A3 I/ d, m' ^- C小结; A: F. s, i6 {! A
1)回归常用的损失函数是均方误差(MSE)。; b5 K: r% ?5 m. U1 c& p5 s
2)常见的回归指标是平均绝对误差(MAE)。
0 b4 S9 X9 W, z' s7 d4 s3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。
/ ^9 R- F; I& q6 ^2 I# o" v4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。# Q3 h' o b$ T+ b' e- L- A
: Y' H5 w4 ~2 t( v8 B9 ]8 K4 W- M g, d' s# G( t% w+ Z
3 f7 z$ }: X! U& }- ]" l |