预测房价:回归问题——R语言1 t3 [/ \7 l! _( B6 P' I. v
在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。4 Z& u& q" V/ N& N) X0 K. ~
$ y! ~) R6 Q4 s( ~# f
问题描述6 i7 V! [. v; q
我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。. v, }1 ?6 ?$ ^" v3 o
本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。6 D' [# t$ U5 x9 o0 s
数据特征:( X1 F8 r* V0 Z. E; t
人均犯罪率。
6 z) F9 ]# _" U9 X占地面积超过25,000平方英尺的住宅用地比例。; ^- K. g2 }+ s
每个城镇非零售业务的比例。
5 c7 }, ~) ^0 x) o* q7 K; wCharles River虚拟变量(如果管道限制河流则= 1;否则为0)。
n/ B& ?* N* j6 g k6 @5 g+ C4 X一氧化氮浓度(每千万份)。6 k- e2 \1 z1 E" L2 k" o
每栋住宅的平均房间数。% T7 i* `/ \: L W$ S/ ?
1940年以前建造的自住单位比例。! j, s5 ~1 P. T# G! m
到波士顿五个就业中心的加权距离。
; R! }8 [+ V" t6 @7 z径向高速公路的可达性指数。
- D+ F- W2 [7 s: P每10,000美元的全额物业税率。
1 |7 o1 P3 [) f- P* _) d8 U城镇的学生与教师比例。1 P, E1 B" n4 T- c u$ h1 u- Y
1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。" n t7 Q5 E2 E( ` V( L
人口比例较低的百分比。9 B$ P0 N% b3 Q' l* T- ?: C! w( M3 D
1. 加载波士顿房价数据) D" F5 w; ^5 `, l* v
library(keras)
' A9 z9 L6 }- k* n& k ` C7 I) x/ I2 J# X- X
boston_housing <- dataset_boston_housing()
T4 x N5 ?( q. K( T% Q) Q. f4 g6 u3 O: a( X- A
c(train_data, train_labels) %<-% boston_housing$train
* C$ k( o8 ~3 O% O, d5 M Lc(test_data, test_labels) %<-% boston_housing$test% L ]9 F I" v. K; L
) R0 p3 A1 K1 w# ~+ x+ l( H
每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。
1 D; p' Q3 ?! g0 r; _# Test data is *not* used when calculating the mean and std.
8 v+ D4 H1 _" T! l2 ]5 V7 l3 Y3 ^6 g' g' I9 `
# Normalize training data
) ~2 v5 n4 ^2 \: {: Mtrain_data <- scale(train_data) 3 F+ c; ~! G4 e* H% Y! [( r$ Z
- j% M& l' V( V' I0 a# M$ ~5 `
# Use means and standard deviations from training set to normalize test set* B( `" }# b5 ?
col_means_train <- attr(train_data, "scaled:center")
1 e; i z, e) D" `1 gcol_stddevs_train <- attr(train_data, "scaled:scale")
8 e: ]- ?/ \3 _" ltest_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)7 G$ i: T' i! I9 L1 q# @: t. n
7 w6 t8 a: i- u1 t- |
3. 构建网络创建模型
4 k6 X/ r5 a4 I* s! B- Nbuild_model <- function() {
, ^, s. P: s7 M. B1 c. k& `0 x4 T3 ~. a+ {. ?
model <- keras_model_sequential() %>%
- O, ~ o( x$ ] h layer_dense(units = 64, activation = "relu",, t' s' f1 ^8 S5 u
input_shape = dim(train_data)[2]) %>%
5 m. K" G* }& y) [6 R y" { layer_dense(units = 64, activation = "relu") %>%
% D/ G. n1 k8 }" h3 }* E. g layer_dense(units = 1)
- }( o$ E- D1 S, g; v
t- I& Y" `; E; e$ i! B# k model %>% compile(4 e7 \# p- e# _. Z& n
loss = "mse",
' ?- h) _6 }3 j! \) c) t optimizer = optimizer_rmsprop(),
7 J$ g- L( [" l @! f& H3 u. D metrics = list("mean_absolute_error"); h) \# S. E" d
); c" J/ ` G3 U: i
4 s- a; u, b( g& R* g7 i' }
model
5 I) W( g B& g6 V: b}
' _ U) c: u$ ~; ?: J4 k. L; [8 k" ?3 [+ @& V5 g" j
model <- build_model()
% R% Z* I. t) y( _* W6 ymodel %>% summary()
: e1 y& v8 j+ D* ~9 }4 i" e" E& w$ j' S
网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型
' V5 }9 S2 @: i( I7 n8 O# Display training progress by printing a single dot for each completed epoch.3 W6 x) D) o% L+ a7 c
print_dot_callback <- callback_lambda(
, w8 A3 Z% e2 C9 a" o% _+ `0 g on_epoch_end = function(epoch, logs) {8 P+ U0 ~3 d0 B" W7 ^& S# ~$ o
if (epoch %% 80 == 0) cat("\n")
) n7 q1 [! e7 z D% |( @) y$ l/ @ cat(".")
) Q7 x' ^' E3 g- H3 s7 N3 H }
8 s' h4 {' d& @) @* u2 n)
% Y6 x: q6 [( V' x1 ]; U4 m. e/ }% S& S2 I6 {9 N0 f
epochs <- 500. D% B+ W& k* H: V
3 d9 O5 V! i: f
# Fit the model and store training stats) P% i! q% G! P0 G4 |) x0 _" J
history <- model %>% fit(
, V v/ k& k9 S! p% V train_data,
. \+ r& D( n6 B/ u train_labels,
) H! Q% }$ F" K epochs = epochs,. }1 B" w! |( C8 `- x1 _, L( ~2 Z
validation_split = 0.2,* U. ]# p/ E! X0 L* C% J# p
verbose = 0,* t2 |$ o3 o( T3 y @# Q ~
callbacks = list(print_dot_callback)
5 Z) D E& m& O6 z5 V9 @, ~)
% ~! l- T% ]* h8 j* Q7 s3 E r! C! D) e: a% |1 E* y# Q. ~
library(ggplot2)- ]& s6 _* a w* b
/ d4 A9 P$ d5 p3 M$ {9 Q0 ?9 t7 vplot(history, metrics = "mean_absolute_error", smooth = FALSE) +, T5 r( v# k; t8 C$ x
coord_cartesian(ylim = c(0, 5)), @; Y* y3 W+ q% \4 r5 I3 j
( r0 }: \0 _; J![]()
- G, }. F$ O! |3 m j/ `# F$ s- m! I& X
小结% {! k# U% O6 S" b$ h5 Q4 M
1)回归常用的损失函数是均方误差(MSE)。1 r$ E9 ~, w; X* X3 Z1 s; z2 T
2)常见的回归指标是平均绝对误差(MAE)。
5 R h/ a0 `- d3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。- _* o2 q0 O8 u( J9 O7 M
4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。
/ w; u% G3 q2 A- N" E1 p1 @/ }6 w& E
+ T; B8 a. C: A: T7 J' f
" E7 \: @( D) m8 ^7 X( i# C3 Z |