预测房价:回归问题——R语言
4 y. e* m! i8 C3 b1 o在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。
1 M, _* F6 N- I; N1 w3 ~
; _8 |2 y4 ?8 Y8 ^$ @# V问题描述
! b/ J- h: i1 d& L$ X6 q5 N- c我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。
: @% H( H5 G0 c- K/ `本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。
, `4 t! Y$ H5 T' W8 T数据特征:# H1 C! w2 L4 x+ T8 `6 U- [) V
人均犯罪率。
+ q( `8 d7 B- n) D& x占地面积超过25,000平方英尺的住宅用地比例。
g8 k5 C+ Y3 T4 z$ R/ x每个城镇非零售业务的比例。0 H$ I: e3 P8 K( [# Q/ \
Charles River虚拟变量(如果管道限制河流则= 1;否则为0)。0 h/ |/ W" w( }; l: H1 ~! s
一氧化氮浓度(每千万份)。) U2 L/ m/ e9 r" ]: @ n$ }* |5 ]
每栋住宅的平均房间数。
' c7 f. ?' l6 Q1940年以前建造的自住单位比例。
" ^8 j3 E# ~# r5 G* S到波士顿五个就业中心的加权距离。! N) V- m. O w9 w O* f* b; J
径向高速公路的可达性指数。
. `; y' _. g P) B' s# a9 J每10,000美元的全额物业税率。2 |2 G9 C9 ~# m/ z
城镇的学生与教师比例。. b. E/ G. E f! U% D& T/ |
1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。
4 t! ~& ?) K7 q/ L7 Z; \人口比例较低的百分比。
5 _! g/ T, `2 w2 c% |! Q: B1. 加载波士顿房价数据: v" [7 x! r9 p$ J5 G
library(keras)
9 O8 P/ N& w" P. `) x
1 E) w/ @; n/ }- O6 g0 ?, Yboston_housing <- dataset_boston_housing()
& V! {( l/ g" Z* l
9 ]5 p, ?2 i# X& W) |c(train_data, train_labels) %<-% boston_housing$train9 N1 U' p# [( q- A
c(test_data, test_labels) %<-% boston_housing$test6 v# Z6 `: n7 Z- n8 j4 v% J2 M0 F" R
0 C, P2 M9 L' t8 p, [: ?每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。 " z9 @6 h: b6 [, A2 J) p
# Test data is *not* used when calculating the mean and std.2 k1 |0 K* ^8 {9 Z1 r' V
1 u- D+ T8 j7 I. u; v# Normalize training data
6 r* e* x0 A4 _4 L* [! K( strain_data <- scale(train_data)
& f, n- t. g1 F0 g+ a3 _
$ T1 D' r$ V+ V& D# Use means and standard deviations from training set to normalize test set
* G; L& }- |+ x- U K! a+ P/ M4 Kcol_means_train <- attr(train_data, "scaled:center") ; `( j# `, J3 h. @) \' x* \
col_stddevs_train <- attr(train_data, "scaled:scale")
3 J$ ~% y' |( T( I- L0 m H" xtest_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)
; q' M) Z6 \' ` I; ^8 Z4 Q6 H! M. _0 D) V' M5 g. r
3. 构建网络创建模型 ) b+ f4 A5 P) P& e% d6 l; Y: [
build_model <- function() {
- n$ e8 Z7 I; P2 T- R
5 z+ j$ K- P! R5 Y3 @ model <- keras_model_sequential() %>%
* I& j$ g$ ?2 K# v( s+ f layer_dense(units = 64, activation = "relu",) Y# H# r2 ]1 \' \: k5 C9 n
input_shape = dim(train_data)[2]) %>%
6 d! O- L% m! { layer_dense(units = 64, activation = "relu") %>%8 H# k! m7 w! t [
layer_dense(units = 1)) B6 m; A9 [8 H1 ?- Q d/ R
; r4 E* R# N3 d
model %>% compile(
# A* X/ A, j; G1 U. c9 t0 n% p x loss = "mse",
! N/ I" j/ ]3 U$ Q- f1 T optimizer = optimizer_rmsprop(),) t& A, D1 N' u! {
metrics = list("mean_absolute_error")+ F( C, `% ]1 g2 X# b G* Y
)
5 T4 o: O! R6 a4 g5 h
* c, p" {' N0 ]" }' x) ]9 v+ x2 H model; ]5 [2 w5 @' Z7 \
}
* j1 w0 x! c. _" W4 J U$ n% Y( m& H
model <- build_model()
* a- p( Q5 [: A4 d9 I* y6 Dmodel %>% summary()" v+ Y7 @6 ^) X8 Y, K8 |$ T
2 ]! O' x" y2 |: r: ~网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型
9 W0 V @& Q+ e- O% c+ Q4 ~1 }# r# Display training progress by printing a single dot for each completed epoch.8 J7 A4 z* i, x, l" d
print_dot_callback <- callback_lambda(
. \$ L" m- X! s# @ on_epoch_end = function(epoch, logs) {' y' J! m% L% p1 S
if (epoch %% 80 == 0) cat("\n")- A6 b4 C" N+ [4 P; w
cat(".")% _- S% y8 |% r! M1 ^- f$ B) @
}
% E. x/ W: T. X p8 \1 H) ( C4 R6 H8 T: q/ b% }) P
% Y: { F @# R+ z# ^epochs <- 500( F, o( t8 ~% |) V) j, p3 {: W
e' f8 k9 @& V- u0 [# Fit the model and store training stats N9 g* h1 F2 u, h5 R1 O
history <- model %>% fit(1 Z% t' f5 H& S' m$ G
train_data,
7 o( f$ ^. L" T' V, C! {' F train_labels,
$ M* t& |- f7 E% Y# }' S! W epochs = epochs,' ]4 c; I- ?4 N
validation_split = 0.2,
# O2 V. D0 e, y; d( I verbose = 0,
# c ]9 |' B, _- V( |8 p" h8 ] callbacks = list(print_dot_callback)
: ?# p* h! F9 H1 p! f8 ?8 Z# m( l5 e): M9 a, R: B/ \2 N
. h0 C% S: K1 e% A$ |
library(ggplot2)
' P& B0 e0 z, N/ q2 p1 r$ B7 }( Q3 d! c6 Y
plot(history, metrics = "mean_absolute_error", smooth = FALSE) +
: @4 [7 b- u* k* {, ^( x0 p coord_cartesian(ylim = c(0, 5))
) g: m0 t. w( w, N5 o! n: q" x) z' _
![]()
3 \- Z- E* h; x( @: `, X) f2 p6 q$ R4 i
小结
$ k3 o3 S+ B* t) X1 U, A0 ]7 A1)回归常用的损失函数是均方误差(MSE)。
+ z+ l, |% T" k3 L% i2)常见的回归指标是平均绝对误差(MAE)。; C( N: b" p# A6 X) w* q+ p& z& m
3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。 q1 }4 ]* _" {% o
4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。
& E2 |! h: r8 C* |( G% @3 [7 L" t [5 d0 P
4 ]( p [6 f5 ~/ T; S/ o; I! X- e
3 {$ B6 k2 D/ k+ D/ B
|