1.2线性回归的keras实现
1.2.1一维线性回归
假设房屋价格仅与面积有关系,给出房屋面积大小,预测房屋价格
导入必要的模块
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt#画出数据集的散点图
from sklearn.model_selection import train_test_split#数据划分
import tensorflow as tf
from tensorflow.keras.models import Sequential#API按顺序堆叠神经网络层
from tensorflow.keras.layers import Dense
制作数据集
这里的数据集 x x x表示房屋面积(单位:平方米),数据集 y y y表示房屋价格(单位:万元)
x = np.array([50, 30, 15, 40, 55, 20, 45, 10, 60, 25])
y = np.array([5.9, 4.6, 2.7, 4.8, 6.5, 3.6, 5.1, 2.0, 6.3, 3.8])
画出数据集的散点图
plt.scatter(x, y)#画散点图
plt.grid(True)#画出坐标网格图
plt.xlabel('area')#x轴名称为‘area’
plt.ylabel('price')#y轴取名为‘price’
plt.show()#输出图像
通过散点的位置分布,我们可以得知,这是一个线性回归模型
数据划分
划分训练集和测试集
使用到的api:
数据划分sklearn.model_selection.train_test_split
用到的参数:
-
*arrays:输入数据集。
-
test_size:划分出来的测试集占总数据量的比例,取值0~1。
-
shuffle:是否在划分前打乱数据的顺序,默认True。
-
random_state:shuffle的随机种子,取值正整数。
返回:
- splitting:列表包含划分后的训练集与测试集。
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, shuffle=True, random_state=23)
x_train, x_test, y_train, y_test
画出训练集数据的散点图
plt.scatter(x_train,y_train)
plt.grid('True')
plt.xlabel('area')
plt.ylabel('price')
plt.show()
plt.scatter(x_test,y_test)
plt.grid('True')
plt.xlabel('area')
plt.ylabel('price')
plt.show()
使用tf.keras.Sequential按顺序堆叠神经网络层,添加网络只要使用.add()函数即可。
使用到的api:
全连接操作tf.keras.layers.Dense
用到的参数:
-
input_dim:如果是第一个全连接层,需要设置输入层的大小。
-
units:输入整数,全连接层神经元个数。
-
activation:激活函数,如果不设置,就表示不使用激活函数。
-
name:输入字符串,给该层设置一个名称。
模型设置tf.keras.Sequential.compile
用到的参数:
-
loss:损失函数,回归任务一般使用tf.keras.losses.MSE,或直接输入字符串’mse’。
更多损失函数请查看https://www.tensorflow.org/api_docs/python/tf/keras/losses -
optimizer:优化器,这里选用tf.keras.optimizers.SGD(learning_rate=1e-5), 也可以直接输入字符串"sgd"。
更多优化器请查看https://tensorflow.google.cn/api_docs/python/tf/keras/optimizers
model = Sequential()
# 全连接层
model.add(Dense(input_dim=1, units=1, name='dense'))
#input_dim限制的是feature vector的个数,units限制的是hidden layer内神经元个数,不包含input layer 和output layer
# 设置损失函数loss、优化器optimizer
model.compile(loss=tf.keras.losses.MSE, optimizer=tf.keras.optimizers.SGD(learning_rate=1e-5))
查看模型每层输出的shape和参数量
model.summary()
模型如下:
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense (Dense) (None, 1) 2
=================================================================
Total params: 2
Trainable params: 2
Non-trainable params: 0
_________________________________________________________________
模型训练
使用到的api:
tf.keras.Sequential.fit
用到的参数:
-
x:输入数据。
-
y:输入标签。
-
batch_size:一次梯度更新使用的数据量。
-
epochs:数据集跑多少轮模型训练,一轮表示整个数据集训练一次。
-
validation_split:验证集占总数据量的比例,取值0~1。
返回:History对象,History.history属性会记录每一轮训练集和验证集的损失函数值和评价指标。
loss是训练集的损失,val_loss是验证集的损失
history = model.fit(x=x_train, y=y_train, batch_size=1, epochs=100, validation_split=0.2)
查看loss的变化趋势
pd.DataFrame(history.history).plot(figsize=(8, 5))
plt.grid(True)
plt.xlabel('epoch')
plt.show()
模型验证
使用到的api:
tf.keras.Sequential.evaluate
用到的参数:
-
x:输入数据。
-
y:输入标签。
-
batch_size:一次模型验证使用的数据量。
返回:损失值
MSE: Mean Squared Error 均方误差:一般用来检查模型和预估值和真实值的之间的误差
M
S
E
=
1
M
∑
m
=
1
M
(
y
m
−
y
m
^
)
2
MSE=\frac{1}{M}\sum^M_{m=1}(y_m-\hat{y_m})^2
MSE=M1m=1∑M(ym−ym^)2
分析:值越大,表型预测的效果越差
# 计算测试集的mse
loss = model.evaluate(x=x_test, y=y_test, batch_size=32)
print('Test dataset mse: ', loss)
得到的loss如下:
1/1 [==============================] - 0s 1ms/step - loss: 1.1380
Test dataset mse: 1.1379549503326416
模型预测
使用到的api:
tf.keras.Sequential.predict
用到的参数:
- x:需要做预测的数据集。
返回:预测值
# 对测试集做预测
y_test_pred = model.predict(x=x_test)
# 画出数据集的散点图和预测直线
plt.scatter(x_test, y_test, color='g', label='test dataset')
plt.scatter(x_train, y_train, color='b',label='train dataset')
plt.plot(np.sort(x_test), y_test_pred[np.argsort(x_test)], color='r', label='linear regression')
plt.legend()
plt.grid(True)
plt.show()
预测面积为35平米的房屋租赁价格
result = model.predict(np.array([35]))
print('Renting price: {:.2f}'.format(result.item()))
查看线性回归模型的系数w和截距b
w, b = model.layers[0].get_weights()
print('Weight={0} bias={1}'.format(w.item(), b.item()))
1.2.2 多维线性回归
在预测房价的实际情况中,往往房价会和多方面因素有关系。
比如:
楼层数,房间数,房屋年龄等等(这些特征均与面积一样)
是否为学区房,周围是否有公园、医院,是否带有电梯等等(拥有两个选项无法用数字描述的属性,是或者否)
小区的地点、位置在几环哪个路段等等(拥有多个无法用数字描述的属性,比如,幸福小区,爱家小区等多个小区)
问题分析:
第一类特征直接输入即可,和面积相同
第二类特征使用0-1编码
第三类特征使用独热编码(One hot编码)
那么,一组特征值,就能对应一个最终的房屋价格,这样,只要修改x_train和y_train 就可以了