预测房价:回归问题——R语言% F# I6 k/ x, Y. W$ [
在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。3 R( _+ B7 ~ n+ h% M" |
9 S2 h6 D# y' L! }- ?问题描述
# I0 l+ t7 V6 [- T7 A' s我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。# Y8 v+ p) H) X y: w8 u2 ^" h; `
本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。7 N& ?4 u; k: m! A# }
数据特征:
# B; P) x. N* x& X人均犯罪率。
( M P7 O% ~4 b: b占地面积超过25,000平方英尺的住宅用地比例。
" k2 C3 f9 ^* c& f$ X每个城镇非零售业务的比例。
3 E: z2 N: q6 j4 a" H2 W# {Charles River虚拟变量(如果管道限制河流则= 1;否则为0)。
- P0 v" O5 G9 A# ^$ _; ]一氧化氮浓度(每千万份)。
/ |: Y- Q0 m2 p, G" ^! p& z2 }每栋住宅的平均房间数。2 I! s# N% y1 ?' _' P4 m3 ?
1940年以前建造的自住单位比例。
6 J# J) `& f8 k5 ]/ c到波士顿五个就业中心的加权距离。 [$ j5 J* h# I2 x, B3 |7 q
径向高速公路的可达性指数。: C: x% ^5 L4 p0 \' \! v9 j
每10,000美元的全额物业税率。' Z3 i1 C+ W) L# C
城镇的学生与教师比例。
$ e+ V1 L' C$ m: a- r- v6 a1 K1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。+ X) L# I. }2 l9 i% V
人口比例较低的百分比。
& X) ^6 ?5 ], { O1. 加载波士顿房价数据- P a9 t$ \7 [) Y4 c; s9 M
library(keras)- J& s2 Y1 f0 n( M
% d, B# Z# K( m" K5 ~boston_housing <- dataset_boston_housing()
5 R: [9 Y4 v, w6 n, \
0 Y8 ^: S5 W5 d x. u9 ~- x6 _; \c(train_data, train_labels) %<-% boston_housing$train, q) E( U0 ]+ R" E( L N4 P& O& u
c(test_data, test_labels) %<-% boston_housing$test3 r) U- {& C: `* o5 D' x
- c9 J) x+ B0 i$ e1 G. R3 z9 f6 p" `
每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。
) }1 ]) N1 g j' E7 k# Test data is *not* used when calculating the mean and std.6 @$ T+ I0 a4 k6 P: u
^2 C$ _! E9 P4 e9 S3 s/ t& T6 N# Normalize training data" W& ?* a1 i) y3 F
train_data <- scale(train_data)
- n% [- s5 R8 }# }- w! Y1 R! V% {6 v# U, h( [
# Use means and standard deviations from training set to normalize test set& x' R5 g1 _8 a* ~( Y2 |. L0 P, W
col_means_train <- attr(train_data, "scaled:center") # x7 p S5 S0 s' ?5 p) z8 n* B5 q
col_stddevs_train <- attr(train_data, "scaled:scale")+ u* y; f% i* o' Y
test_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)
+ N( r' \) C& O# a4 L$ w s C: c" G
3. 构建网络创建模型 + F* N# m+ v: ]9 E. |. }( P
build_model <- function() {( n2 w' }& O) |/ h: y6 `
' p7 ~+ Y: V5 V) z I5 `
model <- keras_model_sequential() %>%4 o3 H, C" u' \' V) G- t
layer_dense(units = 64, activation = "relu",. I2 L+ q$ N& [3 R9 j
input_shape = dim(train_data)[2]) %>%
3 z, M% a4 m3 S% f layer_dense(units = 64, activation = "relu") %>%- C- ` k( ^. G S- k* H, c% V
layer_dense(units = 1)& u, ?# _5 [* @ u1 H+ I
+ ?# h( t9 k, f8 m7 h
model %>% compile(2 Q$ _5 q4 }& |; ]! B/ t. I0 g
loss = "mse", f+ _4 z6 @2 e0 T! L
optimizer = optimizer_rmsprop(),
; l6 P0 r. T* R4 U v6 p metrics = list("mean_absolute_error")
4 `- N# R. A8 ]& [3 A )8 \% Z4 W) Z( I3 ? n! A M
/ X1 w( g% f8 I. [* P4 \ model! A! a/ x* ` ^0 I4 \$ G; C
}/ |! V5 z9 C0 B/ G& {* o
0 Y- z8 K( {; H0 g8 [model <- build_model()
. T. o* Y3 ]1 X# G" ^# b8 v' G) [model %>% summary()# c* K) L+ j2 n. G2 x
6 T& j: G0 e4 R: q, \
网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型
( b/ n! @! K5 u# Display training progress by printing a single dot for each completed epoch.
% a! S* k- x3 Y$ x9 Zprint_dot_callback <- callback_lambda(
1 b' {8 i+ A6 X* e/ s0 i$ i( u. q+ t* |+ { on_epoch_end = function(epoch, logs) {
/ n4 g4 p0 q+ P5 o( f: C* t if (epoch %% 80 == 0) cat("\n") Q7 T" z2 n3 ^5 E2 ~
cat(".")) p. c" |5 ~ z+ g$ A( A* n
}
) X" J9 j8 F8 r4 B! G) 5 x2 ?0 c4 ^( r
" u3 K; H) N- m
epochs <- 500' E# k$ f' ~* X0 Q+ A% [
3 M `, B; p- R v4 l# Fit the model and store training stats- c0 W5 @6 D0 J
history <- model %>% fit(
% Z' C! {1 Z8 n+ U train_data,) s- i0 R9 m- Y; W
train_labels,: p" v) L' K9 q& I
epochs = epochs,- p6 D; @9 J6 ^4 M9 G2 T$ Q5 i
validation_split = 0.2,
' e; q$ N( J# v5 f" k5 y" g verbose = 0,& j% b0 |1 l7 E7 ~
callbacks = list(print_dot_callback)" C: C5 R$ ]( s3 r2 n
)
9 b. T( U8 h7 {! {$ g1 N
8 f3 o! ~5 H7 g9 ~9 Alibrary(ggplot2)* ?# W# z$ d$ K. z
. r4 z7 d0 t4 nplot(history, metrics = "mean_absolute_error", smooth = FALSE) +
7 ]' Y) L" I& C0 @5 a2 r coord_cartesian(ylim = c(0, 5)); z7 q2 U- P$ g: W9 f, b [+ {# i @
- _! D( T1 p+ l! _- M
![]()
8 ?0 P% z% t& P: A7 I# F+ n, n$ [3 W( F1 [- Q# e
小结8 q7 y1 ?0 A2 @
1)回归常用的损失函数是均方误差(MSE)。
. m, [+ T( w0 A. k; P0 p% b2)常见的回归指标是平均绝对误差(MAE)。3 F. F' e. G0 y" |) c* H
3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。0 D0 ?9 R" }, c' Y3 L7 k1 `0 i/ e
4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。
' a" h5 X4 P u/ g( M* K% ~) W6 K$ J( t! U, e
9 X8 f% L; m1 W2 g* K" X: j: m+ o' O1 \/ ^6 X! S2 N9 j" D
|