TensorFlow实现多元线性回归
多元线性回归指自变量有多个,区别于一元线性回归。多元线性回归的情况下,由于每个特征具有不同的值范围,归一化变得至关重要。这里是波士顿房价数据集的多重线性回归的代码,使用13个输入特征。
具体实现
导入软件包
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
归一化和处理
因为各特征的数据范围不同,需要归一化特征数据。为此定义一个归一化函数。另外,这里添加一个额外的固定输入值将权重和偏置结合起来。为此定义函数append_bias_reshape()。该技巧有时可有效简化编程:
def normalize(X):
"""Normalizes the array X"""
mean = np.mean(X)
std = np.std(X)
X = (X - mean) / std
return X
def append_bias_reshape(features, labels):
m = features.shape[0]
n = features.shape[1]
x = np.reshape(np.c_[np.ones(m), features], [m, n + 1])
y = np.reshape(labels, [m, 1])
return x, y
数据预处理
现在使用TensorFlow contrib数据集加载波士顿房价数据集,并将其划分为X_train和Y_train。注意到X_train包含所需要的特征。可以选择在这里对数据进行归一化处理,也可以添加偏置并对网络数据重构:
boston = tf.contrib.learn.datasets.load_dataset('boston') # 加载数据集
X_train, Y_train = boston.data, boston.target # 获取自变量和因变量
X_train = normalize(X_train) # 数据归一化
X_train, Y_train = append_bias_reshape(X_train, Y_train) # 添加偏置的数据重构
m = len(X_train) # 训练实例的数目
n = 13 + 1 # 特征数+偏置
声明占位符
# Placeholder for the training data
X = tf.placeholder(tf.float32, name='X', shape=[m, n])
Y = tf.placeholder(tf.float32, name='Y')
初始化
为权重和偏置创建TensorFlow变量。通过随机数初始化权重:
# Variables for coefficients
w = tf.Variable(tf.random_normal([n, 1]))
b = tf.Variable(0.0)
定义模型
定义要用于预测的线性回归模型。现在需要矩阵乘法来完成这个任务:
# The Linear Regression Model
Y_hat = tf.matmul(X, w) + b
损失函数
为了更好地求微分,定义损失函数:
# Loss function
loss = tf.reduce_mean(tf.square(Y - Y_hat), name='loss')
优化器
# Gradient Descent with learning rate of 0.01 to minimize loss
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(loss)
初始化变量
# Initializing Variables
init_op = tf.global_variables_initializer()
total = [] # 记录平均loss随训练次数的变化
计算图
with tf.Session() as sess:
# 初始化变量
sess.run(init_op)
writer = tf.summary.FileWriter('graphs', sess.graph)
# 训练100个回合
for i in range(100):
_, l = sess.run([optimizer, loss], feed_dict={X: X_train, Y: Y_train})
total.append(l)
print('Epoch {0}: Loss {1}'.format(i, l))
writer.close()
w_value, b_value = sess.run([w, b])
绘制损失函数
plt.title('Loss')
plt.xlabel('Epochs')
plt.ylabel('Total Loss')
plt.plot(total)
plt.show()
在这里,我们发现损失函数随着训练过程的进行而减少:
本节使用了13个特征来训练模型。简单线性回归和多元线性回归的主要不同在于权重,且系数的数量始终等于输入特征的数量。下图为所构建的多元线性回归模型的TensorBoard图:
现在可以使用从模型中学到的系数来预测房价:
N = 500 # 实例的索引编号
X_new = X_train[N, :]
Y_pred = (np.matmul(X_new, w_value) + b_value).round(1)
print('Predicted value: ${0} Actual value: ${1}'.format(Y_pred[0] * 1000,
Y_train[N][0] * 1000), '\nDone')