房价预测模型是一种简单的线性模型,属于监督学习的一种,给一些输入参数比如房屋面积、卧室数量等做,然后结合给定的价格标签做预测。
import pandas as pd
import seaborn as sns
sns.set(context="notebook", style="whitegrid", palette="dark")
导入做数据分析的pandas库,用seaborn来做可视化。
sns.set是seaborn的一个环境设置方法,具体使用规则可以输入sns.set?
查看(jupyter中)。将上下文环境设置为notebook,白色背景,黑色线。
df0 = pd.read_csv('data0.csv', names=['square', 'price'])
sns.lmplot('square', 'price', df0, height=6, fit_reg=False)
data0.csv文件存放了单变量房价预测所要用的数据,第一列是面积,第二列是价格。用pandas的方式读入数据。
用sns.Implot方法可视化这些数据。设置相关参数如:x轴的名称“square”,y轴的名称“price”,所需数据“df0”,图的大小。fit_reg意思就是是否需要拟合这些散点(fit regression),False和True的结果分别如下
结果如下图所示:
如果要看下前5行的数据,可以用
df0.head(5) # 也可以直接输入df0看全部的数据
还有如果要看具体信息的话可以输入
df0.info()
在这里的输出情况如下
RangeIndex: 47 entries, 0 to 46
Data columns (total 2 columns):
square 47 non-null int64
price 47 non-null int64
dtypes: int64(2)
memory usage: 832.0 bytes
简单了解之后再来看下多变量房价预测
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
df1 = pd.read_csv('data1.csv', names=['square', 'bedrooms', 'price'])
df1.head()
到如用到的库,这里用pyplot创建图片,用mplot3D绘制3D图。
从data.csv文件中导入数据。输入是房屋的面积和房间卧室数量,输出是房屋价格。
fig = plt.figure() # 创建一个原始图
# 创建一个 3D 对象
ax = plt.axes(projection='3d')
# 设置 3 个坐标轴的名称
ax.set_xlabel('square')
ax.set_ylabel('bedrooms')
ax.set_zlabel('price')
# 绘制 3D 散点图
ax.scatter3D(df1['square'], df1['bedrooms'], df1['price'], c=df1['price'], cmap='Blues')
最后一行代码中的c=df1['price']
表示以价格的变化情况来控制散点颜色深度的变化,颜色设置为蓝色。
为解决数据单位和范围的问题,通常要数据规范化。
def normalize_feature(df):
return df.apply(lambda column: (column - column.mean()) / column.std())
df = normalize_feature(df1)
df.head()
规范化处理后的数据如下
square bedrooms price
0 0.130010 -0.223675 0.475747
1 -0.504190 -0.223675 -0.084074
2 0.502476 -0.223675 0.228626
3 -0.735723 -1.537767 -0.867025
4 1.257476 1.090417 1.595389
处理之后的图像如下
ax = plt.axes(projection='3d')
ax.set_xlabel('square')
ax.set_ylabel('bedrooms')
ax.set_zlabel('price')
ax.scatter3D(df['square'], df['bedrooms'],df['price'],c=df['price'],cmap=['Reds'])
df.info()
RangeIndex: 47 entries, 0 to 46
Data columns (total 3 columns):
square 47 non-null float64
bedrooms 47 non-null float64
price 47 non-null float64
dtypes: float64(3)
memory usage: 1.2 KB
线性模型如 y = w 0 + w 1 ∗ x 1 + w 2 ∗ x 2 y = w0 + w1*x1 + w2*x2 y=w0+w1∗x1+w2∗x2,为了能用矩阵运算,就需要添加一个x0,模型变成 y = w 0 ∗ x 0 + w 1 ∗ x 1 + w 2 ∗ x 2 y = w0*x0 + w1*x1 + w2*x2 y=w0∗x0+w1∗x1+w2∗x2,矩阵表达就是 y = W ∗ X y = W*X y=W∗X
import numpy as pd
ones = pd.DataFrame({'ones':np.ones(len(df))}) # 产生行数n=len(df),列数为1的数据(ones的数据都是1)
df = pd.concat([ones, df], axis = 1) # 用pd.concat方法根据列合并(axis=1表示合并列)
df.head()
输入如下
ones square bedrooms price
0 1.0 0.130010 -0.223675 0.475747
1 1.0 -0.504190 -0.223675 -0.084074
2 1.0 0.502476 -0.223675 0.228626
3 1.0 -0.735723 -1.537767 -0.867025
4 1.0 1.257476 1.090417 1.595389
数据信息如下
RangeIndex: 47 entries, 0 to 46
Data columns (total 4 columns):
ones 47 non-null float64
square 47 non-null float64
bedrooms 47 non-null float64
price 47 non-null float64
dtypes: float64(4)
memory usage: 1.5 KB
输入数据 X X X应该为ones、square和bedrooms三列,输出 y y y是price。从所有的数据df中分离出来
X_data = np.array(df[df.columns[0:3]])
y_data = np.array(df[df.columns[-1]]).reshape(len(df), 1)
print(X_data.shape, type(X_data))
print(y_data.shape, type(y_data))
用数组的方式提取
(47, 3)
(47, 1)
import tensorflow as tf
alpha = 0.01 # 即学习率 learning rate
epoch = 500 # 训练所有数据集所要迭代的轮数
# 定义占位符 X shape [47,3], y shape [47,1]
X = tf.placeholder(tf.float32, X_data.shape)
y = tf.placeholder(tf.float32, y_data.shape)
# 定义权重变量 W, shape [3,1]
W = tf.get_variable("weights", (X_data.shape[1], 1), initializer = tf.constant_initializer())
# 预测值 y_pred shape [47,1]
y_pred = tf.matmul(X, W)
# 损失函数采用最小二乘法((y1-y2)^2/(2*n)).
# y_pred-y 是[47,1]的矩阵,矩阵相乘要用转置.
# tf.matmul(a,b,transpose_a=True) 即表示a的装置乘b([1,47]×[47,1]=[1,1])
loss_op = 1 / (2 * len(X_data)) * tf.matmul((y_pred - y), (y_pred, y), transpose_a=True)
# 选用梯度下降优化器优化数据
opt = tf.train.GradientDescentOptimizer(learninf_rate = alpha)
# 梯度下降最小化目标函数,单轮训练操作
train_op = opt.minimize(loss_op)
with tf.Session() as sess:
# 初始化全局变量
sess.run(tf.global_variables_initializer())
# 开始训练模型
for e in range(epoch + 1):
sess.run(train_op, feed_dict={X: X_data, y: y_data})
# 每10次输出一次结果
if e % 10 ==0:
loss, W = sess.run([loss_op, W], feef_dict = {X:X_data, y:y_data})
log_str = "Epoch %d \t Loss=%d \t Model: Y = %.4gx1 + %.4gx2 + %.4g"
print(log_str % (e, loss, W[1], W[2], W[0]))
输出结果如下:
Epoch 10 Loss=0.4116 Model: y = 0.0791x1 + 0.03948x2 + 3.353e-10
Epoch 20 Loss=0.353 Model: y = 0.1489x1 + 0.07135x2 + -5.588e-11
Epoch 30 Loss=0.3087 Model: y = 0.2107x1 + 0.09676x2 + 3.912e-10
···
Epoch 480 Loss=0.1322 Model: y = 0.8254x1 + 0.005641x2 + 3.663e-09
Epoch 490 Loss=0.1321 Model: y = 0.828x1 + 0.003183x2 + 4.2e-09
Epoch 500 Loss=0.132 Model: y = 0.8304x1 + 0.0008239x2 + 4.138e-09
可以看到,随着不断的迭代,损失值不断减小,输出的模型也不断优化,最终的模型:Model: y = 0.8304x1 + 0.0008239x2 + 4.138e-09。
以上就是房价预测模型实现的整个过程。下面用TensorBoard可视化一下这个模型。(在文章末尾的附录部分,小编也对TensorBoard简单进行了介绍,不了解的可以先看下附录部分)
TensorBoard可视化需要先在会话里创建一个FileWriter的实例。(对以上创建会话的代码简单修改)
with tf.Session() as sess:
# 初始化全局变量
sess.run(tf.global_variables_initializer())
#创建 FileWriter 实例
writer = tf.summary.FileWriter("./summary/linear-regression-0", sess.graph)
# 放在当前目录的summary/linear-regression-0目录下面
# 开始训练模型
for e in range(epoch + 1):
sess.run(train_op, feed_dict={X: X_data, y: y_data})
# 每10次输出一次结果
if e % 10 ==0:
loss, W = sess.run([loss_op, W], feef_dict = {X:X_data, y:y_data})
log_str = "Epoch %d \t Loss=%d \t Model: Y = %.4gx1 + %.4gx2 + %.4g"
print(log_str % (e, loss, W[1], W[2], W[0]))
# 关闭 FileWriter 的输出流
writer.close()
执行之后,会看到相应生成一个event file,把它加载到tensorboard中,方法如下:
cmd进入当前虚拟环境,输入tensorboard --logdir ./ --host localhost
。 第一个参数’–logdir ./’ 表示使用当前目录,第二个参数‘-- host localhost’ 表示位置为本地主机。(如果在windows系统遇到无法安装TensorBoard的问题,参考一下我的这篇博客([windows在虚拟环境中启动TensorBoard的问题])
流图界面如图所示:
双击流图节点可以看到详细信息,会显示计算流程,但还是比较复杂混乱。这只是做了一个线性模型,如果更复杂的神经网络肯定没法理解。
所以我们就需要用名字作用域来创建数据流图。
需要对数据流图部分代码做简单修改。(使用方式不理解的话可以参考文后附录)
import tensorflow as tf
alpha = 0.01 # 即学习率 learning rate
epoch = 500 # 训练所有数据集所要迭代的轮数
with tf.name_scope('input'):
# 定义占位符 X shape [47,3], y shape [47,1]
X = tf.placeholder(tf.float32, X_data.shape, name = 'X') # 给输入命名,以便在流图中可见
y = tf.placeholder(tf.float32, y_data.shape) # 给输出命名
with tf.name_scope('hypothesis'):
# 定义权重变量 W, shape [3,1]
W = tf.get_variable("weights", (X_data.shape[1], 1), initializer = tf.constant_initializer())
# 预测值 y_pred shape [47,1]
y_pred = tf.matmul(X, W, name = 'y_pred')
with tf.name_scope('loss'):
# 损失函数采用最小二乘法((y1-y2)^2/(2*n)).
# y_pred-y 是[47,1]的矩阵,矩阵相乘要用转置.
# tf.matmul(a,b,transpose_a=True) 即表示a的装置乘b([1,47]×[47,1]=[1,1])
loss_op = 1 / (2 * len(X_data)) * tf.matmul((y_pred - y), (y_pred, y), transpose_a=True)
with tf.name_scope('train'):
# 选用梯度下降优化器优化数据
opt = tf.train.GradientDescentOptimizer(learninf_rate = alpha)
# 梯度下降最小化目标函数,单轮训练操作
train_op = opt.minimize(loss_op)
然后把创建会话部分流图保存的文件位置改为"./summary/linear-regression-1"
运行代码之后,刷新之前打开的TensorBoard可以看到在对应路径下新生成的流图。
双击单个部分可以看到内部的详细流程
可以看到只有这种有名字作用域的流图在深度网络中才有意义。
最后再把损失值得变化情况可视化一下。前面在模型实现部分就看到随着不断的迭代,损失值loss也在不断减小,现在直观看一下。
对上面创建会话部分的代码简单修改如下:
with tf.Session() as sess:
# 初始化全局变量
sess.run(tf.global_variables_initializer())
#创建 FileWriter 实例
writer = tf.summary.FileWriter("./summary/linear-regression-1", sess.graph)
# 放在当前目录的summary/linear-regression-1目录下面
loss_data=[] # 记录所有损失值
# 开始训练模型
for e in range(epoch + 1):
sess.run(train_op, feed_dict={X: X_data, y: y_data})
# 每10次输出一次结果
loss_data.append(float(loss)) # 记录每一次损失值的变化情况
if e % 10 ==0:
loss, W = sess.run([loss_op, W], feef_dict = {X:X_data, y:y_data})
log_str = "Epoch %d \t Loss=%d \t Model: Y = %.4gx1 + %.4gx2 + %.4g"
print(log_str % (e, loss, W[1], W[2], W[0]))
# 关闭 FileWriter 的输出流
writer.close()
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(contexy='notebook', style='whitegrid', palette='dark')
ax = sns.lineplot(x='epoch', y='loss', data=pd.DataFrame({'loss':loss_data, 'epoch':np.arrange(epoch)}))
ax.set_xlabel('epoch')
ax.set_ylabel('loss')
plt.show()
从图像可以看出,第200轮以后,loss值已经很低了,再往后的变化很小。当然在TensorBoard中也能查到详细信息。复杂模型里用TensorBoard更方便简洁,也能节省内存。
=================================
TensorBoard就是为了可是化深度网络的流图而产生的。
TensorBoard有什么用?
TensorBoard可视化工具
在数据处理过程中,用户通常想要可视化地直观常看数据集分布情况;
在模型设计过程中,用户往往需要分析和检查数据流图是否正确实现;
在模型训练过程中,用户也常常需要关注模型参数和超参数变化趋势;
在模型测试过程中,用户也往往需要查看准确率和召回率等评估指标。
TensorBoard通过展示直观的图形,理解算法模型及其工作流程,提升模型开发工作效率。
可视化的数据是数据流图和张量,它们需要在会话中加载或执行操作后才能获取。用户需要用FileWriter实例将这些数据写入事件文件(event file)。最后,启动TensorBoard程序,加载event file 中的序列化数据,从而可以在各个面板中展示对应的可视化对象。
结合前面房价模型的例子相信很容易理解。
所以工作流概括为:创建数据流图——>创建FileWriter实例——>启动TensorBoard
流程中使用的FileWriter实例和汇总操作(Summary Ops)都属于tf.summary模块。该模块主要功能就是获取和输出与模型相关的序列化数据。使用TensorBoard可视化的过程中必要的工具模块。该模块的核心部分如下:
也就是把细节信息分装在模块中,可以理解成层级结构。
使用如下:(结合具体前面可以更深入理解)
with tf.name_scope():
,给占位符和变量赋予相应的名字,看图更容易理解。
方式如下:writer = tf.summary.FileWriter()
.
之前看到一篇关于TensorBoard的blog不错,分享给大家,有兴趣的朋友可以看看【https://blog.csdn.net/u010099080/article/details/77426577】