线性代数基本知识编程演示
准备数据
建立模型
多元线性回归模型
Y = x 1 x w 1 + x 2 x w 2 + … + x 12 x w 12 + b
训练模型
进行预测
%matplotlib notebook
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn.utils import shuffle
### 1. 读取数据文件
df = pd.read_csv("data/boston.csv", header=0)
# 显示数据摘要信息
# print(df.describe())
# 显示所有数据
# print(df)
df = df.values # 获取值,二维数组
# print(df)
df = np.array(df) # 转为numpy数组
# 归一化数据,所有数据范围都搞到[0,1]
# 由于每个特征对标签的影响贡献不同,甚至差异巨大,导致对应的权重就差距巨大
# 如果某个特征对标签的影响贡献很大,那么对应的权重就很大,就有可能权重越界。。
for i in range(12):
df[:, i] = (df[:, i] - df[i:, i].min()) / (df[:, i].max() - df[i:, i].min())
# 前12列特征数据(0-11)
x_data = df[:, :12]
# 最后一列标签数据(12)
y_data = df[:, 12]
# print(x_data, x_data.shape)
# print(y_data, y_data.shape)
### 2. 建立模型
x = tf.placeholder(tf.float32, [None, 12], name="X") # 12列特征数据,行数任意
y = tf.placeholder(tf.float32, [None, 1], name="Y") # 1列标签数据,行数任意
# 定义一个命名空间,Model下的所有语句成为一个整体,对应到计算图中的一个子图
with tf.name_scope("Model"):
# w初始化为shape=(12,1)的列向量
w = tf.Variable(tf.random_normal([12,1], stddev=0.01), name="W")
b = tf.Variable(1.0, name="b")
# 定义模型(多元线性回归)
def model(x, w, b):
return tf.matmul(x, w) + b
# 预测值
pred = model(x, w, b)
### 3. 训练模型
# 迭代伦次
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 = []
for epoch in range(train_epochs):
loss_sum = 0 # 计算每轮损失
for xs, ys in zip(x_data, y_data):
xs = xs.reshape(1, 12) # 把一维向量搞成二维的,要填充到x
ys = ys.reshape(1, 1)
_, loss = sess.run([optimizer, loss_function], feed_dict={x:xs, y:ys})
loss_sum += loss
wtmp = w.eval(session=sess) # 每轮训练之后的w
btmp = b.eval(session=sess)
loss_average = loss_sum / len(y_data) # 每轮平均损失
loss_list.append(loss_average)
# 打印每一轮训练得到的信息
# print("epoch=", epoch+1, "\n", "loss_average=", loss_average, "\n", \
# "w=", wtmp, "\n", "b=", btmp)
# 每轮训练之后,打乱数据顺序,为下轮训练做准备。
# 就像课程中吴老师所讲,让你学习认识图片上的甲骨文,如果你记住了第几张图片上的
# 甲骨文是啥,那就不需要真的认识甲骨文了,只需要知道图片是第几张,就知道对应的
# 甲骨文是啥了。。然而这并没有真正认识甲骨文。类比,每轮训练结束,打乱数据顺序。
x_data, y_data = shuffle(x_data, y_data) # 打乱数据
# 打印损失可视化
plt.plot(loss_list)
### 4. 预测
n = np.random.randint(506)
x_test = x_data[n]
x_test = x_test.reshape(1, 12)
predict = sess.run(pred, feed_dict={x:x_test})
print("n=", n)
print("标签值=%f" % y_data[n])
print("预测值=%f" % predict)
### 思考:所有数据都用来做训练了?
### 不应该把考试的题目范围都局限在平时的训练题中。