赞
踩
本文针对解决的问题:
波士顿房价进行预测采用了两种方法:
1. 搭建神经网络进行预测(激活函数为线性回归)。
2. 最速下降法求得各属性的权值(权值的大小决定房价的影响因素),然后根据各个属性的值乘以权值加上偏置得到预测的值。
首先还是先导入本文所需要得包
from keras.datasets import boston_housing # 波士顿房价
import pandas as pd
from keras.models import Sequential # 构建神经网络
from keras.layers import Dense,Dropout # 全连接层和遗弃数据
from keras.optimizers import Adam # 优化器
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler # 归一化
import numpy as np
直接将数据集的内容导入
(train_data, train_targets), (test_data, test_targets) = boston_housing.load_data()
x_train = pd.DataFrame(train_data) # 每座房子的13个属性(训练集)
y_train = pd.DataFrame(train_targets) # 每座房子的价格(训练集)
x_test = pd.DataFrame(test_data) # 每座房子的13个属性(测试集)
y_test = pd.DataFrame(test_targets) # 每座房子的价格(测试集)
归一化的目的就是消除量纲的影响,因为在数据中存在着不同的类型的数据,直接使用会有量纲的影响。
sc1 = MinMaxScaler(feature_range=(0,1)) # 归一化范围在0到1
sc2 = MinMaxScaler(feature_range=(0,1))
x_train = sc1.fit_transform(x_train).reshape(x_train.shape[0],x_train.shape[1])
y_train = sc2.fit_transform(y_train).reshape(-1,1)
x_test = sc1.fit_transform(x_test).reshape(x_test.shape[0],x_test.shape[1])
注意要是使用以上的这种归一化方法会使得损失值偏大,因为当我们直接使用归一化会对所有的值归一化,就没有消除量纲的影响。以上这种就是根据最大最小值归一化的。
正确归一化
dataset = load_boston()
x = dataset.data
y = dataset.target
mean = x.mean(axis=0) # 求平均值axis=0表示纵向,1横向
std = x.std(axis=0) # 求方差
x = (x - mean) / std
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size = 0.2)
如下图,13个属性值,我们首先需要按照纵向求得平均值,然后求得方差,最后标准化。
在讲搭建模型之前,我们先来了解一下全连接层Dense,简单的说就是output = activation(dot(input, kernel) + bias),其中activation为激活函数,dot(input, kernel)输入与权重点乘,最后加上偏置,
Dense的参数:
model = Sequential()
# 全连接层
model.add(Dense(units=64, # 神经元个数
activation='relu', # 激活函数
kernel_regularizer=None, # 权重
use_bias=True,
input_shape=(x_train.shape[1],) # 输入形状
))
model.add(Dense(units=64,
activation='relu'))
model.add(Dropout(0.2)) # 舍弃输出的20%的数据
model.add(Dense(units=1,
activation=None))
model.compile(loss='mse', # 均方误差
optimizer='adam' # 指定优化器
)
model.fit(x_train,
y_train,
epochs=300,
batch_size=50, # 一次训练所选取的样本数
)
这里的batch_size可以去 神经网络中Batch Size的理解_myc的博客-CSDN博客 查看更加详细的用法。
total_loss = 0
for i in range(len(predict)):
total_loss += (predict[i] - y_test[i]) ** 2
avg_loss = total_loss/len(predict)
print(avg_loss)
平均的损失值为 8.815071
predict = model.predict(x_test)
predict = sc2.inverse_transform(predict) # 还原数据
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.plot(y_test, color="red")
plt.plot(predict, color="blue")
plt.legend(['真实值','预测值'])
plt.show()
可以看出模型已经很好了。
原理:根据梯度下降法计算出最后的权重,根据属性的权重的大小推断出是否是决定性因素。
from sklearn.datasets import load_boston
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from sklearn.model_selection import train_test_split
首先定义初值
w = np.random.rand(13) # 随机生成权重
b = 1.0 # 随机设置偏置
lr = 0.0001 # 学习率
epochs = 3000 # 迭代次数
reg = 0.5 # 正则表达式lambda
对L(w,b)分别求w1,w2,…,wn和b的偏导
然后可以最速下降法求得下一个权重值
for epoch in range(epochs):
sum_w = 0
sum_b = 0
for i in range(x_train.shape[0]):
xi = x_train[i]
yi = y_train[i]
yi_hat = model(xi)
sum_w += (yi_hat - yi) * xi
sum_b += (yi_hat - yi)
grad_w = (2 / x_train.shape[1]) * sum_w + (2.0 * reg * w) # 梯度
grad_b = (2 / x_train.shape[1]) * sum_b
w = w - lr * grad_w
b = b - lr * grad_b
注意:lr可以理解为步长,lr后面的偏导就相当于方向,意思是w0向着这个方向下降了lr个距离
为了防止过拟合,加入λw**2,求导得2λw,定义λ的值,当λ越大时降低训练时的损失值,如λ=1000;当λ越小时降低预测时的损失值,如λ=0.01。
dataset = load_boston() x = dataset.data y = dataset.target mean = x.mean(axis=0) # 上部同样的方法 std = x.std(axis=0) x = (x - mean) / std x_train,x_test,y_train,y_test = train_test_split(x,y,test_size = 0.2) ''' x_train (404,13) x_test (404,) ''' w = np.random.rand(13) # 随机生成权重 b = 1.0 # 随机设置偏置 lr = 0.0001 # 学习率 epochs = 3000 # 迭代次数 reg = 0.5 # 正则表达式lambda def model(x): y_hat = w.dot(x) + b return y_hat list_w,list_b = [],[] for epoch in range(epochs): sum_w = 0 sum_b = 0 for i in range(x_train.shape[0]): xi = x_train[i] yi = y_train[i] yi_hat = model(xi) sum_w += (yi_hat - yi) * xi sum_b += (yi_hat - yi) grad_w = (2 / x_train.shape[1]) * sum_w + (2.0 * reg * w) # 梯度 grad_b = (2 / x_train.shape[1]) * sum_b w = w - lr * grad_w b = b - lr * grad_b list_w.append(w) list_b.append(b) print(list_w[-1],list_b[-1]) def loss_function(x,y): total_loss = 0 for i in range(len(x)): xi = x[i] yi = y[i] yi_hat = model(xi) total_loss += (yi_hat - yi) ** 2 avg_loss = total_loss/len(x) return avg_loss train_loss = loss_function(x_train,y_train) # 训练集平均损失值 test_loss = loss_function(x_test,y_test) # 测试集平均损失值 print(train_loss,test_loss) predict_2 = x_test.dot(list_w[-1]) + list_b[-1] print(predict_2) print(y_test) plt.rcParams['font.sans-serif'] = ['SimHei'] plt.plot(y_test, color="red") plt.plot(predict_2, color="blue") plt.legend(['真实值','预测值']) plt.show()
训练集和测试集的平均损失值分别为20.886724867938153和27.05772042864247
上面的神经网络的平均的损失值为 8.815071 比这里的27小得多,说明这里的预测的模型没有神经网络好。
经过线性回归的预测13个属性的权重:
[-0.72108399 0.69643086 -0.0926451 0.29574251 -1.29656288 3.48564137
-0.62116863 -2.3274482 1.21939315 -1.48616123 -2.0008885 1.0035156
-2.29973511]
可以明确得出第2、4、6、9、12因素为主要影响因素。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。