Tensorflow 线性回归预测房价实例

在本节中将经过一个预测房屋价格的实例来说解利用线性回归预测房屋价格,以及在tensorflow中如何实现
html

1.1. 准备工做

从网上获得的数据能够看到房屋价格与房屋尺寸的一个对比关系,以下图:python

2017-09-01-13-36-10

咱们假设x轴(房屋尺寸)而Y轴(房屋价格)依据上表数据绘制折线图算法

2017-09-01-13-37-04

如今咱们使用简单的线性模型来预测,跨域

  • 红线表述咱们的预测曲线 : \[y_p=ax+b\]
  • 蓝线表述房屋价格与尺寸的实际关系
  • 预测与实际的不一样用黄线表示
    2017-09-01-13-39-58

接下来须要经过数据来找到a,b的最佳值从而使预测与实际的偏差最小。这次咱们采用SSE(和方差)来判别偏差。该统计参数计算的是拟合数据和原始数据对应点的偏差的平方和,计算公式以下markdown

\[\frac{1}{2}\sum_{k=1}^{n} \ {({y} -{y_p})^2}\]app

在拿到原始的数据后,为方便运算,咱们将数据进行归一化处理,归一化计算公式以下ide

\[\frac{x-x_{min}}{x_{max}-x_{min}}\]函数

1.2. 归一化数据

咱们将原始的数据进行归一化处理,归一化处理后的结果如图:性能

2017-09-01-14-04-28

def normalize(arr):
    arr_min = np.min(arr)
    arr_max = np.max(arr)
    arr_out = []
    for item in arr:
        out = np.divide(np.subtract(item, arr_min), np.subtract(arr_max, arr_min))
        arr_out = np.append(arr_out, np.array(out))
    return arr_out

1.3. 用随机的值填充a,b并计算偏差,偏差采用上文所使用SSE(和方差)

2017-09-01-14-07-11

def model(x, b, a):
    # linear regression is just b*x + a, so this model line is pretty simple
    return tf.multiply(x, b) + a

loss = tf.multiply(tf.square(Y - y_model), 0.5)

1.4. 计算偏差梯度

对sse分别求a,b的偏微分
\[\frac{\partial sse}{\partial a}\]
\[\frac{\partial sse}{\partial b}\]学习

2017-09-01-14-22-22

1.5. 调整参数直到SSE参数最小

2017-09-01-14-24-10

新 a = a – r * ∂SSE/∂a = 0.45-0.01*3.300 = 0.42

新 b = b – r * ∂SSE/∂b= 0.75-0.01*1.545 = 0.73

(r是学习率,表示调整的步长)

# construct an optimizer to minimize cost and fit line to mydata
train_op = tf.train.GradientDescentOptimizer(0.01).minimize(loss)

而后再重复上一步骤计算,直到所设定的次数完成

2017-09-01-14-26-44

for i in range(500):
    for (x, y) in zip(trX, trY):
        output = sess.run(train_op, feed_dict={X: x, Y: y})

经过刚才几步的组合,程序便能计算出最合适的a,b的值,完成代码清单以下:

import tensorflow as tf
import numpy as np

sess = tf.Session()


# 线性模型 y=bx+a
def model(x, b, a):
    return tf.multiply(x, b) + a


# 归一化函数
def normalize(arr):
    arr_min = np.min(arr)
    arr_max = np.max(arr)
    arr_out = []
    for item in arr:
        out = np.divide(np.subtract(item, arr_min), np.subtract(arr_max, arr_min))
        arr_out = np.append(arr_out, np.array(out))
    return arr_out

# 原始数据
trX_i = [1100., 1400., 1425., 1550., 1600., 1700., 1700., 1875., 2350., 2450.]
trY_i = [199000., 245000., 319000., 240000., 312000., 279000., 310000., 308000., 405000., 324000.]

# 数据归一化
trX = normalize(trX_i)
trY = normalize(trY_i)

X = tf.placeholder(tf.float32)
Y = tf.placeholder(tf.float32)

# 设一个权重变量b,和一个误差变量a
b = tf.Variable(0.0, name="weights")
# create a variable for biases
a = tf.Variable(0.0, name="biases")
y_model = model(X, b, a)

# 损失函数
loss = tf.multiply(tf.square(Y - y_model), 0.5)

# 梯度降低
train_op = tf.train.GradientDescentOptimizer(0.01).minimize(loss)

init = tf.global_variables_initializer()
sess.run(init)

# 训练数据
for i in range(500):
    for (x, y) in zip(trX, trY):
        output = sess.run(train_op, feed_dict={X: x, Y: y})

print('b:' + str(sess.run(b)) + ' || a:' + str(sess.run(a)))


---result

b:0.682465 || a:0.1512

1.6. 概念

1.6.1. 简单线性回归

在房价预测例子中,咱们发现房价数据呈一种比较明显的线性关系,那么天然咱们可能会选择简单线性回归对数据进行拟合,首先从线性模型着手:
\[y_p=ax+b\]
从上面的二元一次方程看出,咱们的输入x是已知向量,只要咱们求出a,b的值,就能经过上述公式进行房价预测了,这就是简单线性回归的思想。

1.6.2. 梯度降低

梯度

