预测房价:回归问题——R语言$ o7 S' j! i/ y7 N' O# u
在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。
% X) A! x2 \) p; J7 B' z `! L: M" F
问题描述4 v1 ^+ P9 J& p/ f' v" ]5 b
我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。
( h$ x9 |( z i& ? a5 {! z6 L本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。
0 Z% p! Q" \2 K) d+ k: ~! B9 `数据特征:
* r* w9 H8 W4 z2 E人均犯罪率。
, v2 w- b( F% F5 r+ Q/ c占地面积超过25,000平方英尺的住宅用地比例。8 a4 c) U% Y4 F: `( k% [. P
每个城镇非零售业务的比例。, u! `& p: y7 y5 [3 x
Charles River虚拟变量(如果管道限制河流则= 1;否则为0)。& ]# ?2 @) G7 g2 a. J8 H7 @' G
一氧化氮浓度(每千万份)。' X+ N! D2 y8 {& }$ ^ O
每栋住宅的平均房间数。( {5 M- G/ h+ u4 H+ I0 Q1 Y
1940年以前建造的自住单位比例。
* {" [$ G8 j8 A到波士顿五个就业中心的加权距离。
: L6 M u& n# P) V4 u8 V径向高速公路的可达性指数。; p6 |5 ]# t! v* Z, E/ q6 V3 `
每10,000美元的全额物业税率。, c- j. M# t' W& V: G# y* V
城镇的学生与教师比例。8 Y. f- s# B/ x' Q& m3 C; v
1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。# q" E& c5 n; P
人口比例较低的百分比。
$ t. Z2 Q g( e, |/ e1. 加载波士顿房价数据! a! ?! e( r2 S8 }$ i" Y8 H
library(keras)
, f3 V* h& b* T* _, L+ S3 i9 Y _( z: v1 T$ r. }
boston_housing <- dataset_boston_housing()
/ t. E/ V, b- P4 u1 a2 q, {, U6 V' ?' a7 O1 a2 W Z, [( g9 n' N1 C
c(train_data, train_labels) %<-% boston_housing$train$ R. j: F! w$ \8 }
c(test_data, test_labels) %<-% boston_housing$test
4 H; I' H/ x; U& S* x* A
5 G% @' X. x. x4 }: W每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。
: ~0 S- q( @; d+ U/ b9 P( D# Test data is *not* used when calculating the mean and std.
- A& b6 D! X1 o0 o# @) N1 b ^& \) |) w& r% d% I, N
# Normalize training data3 R' m( Z# t8 i) |$ Q
train_data <- scale(train_data)
! z& C& n$ t: u' m6 |! A
, j5 p# S1 ?8 `+ l# Use means and standard deviations from training set to normalize test set m) N8 B' T1 P- t" Q
col_means_train <- attr(train_data, "scaled:center")
, v& d. [7 ~6 t6 Tcol_stddevs_train <- attr(train_data, "scaled:scale")
( A' T! S* [( T1 I& ~% V' Htest_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)
! m, ]* p: s4 [( {4 U
N5 B G4 f+ s. W4 p) d2 u$ r3. 构建网络创建模型
! A/ b t V: y- sbuild_model <- function() {% w% I0 B- { ]$ s
( ~6 d9 g5 M+ O" J/ P model <- keras_model_sequential() %>%; `2 d% u0 }" r4 l
layer_dense(units = 64, activation = "relu",
' e" Q v5 u$ F) F input_shape = dim(train_data)[2]) %>%
+ V3 Y( n$ ^( n4 h5 q layer_dense(units = 64, activation = "relu") %>%+ s2 U1 f! y- n, |( H1 w
layer_dense(units = 1)
# T8 r# r9 h' U; R9 P, d; K7 t
# N9 E9 c: y* O/ i: h# [8 t model %>% compile( L8 S% v7 w: X8 W6 ^" ?2 ~
loss = "mse",
# s/ i- a0 X% c; R& a4 l! h optimizer = optimizer_rmsprop(),
: ~& u) V/ t3 J. c metrics = list("mean_absolute_error")' f- L; j8 ?9 f6 ^
)) r. h& J* I1 k& p0 Y$ f
- `9 z$ t7 z5 y' V) E model
% n" x! z! [* {. s$ c. q6 C}
; S. }; g7 U2 S9 R& L Y5 ~4 B( q6 V( c
model <- build_model()/ f: N( n3 j* g
model %>% summary()
1 m" B: L4 ]* k* t- C' P' A! |4 U( p& C. `+ r
网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型
5 c1 S4 H' }" ^# W" Z& r# Display training progress by printing a single dot for each completed epoch.7 s6 h3 G x" Z. S1 S
print_dot_callback <- callback_lambda(
. I8 P& U# v8 Z# g$ T% D! N on_epoch_end = function(epoch, logs) {* G2 U4 H( h0 a: ~/ a7 u
if (epoch %% 80 == 0) cat("\n") z8 }3 q( }: I, {/ y7 D
cat(".")% k! [6 t( C, s2 J
}/ B$ L9 _$ V b
) / ~$ v3 }8 a4 ^
7 n6 {4 ^: _% t" m' x; Gepochs <- 5007 F" Y, ^, {% C' H# t2 A3 {/ p
' H" v" T k8 [8 e
# Fit the model and store training stats
& F" q. A% _0 [9 g9 v! ?6 ahistory <- model %>% fit(
6 c+ C- U$ y6 c% m# ?/ \2 h0 m/ Y$ ] train_data,- L; l" ?2 [/ d9 f5 N* V
train_labels,. I, q' H0 R ?% u5 F& Y3 @' R- d3 x
epochs = epochs,
4 X2 D0 r& p/ F8 U7 }( x validation_split = 0.2,
: D4 |( |8 S6 M4 [7 _1 ` verbose = 0,
. c1 {4 H$ ~" O, e2 U3 e; R6 k callbacks = list(print_dot_callback)6 y7 E! Z q9 r$ a; x2 |
)$ N5 K: R5 b& w' R2 b
. f' s" a% x. J" R) Q1 x
library(ggplot2). S3 V" s7 ^% X. k6 v2 I
) B" S/ T4 e( F# h% @" K
plot(history, metrics = "mean_absolute_error", smooth = FALSE) +
* {7 e8 c/ w: a7 E" X coord_cartesian(ylim = c(0, 5))* G( O3 }* @* s2 {; Z# d# B' i
3 B. f# g Z* v7 b$ ~7 E
![]()
) R6 d- P% l( {( K6 V3 G
5 ]/ T1 Z7 Z& |8 n9 R5 d小结, n* ]0 o; P; \: X
1)回归常用的损失函数是均方误差(MSE)。* I+ x! p4 u9 t3 B/ b& g
2)常见的回归指标是平均绝对误差(MAE)。
# w8 O, C% c7 ]; X3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。 x. z( s5 o2 {
4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。. L/ W% J5 g, W4 R' J1 H
$ f# x) {1 V- E8 h! g
) k* o! \+ ^5 A' i1 V
1 {5 o& X/ W" B, K) C |