一、问题描述
波士顿房价数据集包括506个样本,每个样本包括12个特征变量和该地区的平均房价。房价显然与多个特征变量有关,故选择多个特征变量来建立线性方程,这就是多元线性回归问题。
二、读取数据
1. 数据集解读
波士顿房价数据集
2. 读取数据
%matplotlib notebook
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd #读取数据的库,数据结构自动转换为Numpy的多维数组
from sklearn.utils import shuffle
#读取数据文件
df = pd.read_csv("data/boston.csv", header = 0)
#显示数据摘要描述信息
print(df.describe()) #平均值、最大值、最小值等
#显示所有数据
print(df)
boston数据摘要
#获取df的值
df = df.values
#把 df 转换成 np 的数组格式
df = np.array(df)
#x_data 为前 12 列特征数据
x_data = df[:, :12]
#y_data 为最后 1 列标签数据
y_data = df[:, 12]
#可打印出来查看具体数据和形状
#print(x_data,'\n shape=', x_data.shape)
#print(y_data,'\n shape=', y_data.shape)
3. 数据建模
房价与多个特征变量有关,使用多元线性回归建模,结果可以由不同特征的输入值和对应的权重相乘求和,加上偏置项计算求解。
boston矩阵运算模型
-
定义特征数据和标签的占位符
shape中None表示行的数量未知,在实际训练时决定一次代入多少行样本,从一个样本的随机SDG到批量SDG都可以。
#定义特征数据和标签数据的占位符
x = tf.placeholder(tf.float32, [None, 12], name = "X") #12个特征数据(12列)
y = tf.placeholder(tf.float32, [None, 1], name = "Y") #1个标签数据(1列)
- 定义模型结构
#定义了一个命名空间
with tf.name_scope("Model"):
#w 初始化值为shape=(12,1)的随机数
w = tf.Variable(tf.random_normal([12,1], stddev = 0.01), name = "W")
#b 初始化值为 1.0
b = tf.Variable(1.0, name = "b")
#w和x 是矩阵相乘,用matmul,不能用mutiply或者*
def model(x, w, b):
return tf.matmul(x, w) + b
#预测计算操作,前向计算节点
pred = model(x, w, b)
4. 模型训练
- 设置训练超参数
#迭代轮次
train_epochs = 50
#学习率
learning_rate = 0.01
- 定义均方差损失函数
#定义损失函数
with tf.name_scope("LossFunction"):
loss_function = tf.reduce_mean(tf.pow(y - pred, 2)) #均方误差
- 选择优化器
# 创建优化器-梯度下降优化器
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss_function)
- 启动会话
#声明会话
sess = tf.Session()
#定义初始化所有变量的操作
init = tf.global_variables_initializer()
#启动会话
sess.run(init)
- 迭代训练
#loss_list = [] #用于保存loss值的列表
#迭代训练
for epoch in range(train_epochs):
loss_sum = 0.0
for xs, ys in zip(x_data, y_data):
xs = xs.reshape(1, 12) #为了使得feed数据与placeholder的shepe一致
ys = ys.reshape(1, 1) #如 8 reshape 成 [8]
_, loss = sess.run([optimizer, loss_function], feed_dict = {x: xs, y: ys})
loss_sum = loss_sum + loss #累计损失和
#打乱数据顺序(免得机器预测的准确性是因为记住了数据顺序,而不是学习得到的结果)
x_data, y_data = shuffle(x_data, y_data)
b0temp = b.eval(session = sess)
w0temp = w.eval(session = sess)
loss_average = loss_sum/len(y_data)
loss_list.append(loss_average) #每轮添加一次
print("epoch=", epoch+1, "loss=", loss_average, "b=", b0temp, "w=", w0temp)
#epoch默认从0开始故加1
# 部分输出结果:
# epoch= 50 loss= 23.2618146344 b= 29.5004 w= [[ -9.82677174]
# [ 4.31687546]
# [ 0.43684608]
# [ 2.7463789 ]
# [ -8.32740021]
# [ 20.50283623]
# [ 0.6644336 ]
# [-15.10861492]
# [ 6.10050821]
# [ -6.39524317]
# [ -8.42674637]
# [-19.60347939]]
- 可视化损失值
plt.plot(loss_list)
5. 模型应用
模型一般应该用来预测新的样本值,本例506条数据都用来训练了,于是随机抽取一条来看看结果。
#指定一条看看效果
n = 348
x_test = x_data[n]
x_test = x_test.reshape(1, 12)
predict = sess.run(pred, feed_dict = {x: x_test})
print("预测值:%f" % predict)
target = y_data[n]
print("标签值:%f" %target)
# 预测值:22.470255
# 标签值:17.800000
#随机抽取一条看看
n = np.random.randint(506)
print(n)
x_test = x_data[n]
x_test = x_test.reshape(1, 12)
predict = sess.run(pred, feed_dict = {x: x_test})
print("预测值:%f" % predict)
target = y_data[n]
print("标签值:%f" %target)
# 275
# 预测值:43.649399
# 标签值:50.000000