
1.1 机器学习的基础
ML是一个描述使用一组通用算法分析数据的过程的概念,它能提供你感兴趣的数据,而不用专门编写特定代码。
可以将ML视为黑箱,前沿科学家使用黑箱来实现一些高级功能,比如,检测癫痫病或者癌症,而你的邮件收件箱将会每天使用黑箱过滤垃圾邮件。
从更高的层面上说,ML可以分为监督式学习和非监督式学习。
1.1.1 监督式学习
对于监督式学习,我们的主要任务是编写一个函数将输入映射到输出。比如,如果有一个输入变量(x)和一个输出变量(y),那么就可以使用某个算法作为从输入到输出的映射函数:
y = f (x)
我们的目标是尽量实现映射函数,这样当有一个输入(x)的时候,我们可以预测出对应的输出变量(y)。
比如,我们有一堆水果和一些篮子。首先,我们将水果和篮子按照标签分类,如苹果、香蕉、草莓等。当将水果和篮子的标签制作好并将水果放到对应的篮子中之后,现在我们的工作就是标记新添加的水果。我们已经学习了所有的水果品种并用标签将它们标记好了。基于之前的经验,我们可以根据水果的颜色、大小和形状来标记水果的品种。
1.1.2 非监督式学习
在这种情况下,只有输入数据(x),没有对应的输出变量。非监督式学习的目标是对数据的基础结构或分布情况进行建模,由此从数据中学习更多知识。
在非监督式学习中,我们一开始可能没有任何数据。看一下监督式学习中的例子,现在我们有一篮子水果,需要将它们按类分组。但是,我们事先没有任何数据,也没有接受过训练或者用标签加以区分。在这种情况下,我们需要了解输入的对象所处的领域,因为我们不知道它是水果还是其他的东西。所以,首先,要了解每次输入的全部特征。然后,当有新输入的时候,尽量用已有的特征进行匹配。最后,我们可能会将所有红色的水果放到一个篮子中,所有绿色的水果放到另外一个篮子中。这种分类方法并不精确,我们将它称为非监督式学习。
1.1.3 线性回归——监督式学习
看一个线性回归的简单例子,它是由TensorFlow实现的。
根据在相同区域中其他不同大小的房屋价格来预测某个房屋的价格(见下图)。

在我们手上有两栋房屋的价格信息,一栋售价是82 000美元,另外一栋售价是55 000美元。现在,我们的任务是预测第3栋房屋的价格。我们知道房屋的价格和对应房屋的面积,这样可以将已有的数据映射到一张图上。我们根据已有的两个数据推测第3栋房屋的价格。
![]()
现在可能你想知道如何绘制直线。画一条随机的直线以接近图中标记的所有点。计算每个点到线之间的距离,并将它们加到一起。这样得到一个误差值。使用的算法应该最小化误差,因为最合适的直线拥有更小的误差值。这个过程称为梯度下降(gradient descent)。
首先将指定区域中所有房屋的价格都映射到对应的图中(见下图)。

然后,将已知的两栋房屋的价格绘制到图中(见下图)。

之后,绘制一条直线以尽量接近所有的值。这条直线与数据完美吻合。由此,我们应该可以推断出第3栋房屋的价格(见下图)。

根据第3栋房屋的面积,可以将数据映射到图中。接下来,找出连接所有点的直线。从上图中可以看到,y轴映射到了98 300美元,因此可预测第3栋房屋的价格(见下图)。这个过程叫作线性回归(linear regression)。

