预测房价:回归问题——R语言5 _' U' u& [% |/ H9 x
在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。
# v g2 N9 P+ ]# ~, T: u# [- Z! F: |0 J% g9 `5 e) D- b) h3 X
问题描述
; f9 h/ C- A8 d* `我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。7 L* c& H' ^* W; N: G3 Q) F8 q9 z
本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。
/ U/ I" ?! h3 J+ w9 o: z数据特征:- M8 B- g) A1 @& u) ~4 z! Q6 Y
人均犯罪率。
) Q5 h6 S$ p! O& T$ X5 m. i占地面积超过25,000平方英尺的住宅用地比例。; B4 O+ V7 K j6 M* A
每个城镇非零售业务的比例。; _$ f0 D" N- b, A; T3 j9 L
Charles River虚拟变量(如果管道限制河流则= 1;否则为0)。
/ }4 Y+ q6 O5 L8 {2 G% a一氧化氮浓度(每千万份)。
2 x) u+ k# q$ I! ]: Z7 B" C7 y每栋住宅的平均房间数。( x, B2 Y9 ^1 X7 b- o1 R7 S
1940年以前建造的自住单位比例。. w6 W& ~6 g% d. I, I
到波士顿五个就业中心的加权距离。
& T& m- ~! d) ?" q. `1 h5 M- `径向高速公路的可达性指数。# y6 p$ ~- K1 `4 q6 t( o, C1 ~2 T
每10,000美元的全额物业税率。" n2 u- r8 R( O; g
城镇的学生与教师比例。
% _, v% E! j( p% `9 f+ J1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。
6 G& K5 m! I% N/ ]$ l% w# H人口比例较低的百分比。
$ Q! R" E+ w7 m2 q. c, _+ U" S1. 加载波士顿房价数据
+ n- @: f' e6 tlibrary(keras)
* [) K, G% b7 X0 f1 l0 |4 }$ V$ f* F3 s+ b
boston_housing <- dataset_boston_housing()
?# T4 z J2 ?9 p& B! ~0 {
2 e- h3 [% m5 _+ X' I. e! Q# W Hc(train_data, train_labels) %<-% boston_housing$train
; O$ s; e) q2 C0 \: M* h, a8 Xc(test_data, test_labels) %<-% boston_housing$test
( a; O. i4 R. M+ V( z9 n. s& _: u7 o+ o
每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。 ; M- r1 D8 r! o$ N
# Test data is *not* used when calculating the mean and std.
$ T" V' ^5 h7 R( ~' u* s' N0 d, g' N8 P
# Normalize training data
* _/ y. t( _1 \( @; J" h, B( c* Mtrain_data <- scale(train_data)
$ H8 ^* h, k5 T0 ^5 s( D$ X+ R0 H( X/ a" m% H* ]
# Use means and standard deviations from training set to normalize test set9 M& I7 N$ @. l* R
col_means_train <- attr(train_data, "scaled:center") ( \, [3 D5 V: v" z* ]
col_stddevs_train <- attr(train_data, "scaled:scale")
1 L) K' C; r! _+ z4 ] D7 E0 Rtest_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)
* q! F7 T# @" ~- _4 N. @8 P/ O7 {0 f- g i1 @9 t- S6 l* I% M
3. 构建网络创建模型
G4 z& W1 |6 Y2 qbuild_model <- function() {
* R% Z# |7 t3 K6 u/ j, {" s @' S% [, V
model <- keras_model_sequential() %>%1 y5 w( Y0 \" f* }! l
layer_dense(units = 64, activation = "relu",+ F6 Z4 T p" k* n- ?
input_shape = dim(train_data)[2]) %>%
, B( c$ _2 I6 {+ p8 F+ K9 s i9 Y$ ? layer_dense(units = 64, activation = "relu") %>%( ^ Z- Y; J# h3 h# K
layer_dense(units = 1)
3 X- z, v% y0 r: \9 l7 l+ f9 B
$ C' l4 ~" T c$ x+ y- Z& a- S' [ c model %>% compile(* c# d. q3 X0 h+ d
loss = "mse",2 v/ q3 h2 [0 J$ m8 }1 G4 d# u, y
optimizer = optimizer_rmsprop(),+ w3 J( k& R: s# ^' A. `: R% L
metrics = list("mean_absolute_error")+ ^( m, G8 d4 D( d3 @6 k2 n& [
)
: c4 R2 W( N. ^4 ? U
- Z; v$ e3 G* z1 {! C model
N, N' y" z: F2 Y4 u}0 E, { y7 h* h3 U* `) T6 Z: r
; k% ~0 s9 n% x f t) qmodel <- build_model()
8 w7 y5 T3 Y5 P9 imodel %>% summary()
+ q, R: P( ^6 Q
) l8 t+ e* d: i: Z' w# b" S网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型$ w; t0 K0 n+ F3 t2 }
# Display training progress by printing a single dot for each completed epoch.
7 q- Y6 o+ j/ ^; Aprint_dot_callback <- callback_lambda(
7 u0 F+ y v, A, ~" U on_epoch_end = function(epoch, logs) {
; J4 z" z" X6 S if (epoch %% 80 == 0) cat("\n")* t9 m* Q3 p' u9 t' u
cat(".")
; r6 ~, ` _# g }$ u+ o( m. L; n. F& l% J
) 5 {. b' U3 h/ W @2 S
2 v: M. x/ F! ^7 U2 J$ u: Uepochs <- 500
; u3 r& ?/ C% k1 ]: H* X- s; w+ o7 v$ ~* Q; L# _( |
# Fit the model and store training stats
P- E" Y/ b; r1 Q% B2 S; jhistory <- model %>% fit(
) h; h% D4 p" y7 M. b# B( ]- X7 x% b train_data,
- Z. _1 W0 B- [+ l6 e: H train_labels,1 F% J, M* S* y5 s9 L7 C5 s' P
epochs = epochs,' m7 S7 I/ h0 I: }4 A9 `$ l/ e
validation_split = 0.2,
, a! P! `' U, L1 C1 @( {2 \. g verbose = 0,: d( s [8 Q7 A; i, ~
callbacks = list(print_dot_callback)
: m* j$ n+ R% {)
- _, g* a: b0 e" c6 @, W, d4 H2 B( v+ @! n4 k- G6 `! a
library(ggplot2)5 ]4 f2 \# f% {* B& L
. f- o0 ~& H. Z' a5 Y5 @9 oplot(history, metrics = "mean_absolute_error", smooth = FALSE) +
) k' D) O9 }1 g coord_cartesian(ylim = c(0, 5))
6 `+ k2 m9 {: M- p# y0 u! D, E
! }( `) V- ^9 z4 p![]()
. r; Q- R$ P8 Z, \8 V- n
6 T0 |% t! e/ y% f' Y' @& v$ t; \1 E小结
& @7 S. ^) W1 @$ k% j1)回归常用的损失函数是均方误差(MSE)。
! t* U( j+ x) L5 I2)常见的回归指标是平均绝对误差(MAE)。
# @8 s2 I5 `- B9 R' u$ x+ D3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。
9 Y6 ?3 F* r Q, n8 [4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。2 E; h, J, x5 n b: W( }
6 ]/ ^9 {" _) `4 X+ S' Y; ]( w
1 Z0 k! }3 R9 F( g& P
, c; W3 y; x8 f# O4 }' g
|