数学建模社区-数学中国

标题: 预测房价:回归问题——R语言 [打印本页]

作者: 1047521767    时间: 2021-10-29 10:50
标题: 预测房价:回归问题——R语言
预测房价:回归问题——R语言
) v- J6 b0 n, v- g在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。
% Z8 z& _( D( c9 L: ~. R! ^( ^& |* ]  Z( A4 s4 \4 }
问题描述
# v4 `7 I% G* j! w, c我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。4 e' a, L% M( [$ u; w# c
本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。, i4 M8 W: g, r7 a+ b4 _/ {0 \
数据特征:0 P( W8 L2 f) K
人均犯罪率。
8 }! E1 g6 B. `) b1 o) H8 X占地面积超过25,000平方英尺的住宅用地比例。
9 s: ^4 D6 o. |1 e, H$ E2 }每个城镇非零售业务的比例。+ _) S* B0 j- f/ S6 ]5 b. w7 m
Charles River虚拟变量(如果管道限制河流则= 1;否则为0)。
8 {/ L8 X8 R) v7 `一氧化氮浓度(每千万份)。
; j& K' W) O4 U7 A' p5 }! I每栋住宅的平均房间数。
/ Q; [4 n0 E, V8 G4 Q. K# _8 D* u1940年以前建造的自住单位比例。
; N7 h2 b( q1 H. Y$ S到波士顿五个就业中心的加权距离。- O/ `$ M' u5 V  B3 s
径向高速公路的可达性指数。6 r6 i( a& I3 ^4 T9 x& m
每10,000美元的全额物业税率。+ g+ z9 N1 h6 P5 |( L5 p" H
城镇的学生与教师比例。! h% h( \% g/ _# e  C! D
1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。
2 V$ Z! \/ ^, C8 }- p( u4 K人口比例较低的百分比。
: v8 N, k& ^- X+ Q  w" q4 V4 \1. 加载波士顿房价数据/ ~1 f8 Q' R; Q% ]
library(keras)$ G8 U  R. E; e: w6 P2 G; M& J% i

+ e# o. s# M7 J1 J, }. ]- m0 g% uboston_housing <- dataset_boston_housing()! z9 J0 a. W5 c$ M3 y4 H0 J
; I; l# I5 f! C8 x
c(train_data, train_labels) %<-% boston_housing$train
1 G' i7 Z; \, Zc(test_data, test_labels) %<-% boston_housing$test2 T% Q9 m3 W1 O# B- ~/ T; z& \
/ G: }  J% l! [, D

每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。

2. 准备数据

数据标准化

将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。


( Y# T' Y) p  x! x# b8 [# Test data is *not* used when calculating the mean and std.! l# N6 [( \/ h, C' J
* X. c% L. y5 Z) `. O4 p% m
# Normalize training data
. m( ?! @" [* S7 H" K2 ttrain_data <- scale(train_data)
3 z6 _& Y5 E8 L! y7 p9 T# X+ M, U# w' O
# Use means and standard deviations from training set to normalize test set* G( @% o2 Z0 A$ Z& t+ u. W
col_means_train <- attr(train_data, "scaled:center") ) k, F+ D, Y  z5 _
col_stddevs_train <- attr(train_data, "scaled:scale")
$ g- y/ l& N8 P: }test_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)# [' ]  I/ _7 I" e# T

9 S; H8 [0 A8 A, o3. 构建网络

创建模型

& u+ }- Z, ?! z7 G
build_model <- function() {
, l" b$ h1 o. u* n4 `( E4 H; b9 U9 M( z4 c' c1 `
  model <- keras_model_sequential() %>%, v( G/ L9 t8 A$ q" d0 Z4 V
    layer_dense(units = 64, activation = "relu",
" i. v) B4 o. h7 Y) ^8 E                input_shape = dim(train_data)[2]) %>%* Z/ M0 C/ J3 e+ e" C; ~, S
    layer_dense(units = 64, activation = "relu") %>%! m8 i0 [3 o4 e% v4 {; t( n
    layer_dense(units = 1). [6 O$ w+ w- g5 Q4 X
# ^. j. l) A" s( V& q
  model %>% compile(; H' P' j8 [; j2 P2 q/ z; P
    loss = "mse",
; |% o7 j3 ~- e- z    optimizer = optimizer_rmsprop(),
6 m* Z9 \! [0 g0 a/ w$ @* h- R    metrics = list("mean_absolute_error")8 h3 N, x8 E8 c. D
  )6 D& \# _: \3 J+ g. O
/ Q) U5 m3 s4 L& x
  model! L" Q( L& ?/ p( l& C/ S* ]
}
2 m$ N8 W! U# n) t
* ~) r/ A( b" u1 amodel <- build_model()
. c4 Y  E5 U+ L' R$ ymodel %>% summary()6 ]- l! Q* Z9 C. O# d
) m+ X' v. z$ a9 O

网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。

4. 训练模型
% D8 j8 i7 Q" g3 U9 N1 R! G6 m3 ?# Display training progress by printing a single dot for each completed epoch.0 o/ f0 D0 M. u3 `+ d
print_dot_callback <- callback_lambda(
' |* v4 E. G' ?4 K. v- J% }% O  on_epoch_end = function(epoch, logs) {  q& H- b9 V# g8 u, L9 P; p
    if (epoch %% 80 == 0) cat("\n")
1 W: F: h. f3 e9 e9 o4 F3 X    cat(".")
3 _% `6 T4 A7 n" C  }- n2 Z% Y" V5 q* H2 P
)   
: r6 A" Z4 N6 {: |& F8 t  {" B) M) I- U4 Y- T: g5 K
epochs <- 500
, ]; D6 w2 o$ q6 C: e/ d2 Y
+ k- @3 y0 a- U; ?# z6 h# Fit the model and store training stats
0 I+ f* x% U, {# ?! r; W( ehistory <- model %>% fit(+ _. j) Y1 a- Q* Y0 o
  train_data,4 t: W1 q4 Z: q3 ?
  train_labels,
1 G  `0 y  I! b+ d' d0 V# s# c; h  epochs = epochs,
7 @1 U/ D9 Y9 x/ C" Q  validation_split = 0.2,
2 @: b" k3 ^% {7 e2 R+ l6 k2 X  verbose = 0,. k6 C$ D- c0 {. s0 k9 y$ x8 D
  callbacks = list(print_dot_callback)! S$ R: T( |: ^9 ~9 q' u4 |
)
( ~6 K1 H, u' ?. S
) o! v$ c* ]; v6 U6 W' ?library(ggplot2)8 @: _6 V8 X, g- {( L1 [( g$ A
1 c2 y5 g2 A9 h& \, k
plot(history, metrics = "mean_absolute_error", smooth = FALSE) +* |+ u$ f" b) D% |9 U
  coord_cartesian(ylim = c(0, 5))
, j3 [" M" ^3 {& s. D5 z2 U- R0 B! ]! d5 F4 w8 [
2 i6 ~1 K- a" T$ O7 w1 Q7 O' t

/ h5 m7 ?3 O* A# \小结
6 y7 i* U* A9 ?, J5 V7 D1)回归常用的损失函数是均方误差(MSE)。
* @3 G- `& o. s4 D0 u& ?$ K2)常见的回归指标是平均绝对误差(MAE)。& Q$ V' V* s! B8 r" Y
3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。, D) j9 c; U: E6 y& B" T2 j. s
4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。/ B% }$ Y( T- t' J- |
4 \* O  N  U$ W) }' S
1 w8 r, O  h" d
  N5 B: s* p% }2 n7 y





欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5