如上一节中讲的咱们须要找出SSE最小化时的a,b的值,采用的这种方法就叫作梯度降低。梯度降低不只仅局限于最小化这个函数,也可能根据实际状况须要最大化某个函数,这种状况叫作梯度上升。单纯从数学上讲,对一个函数来讲,梯度表示某个向量的偏导数,同时还表明了该向量的方向,在这个方向上,函数增长得最快,在相反的方向上,函数减少得最快。
利用梯度这一性质,咱们采用梯度降低算法去最小化咱们的损失函数,咱们在梯度的反方向跨域一小步,再从一个新起点开始重复这个过程,直到咱们找到损失函数的最小值,最后肯定咱们的a, b值。
咱们须要最小化的函数为(又称为损失函数):
\[sse=\frac{1}{2}\sum_{k=1}^{n} \ {({y} -{y_p})^2}=\frac{1}{2}\sum_{k=1}^{n} \ {(y_k-ax_k-b)^2}\]
对a,b分别求偏导,并令偏导等于0:
\[\frac{\partial sse}{\partial a}=- \sum_{k=1}^n \ x_k(y_k-ax_k-b) \ =0\]
\[\frac{\partial sse}{\partial b}=- \sum_{k=1}^n \ (y_k-ax_k-b) =0\]
最后,输入已知的xy值(均为向量),解两个一次方程就计算出a,b的确切值。

步长

为了求SSE的最小值,咱们须要向梯度相反的方法移动,每移动一步,梯度逐渐下降,可是移动多少才合适呢,这须要咱们谨慎的选择步长。目前,主流的选择方法有:
• 使用固定步长
• 随时间增加逐步减少步长
• 在每一步中经过最小化目标函数的值来选择合适的步长
在上一例子中,咱们选择固定步长r=0.01,其实,最后一种方法很好,但它的计算代价很大。咱们还能够尝试一系列步长,并选出使目标函数值最小的那个步长来求其近似值。
stepSizes=[10, 1, 0.1, 0.01, 0.001]

1.6.3 损失函数

损失函数是用来评价模型的预测值与真实值的不一致程度,它是一个非负实值函数。一般使用L(Y,f(x))来表示,损失函数越小,模型的性能就越好。
在预测房价的例子中,咱们使用了和方差来计算偏差,并把该函数称为损失函数,即计算实际值和预测值的偏差平方和。为何要选择这一函数来计算偏差,而不采用绝对值偏差,或偏差的三次方,四次方来定义偏差函数是由于:

  1. 相对于绝对值偏差,偏差平方和计算更加方便。
  2. 这里的损失函数使用的是“最小二乘法”的思想,假定咱们的偏差知足均值为0的高斯分布,这样符合通常的统计规律,而后根据最大似然函数估计进行推导,就得出了求导结果,平方和最小公式:
    \[sse=\frac{1}{2}\sum_{k=1}^{n} \ {({y} -{y_p})^2}\]

除上面提到的损失函数外,还有其余的一些常见的损失函数:

0-1 Loss

若是预测值与标值不等,则记为1;若是相等,则标记为0
\[L(Y, f(x)) = \left\{ \begin{array}{ll} 1 & \textrm{$Y\neq f(x)$}\\ 0 & \textrm{$Y= f(x)$} \end{array} \right. \]

Log对数损失函数

在逻辑回归中损失函数的推导是假设样本服从伯努利分布(0-1分布),而后求知足该分布的似然函数,最后推导出顺势函数的公式为:\[L(Y,P(Y|X)) = -logP(Y|X)\]

指数损失函数

出如今Adaboost算法中
\[L(y,f(x))=\frac{1}{n}\sum_{i=1}^{n}\ {exp[-y_if(x_i)]}\]

Hinge损失函数

在线性支持向量机中,Hinge的损失函数标准形式为:
\[L(y)=\frac{1}{n}\sum_{i=1}^{n}\ {l(wx_i+by_i)}\]

绝对值损失函数

\[L(y,f(x))=|Y-f(x)|\]

1.6.4 特征归一化

对于多属性的样本,咱们在作分类预测的时候,应该把每一个属性看做同等重要,不能让某个属性的计算结果严重影响模型的预测结果。例如,如下有一个样本数据:

玩游戏所耗时间百分比 描述每一年得到的飞行常客里程数 每周消费的冰淇淋公升数
0.8 400 0.5
12 134000 0.9
0 20000 1.1
67 32000 0.1

若是咱们采用KNN算法作分类预测,在计算欧式距离的时候,好比计算样本3和样本4之间的距离,很明显咱们发现每一年得到的飞行常客里程数因为自己数值很大,其计算结果的影响将远远大于其余两个特征值的影响,对于三个等权重的特征之一,咱们不能让它严重的影响计算结果,因此,咱们一般会采用特征归一化的方法把值处理为0到1或者-1到1之间。
\[\sqrt{(0-67)^2+(20000-32000)^2+(1.1-0.1)^2}\]
即上面提到的公式:
\[\frac{x-x_{min}}{x_{max}-x_{min}}\]
其中\(x_{min}\)\(x_{max}\)是特征向量x的最小值和最大值,这样经过对每一个特征向量进行归一化处理,全部特征值的计算都统一了,而计算获得的结果就更加准确。
在以前预测房价的例子中,咱们对已有的特征向量,即房屋大小和实际价格作了归一化处理,即使是只有一个特征向量,咱们仍然须要这样作,其目的与上面的样本数据同样,好比假设咱们须要在该房屋预测中增长房间数量或房屋年龄等特征进行房屋价格预测,咱们均可以采用同一类方法进行处理,以减小各特征值对计算结果的影响。


参考连接

【1】:http://www.kdnuggets.com/2017/04/simple-understand-gradient-descent-algorithm.html

做者:帅虫哥 出处: http://www.cnblogs.com/vipyoumay/p/7488954.html

相关文章
相关标签/搜索