“如果你是一家特许经营餐厅的CEO,你正在考虑在某座城市开设一家新的奥莱店,现在你手上有各城市已开设的加盟餐厅的营业利润以及该城市的人口数据,你想知道在某一人口规模的城市中开设的新餐厅的营业利润将会是多少。”
首先,我们导入一些用于数据运算和绘制图表的Python包,
import numpy as npimport pandas as pdimport matplotlib.pyplot as plt
然后读取数据并使用散点图(Scatter)来显示城市人口和餐厅利润的数据。
path = 'C:\machine learning\ex1data1.txt'data = pd.read_csv(path,names=['Population', 'Profit'])data.plot(kind='scatter',x='Population', y='Profit', figsize=(12,8))plt.show()
现在,我们将创建一个函数来计算给定解决方案的Cost Function(以参数theta为特征)。
def computeCost(X, y, theta): inner = np.power(((X * theta.T) - y), 2) return np.sum(inner) / (2 * len(X))
在训练集的左侧插入一列全为“1”的列,以便计算Cost Function和执行梯度下降,
data.insert(0, 'Ones', 1)
并对变量进行初始化。
cols = data.shape[1]X = data.iloc[:,0:cols-1]y = data.iloc[:,cols-1:cols]
此外,还需转换矩阵X和y并初始化参数矩阵theta,这样就可以用numpy包的矩阵功能来计算Cost Function,
X = np.matrix(X.values)y = np.matrix(y.values)theta = np.matrix(np.array([0,0]))
于是我们就有了X,y和theta的矩阵(Matrix)。
X.shape, theta.shape, y.shape
现在我们可以试试我们的Cost Function。先将参数theta初始化为0,所以目前的解决方案还不是最优的,但我们可以看看这个函数能否运行。
computeCost(X, y, theta)
有了初始的Cost Function后,我们需要定义一个函数来对参数theta进行梯度下降。 梯度下降(Gradient Descent)的思想就是,对于每次迭代(Iteration)我们计算误差项的梯度,以便确定参数向量的移动方向。 也就是说,我们通过计算为了减少误差而对参数进行的更改,从而使解决方案更接近最佳解决方案(即最佳拟合)。
def gradientDescent(X, y, theta, alpha, iters): temp = np.matrix(np.zeros(theta.shape)) parameters = int(theta.ravel().shape[1]) cost = np.zeros(iters) for i in range(iters): error = (X * theta.T) - y for j in range(parameters): term = np.multiply(error, X[:,j]) temp[0,j] = theta[0,j] - ((alpha / len(X)) * np.sum(term)) theta = temp cost[i] = computeCost(X, y, theta) return theta, cost
此外,我们还需初始化一些额外的变量 ,learning rate-alpha和要执行的迭代次数iters。
alpha = 0.01iters = 1000
现在让我们运行梯度下降算法来调节我们的参数theta来训练集的数据。
g,cost = gradientDescent(X, y, theta, alpha, iters)
最后,我们可以使用拟合参数theta来计算训练模型的Cost Function(误差)。
computeCost(X, y, g)
好了,让我们通过绘制图表来看一下线性回归的结果吧。
#变量的定义域和取样的个数x = np.linspace(data.Population.min(), data.Population.max(), 100)#输出predictionf = g[0, 0] + (g[0, 1] * x)fig, ax = plt.subplots(figsize=(12,8))ax.plot(x, f, 'r', label='Prediction')ax.scatter(data.Population, data.Profit, label='Traning Data')ax.legend(loc=2)ax.set_xlabel('Population')ax.set_ylabel('Profit')ax.set_title('Predicted Profit vs. Population Size')plt.show()
由于梯度下降函数也会在每次迭代训练集数据的过程中输出一个结果向量y,所以我们也可以绘制该向量。Cost Function的值在各个方向总是下降的,这就是一个凸函数(Convex Function)优化问题的例子。
fig, ax = plt.subplots(figsize=(12,8))ax.plot(np.arange(iters), cost, 'r')ax.set_xlabel('Iterations')ax.set_ylabel('Cost')ax.set_title('Error vs. Training Epoch')plt.show()
不知道读者们有没有想过这么一个问题,我们拟合出来的线性回归模型对于已知训练集的数据来说是最优解,但是对于新加的数据是不是也奏效呢?下一期炸猪排将给大家介绍交叉验证法(Cross-validate)和贝叶斯参数估计(Bayesian Parameter Estimation),敬请期待~~~
炸猪排
于新西兰皇后镇