我们将问题以伪代码的形式展现出来。
def estimate_house_price(sqft, location):
price = 0
#In my area, the average house costs 2000 per sq.ft
price_per_sqft = 2000
if location == "vegas":
#but some areas cost a bit more
price_per_sqft = 5000
elif location == "newyork":
#and some areas cost less
price_per_sqft = 4000
#start with a base price estimate based on how big the place is
price = price_per_sqft * sqft
return price
上面就是预测房价的常见方法。可以添加很多条件,但是当地点或者其他参数越来越多的时候,代码将会变得更加复杂。对于房价预测来说,有很多因素需要考虑,如面积、位置以及附近的学校、加油站、医院、交通状况等。可以先将这个函数简单化,代码如下。
def estimate_house_price(sqft, location):
price = < DO MAGIC HERE >
return price
如何标识一条直线(而不用编写额外的条件检查)呢?一般来说,线性回归线用如下公式表达。
Y = XW +b
在这个例子中,为了便于理解,首先,将上面的公式转换为以下形式。
prediction = X • Weight + bias
其中,prediction表示预测值,Weight表示直线的斜率,bias表示截距(也就是当X=0的时候,Y的值)。
然后,构建线性模型,这时需要确定梯度下降值。根据cost函数确定均方差(mean squared error),以获得梯度下降值。

用伪代码表示cost函数,以解决房价预测的问题。
def estimate_house_price(sqft, location):
price = 0
#and this
price += sqft * 235.43
#maybe this too
price += location * 643.34
#adding a little bit of salt for a perfect result
price += 191.23
return price
值235.43
、643.34
以及191.23
看上去像是随机值,但是这些值可以用来预测新的房屋价格。是如何获得这些值的呢?我们应该使用迭代方法来获得正确的值,以减小在正确方向上的误差。
def estimate_house_price(sqft, location):
price = 0
#and this
price += sqft * 1.0
#maybe this too
price += location * 1.0
#adding a little bit of salt for a perfect result
price += 1.0
return price
因此,先从1.0开始迭代,然后在正确的方向上最小化误差。使用TensorFlow实现下面的代码。后面将会详细解释这些代码。
#import all the necessary libraries
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy
#Random number generator
randnumgen = numpy.random
#The values that we have plotted on the graph
values_X =
numpy.asarray([1,2,3,4,5.5,6.75,7.2,8,3.5,4.65,5,1.5,4.32,1.65,6.08])
values_Y =
numpy.asarray([50,60,65,78,89,104,111,122,71,85,79,56,81.8,55.5,98.3])
# Parameters
learning_rate = 0.01
training_steps = 1000
iterations = values_X.shape[0]
# tf float points - graph inputs
X = tf.placeholder("float")
Y = tf.placeholder("float")
# Set the weight and bias
W = tf.Variable(randnumgen.randn(), name="weight")
b = tf.Variable(randnumgen.randn(), name="bias")
# Linear model construction
# y = xw + b
prediction = tf.add(tf.multiply(X, W), b)
#The cost method helps to minimize error for gradient descent.
#This is called mean squared error.
cost = tf.reduce_sum(tf.pow(prediction-Y, 2))/(2*iterations)
# In TensorFlow, minimize() method knows how to optimize the values for #
weight & bias.
optimizer =
tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
#assigning default values
init = tf.global_variables_initializer()
#We can start the training now
with tf.Session() as sess:
# Run the initializer. We will see more in detail with later
#chapters
sess.run(init)
# Fit all training data
for step in range(training_steps):
for (x, y) in zip(values_X, values_Y):
sess.run(optimizer, feed_dict={X: x, Y: y})
c = sess.run(cost, feed_dict={X: values_X, Y:values_Y})
print("Step:", '%04d' % (step+1), "cost=", "
{:.4f}".format(c), \
"W=", sess.run(W), "b=", sess.run(b))
print("Successfully completed!")
# with this we can identify the values of Weight & bias
training_cost = sess.run(cost, feed_dict={X: values_X, Y:
values_Y})
print("Training cost=", training_cost, "Weight=", sess.run(W),
"bias=", sess.run(b))
# Lets plot all the values on the graph
plt.plot(values_X, values_Y, 'ro', label='house price points')
plt.plot(values_X, sess.run(W) * values_X + sess.run(b),
label='Line Fitting')
plt.legend()
plt.show()
可以在GitHub仓库中找到本章的代码。