预测房价:回归问题——R语言
& g* D- W! B3 A2 \( H' W在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。4 M$ N2 x. Z* ?
4 k0 Q, l. k' r8 M+ N问题描述
" m5 i" f' R* {, T+ U6 F我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。( q1 I; P3 ~% u1 J) R7 |0 G4 ?5 P
本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。, C% E2 Y; ?( ]7 B
数据特征:: W% N R) e# P7 M5 e! c
人均犯罪率。
S& s. `8 v: v7 G占地面积超过25,000平方英尺的住宅用地比例。
+ P% t( t& u: B& {6 Y2 M: ^每个城镇非零售业务的比例。- ~. D; D& u, R* B% k; S% W$ t
Charles River虚拟变量(如果管道限制河流则= 1;否则为0)。
: \) d3 k! ~1 [" E0 K; A, z: V一氧化氮浓度(每千万份)。# z' G9 p( s9 F; Q# |3 {9 a/ ]* F
每栋住宅的平均房间数。
% L( J$ h) @* L) T( |. A! `* D, }1940年以前建造的自住单位比例。6 e/ D9 Y5 y; f4 L( w
到波士顿五个就业中心的加权距离。
- p. Q3 `6 f. \ d% C径向高速公路的可达性指数。
9 N/ k" J/ @7 c& Z每10,000美元的全额物业税率。7 u2 ^' A7 m/ F
城镇的学生与教师比例。
# o1 `3 \' r; g$ {( P1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。* N* b {- L+ f+ G
人口比例较低的百分比。2 l2 _! X- K. L0 v( E/ O0 V
1. 加载波士顿房价数据! I2 s' x& _* Q
library(keras)
5 d* H- r1 H0 p% E7 ^2 }1 _
+ e) T, ?' O& B- E& r2 q. v+ Uboston_housing <- dataset_boston_housing(); j: W( U O- l# U
$ \) [) _$ D1 A5 z8 c* zc(train_data, train_labels) %<-% boston_housing$train d* l: \6 b! K2 S' h
c(test_data, test_labels) %<-% boston_housing$test5 t) x+ X& R$ O+ l% [2 p. N; g
* T+ J/ u0 `% y, a1 k
每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。 8 m: f/ V4 n* v5 G4 S
# Test data is *not* used when calculating the mean and std.
* B3 e* I9 f$ f" M e- z5 Q9 R
; F- z& l7 E6 `# |2 c# Normalize training data
9 A. v$ @, e/ J$ e, e) n: n0 Otrain_data <- scale(train_data)
: w/ ]2 I/ a7 K
4 _4 X m. W2 h- X; a7 d+ h5 U# Use means and standard deviations from training set to normalize test set
4 |8 `. j1 E5 xcol_means_train <- attr(train_data, "scaled:center") # l( m* o# a k" k- _- ^
col_stddevs_train <- attr(train_data, "scaled:scale")' s: T P8 i' c4 Z
test_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)
; ?: P8 ~: K5 F3 p2 t4 z. t7 E. F7 ^; I1 Z
3. 构建网络创建模型
! R: P* u: X. ~0 V, U/ W0 Z. Hbuild_model <- function() {3 u. x; w# j' h, H; V
6 S" d, s+ G& P: F% s model <- keras_model_sequential() %>% Y0 z [" T/ H% b
layer_dense(units = 64, activation = "relu",
4 x3 o$ q' n$ e& {1 J input_shape = dim(train_data)[2]) %>%& s: E2 c4 P9 P; }
layer_dense(units = 64, activation = "relu") %>%
/ w$ [4 w- @) L5 e o& A- o- j$ w layer_dense(units = 1)
& K0 ]: S" L* g# G- B; F; ^5 X' d, C5 j$ f: q. L
model %>% compile(5 w! T7 G1 I0 [$ h/ h' c% R
loss = "mse",9 V2 x) \$ Z, L% k# N, P3 x
optimizer = optimizer_rmsprop(),/ u5 |! R/ S2 |5 _
metrics = list("mean_absolute_error")
) }4 `( J* V5 N4 O )
& O1 x! p; Q) p* f2 o) u" P$ L0 U+ i! v% z. J. s7 j
model4 S9 e/ {3 Q. N. X
}3 I" G+ O' p$ [# \1 }4 z
! b4 Y8 t7 z4 L0 t" P
model <- build_model()
/ f" S& N- a. L, u$ H+ l; V+ X7 Kmodel %>% summary()
$ C( b8 Y# U2 T# q3 T* \3 f1 \1 X! T8 W# {- N4 x! t
网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型
; D4 I, U6 P0 Q1 [$ M9 Y# Display training progress by printing a single dot for each completed epoch.
w; o3 E5 G# _* wprint_dot_callback <- callback_lambda(" U3 `4 v* }+ c) g
on_epoch_end = function(epoch, logs) {
5 a, m4 u- H) u! a3 U+ ~* g: q if (epoch %% 80 == 0) cat("\n")& O0 q' K5 X" u$ W! L
cat(".")/ O- S/ r5 b; J' B; k% g
}2 Z3 U" Q2 [, a" e3 @
) \1 w* z- \6 P. [7 e) Z
) S+ ]; J0 {4 s5 b2 repochs <- 500
# L$ U3 } q Q" s3 m' O- p! q, a3 u- ?: v* ]# U
# Fit the model and store training stats
- J& B( R8 Q) I# C9 H" phistory <- model %>% fit(6 Z, B* M' U6 M j2 U+ L" f
train_data,
/ l+ v( x4 M: D1 Q" m train_labels,
& Y, s# E; p( p7 w epochs = epochs,
/ ^1 ?( K P- }- s validation_split = 0.2,+ K2 Q" }3 P# c* |
verbose = 0,% Y% n1 C5 J7 |# Z$ l* u: A+ q
callbacks = list(print_dot_callback)
7 I! |4 O* c6 V* K). Q% O3 B7 \8 N }
7 C2 V, \" ^2 M. D9 i5 }6 e/ w' X
library(ggplot2)
* `/ B$ D) f; P% y( U/ |% t8 Y7 _0 A4 s
plot(history, metrics = "mean_absolute_error", smooth = FALSE) +
: ?. f7 \1 Q- k# J coord_cartesian(ylim = c(0, 5))
: t1 s9 z# M& \* O
& s. R/ F- K4 e. I6 t. K" I) J k- ~8 A8 \9 |2 d' l1 ~4 m8 ~ _; C
# L5 T/ Q s9 ]) R小结
- p& u. ?. U; v6 T" o0 a% ?# X* K1)回归常用的损失函数是均方误差(MSE)。
- c4 A& p% a$ d2)常见的回归指标是平均绝对误差(MAE)。
# b' m9 p2 @+ }1 e3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。8 @4 a% c! d- v3 N: ?
4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。% ?# I- ?1 M. Z( q5 B4 H% B
8 t6 X" W1 u8 J+ ?7 z- b& I0 M* P( b8 @8 E
/ Z9 E5 F. A7 |- ^2 P |