当前位置:   article > 正文

【Andrew Ng】 机器学习Exercise1——Linear Regression_对于这个数据集,你 可以使用散点图来可视化数据,因为它只有两个属性可以绘制(利润

对于这个数据集,你 可以使用散点图来可视化数据,因为它只有两个属性可以绘制(利润

1、单变量线性回归

在本部分练习中,您将使用一个变量实现线性回归,以预测食品卡车的利润。假设你是一家连锁餐厅的首席执行官,正在考虑在不同的城市开设一家新分店。这个连锁店已经在不同的城市有了卡车,你可以从城市得到利润和人口的数据。

您希望使用这些数据来帮助您选择下一个要扩展到的城市。

文件ex1data1.txt包含线性回归问题的数据集。第一列是一个城市的人口第二列是那个城市的食品卡车的利润。利润为负数表示亏损。

 

1.1 Plotting the Data

在开始任何任务之前,通过可视化来理解数据通常是有用的。对于这个数据集,您可以使用散点图来可视化数据,因为它只有两个属性可以绘图(利润和人口)。(现实生活中你会遇到的许多其他问题都是多维的,不能用二维图来表示。)

  1. import numpy as np
  2. import pandas as pd
  3. import matplotlib.pyplot as plt
  4. path = 'ex1data1.txt'
  5. data = pd.read_csv(path, header=None, names=['Population', 'Profit'])
  6. data.head()
  7. Out[1]:
  8. Population Profit
  9. 0 6.1101 17.5920
  10. 1 5.5277 9.1302
  11. 2 8.5186 13.6620
  12. 3 7.0032 11.8540
  13. 4 5.8598 6.8233
  14. data.describe()
  15. Out[2]:
  16. Population Profit
  17. count 97.000000 97.000000
  18. mean 8.159800 5.839135
  19. std 3.869884 5.510262
  20. min 5.026900 -2.680700
  21. 25% 5.707700 1.986900
  22. 50% 6.589400 4.562300
  23. 75% 8.578100 7.046700
  24. max 22.203000 24.147000

看下数据长什么样子

  1. data.plot(kind='scatter', x='Population', y='Profit', figsize=(12,8))
  2. plt.show()

 

1.2 Gradient Descent

在这一部分中,您将符合线性回归参数θ数据集使用梯度下降法。

 

1.2.1 Update Equations(更新方程)

线性回归的目标是使成本函数最小化

J(θ)=12m(hθ(x(i))y(i))2

假设hθ(x)是由线性模型

hθ(x)=θTx=θ0+θ1x1

回想一下,你的模型的参数是\theta _{j}值。这些值将最小化成本调整J(θ)。一种方法是使用批量梯度下降算法。在批量梯度下降,每个迭代执行update

θj:θjα12mi=1m(hθ(x(i))y(i))xji ,同时更新所有\theta _{j}的j。

  1. def computeCost(X, y, theta):
  2. inner = np.power(((X * theta.T) - y), 2)
  3. return np.sum(inner) / (2 * len(X))
'
运行

每一步的梯度下降法,参数\theta _{j}接近最优值,达到成本最低J(θ)。

Note:我们将每个示例作为一行存储在X矩阵中。考虑截距项(θ0),我们添加一个额外的第一列X作为θ0,当作另一个“特性”。

在训练集中添加一列,以便我们可以使用向量化的解决方案来计算代价和梯度。

  1. data.insert(0, 'Ones', 1)
  2. data.head()
  3. Out[3]:
  4. Ones Population Profit
  5. 0 1 6.1101 17.5920
  6. 1 1 5.5277 9.1302
  7. 2 1 8.5186 13.6620
  8. 3 1 7.0032 11.8540
  9. 4 1 5.8598 6.8233

区分训练数据X和目标变量y

  1. # set X (training data) and y (target variable)
  2. cols = data.shape[1]
  3. X = data.iloc[:,0:cols-1]#X是所有行,去掉最后一列
  4. y = data.iloc[:,cols-1:cols]#X是所有行,最后一列

观察下 X (训练集) and y (目标变量)是否正确.

  1. X.head()#head()是观察前5行
  2. Out[4]:
  3. Ones Population
  4. 0 1 6.1101
  5. 1 1 5.5277
  6. 2 1 8.5186
  7. 3 1 7.0032
  8. 4 1 5.8598
  9. y.head()
  10. Out[5]:
  11. Profit
  12. 0 17.5920
  13. 1 9.1302
  14. 2 13.6620
  15. 3 11.8540
  16. 4 6.8233

代价函数是应该是numpy矩阵,所以我们需要转换X和Y,然后才能使用它们。 我们还需要初始化theta。

theta 是一个(1,2)矩阵

  1. X = np.matrix(X.values)
  2. y = np.matrix(y.values)
  3. theta = np.matrix(np.array([0,0]))
  4. theta
  5. Out[6]: matrix([[0, 0]])

看下纬度

  1. X.shape, theta.shape, y.shape
  2. Out[7]: ((97, 2), (1, 2), (97, 1))

计算代价函数 (theta初始值为0).

  1. computeCost(X, y, theta)
  2. Out[8]: 32.072733877455676

 

1.2.2 Batch Gradient Descent(批量梯度下降)

θj:θjαθjJ(θ)

  1. def gradientDescent(X, y, theta, alpha, iters):
  2. temp = np.matrix(np.zeros(theta.shape)) #theta.shape 是一行两列。生成一个一行两列以0填充的矩阵
  3. parameters = int(theta.ravel().shape[1]) #ravel() 将多维数组降位一维。得到具体参数数量(共有多少列)
  4. cost = np.zeros(iters)
  5. for i in range(iters):
  6. error = (X * theta.T) - y
  7. for j in range(parameters):
  8. term = np.multiply(error, X[:,j]) #multiply 数组和矩阵对应位置相乘,输出与相乘数组/矩阵的大小一致
  9. temp[0,j] = theta[0,j] - ((alpha / len(X)) * np.sum(term))
  10. theta = temp
  11. cost[i] = computeCost(X, y, theta)
  12. return theta, cost
'
运行

初始化一些附加变量 - 学习速率α和要执行的迭代次数。

  1. alpha = 0.01 #学习率
  2. iters = 1000 #迭代次数
'
运行

现在让我们运行梯度下降算法来将我们的参数θ适合于训练集。

  1. g, cost = gradientDescent(X, y, theta, alpha, iters)
  2. g
  3. out[9]: matrix([[-3.24140214, 1.1272942 ]])

最后,我们可以使用我们拟合的参数计算训练模型的代价函数(误差)。

  1. computeCost(X, y, g)
  2. out[10]: 4.5159555030789118

现在我们来绘制线性模型以及数据,直观地看出它的拟合。

  1. x = np.linspace(data.Population.min(), data.Population.max(), 100) ##linspace 在指定的间隔内返回均匀间隔的数字
  2. f = g[0, 0] + (g[0, 1] * x) #一次函数 f = a + bx
  3. fig, ax = plt.subplots(figsize=(12,8))
  4. ax.plot(x, f, 'r', label='Prediction')
  5. ax.scatter(data.Population, data.Profit, label='Traning Data')
  6. ax.legend(loc=2)
  7. ax.set_xlabel('Population')
  8. ax.set_ylabel('Profit')
  9. ax.set_title('Predicted Profit vs. Population Size')
  10. plt.show()

 

1.2.3 Visualize Cost Data(代价数据可视化)

由于梯度方程式函数也在每个训练迭代中输出一个代价的向量,所以我们也可以绘制。

请注意,代价总是降低 - 这是凸优化问题的一个例子。

  1. fig, ax = plt.subplots(figsize=(12,8))
  2. ax.plot(np.arange(iters), cost, 'r')
  3. ax.set_xlabel('Iterations')
  4. ax.set_ylabel('Cost')
  5. ax.set_title('Error vs. Training Epoch')
  6. plt.show()

可以看到从第二轮代价数据变换很大,接下来平稳了

 

2、多变量线性回归

在这一部分中,您将使用多个变量实现线性回归来预测房价。假设你正在出售你的房子,你想知道一个好的市场价格是多少。一种方法是首先收集最近售出的房屋的信息,并建立一个房价模型。

  1. path = 'ex1data2.txt'
  2. data2 = pd.read_csv(path, header=None, names=['Size', 'Bedrooms', 'Price'])
  3. data2.head()
  4. Out[11]:
  5. Size Bedrooms Price
  6. 0 2104 3 399900
  7. 1 1600 3 329900
  8. 2 2400 3 369000
  9. 3 1416 2 232000
  10. 4 3000 4 539900

通过观察价值,注意房子的大小差不多是卧室数量的1000倍。当特征按数量级不同时,首先进行特征缩放可以使梯度下降更快地收敛。

这个对于pandas来说很简单

  1. data2 = (data2 - data2.mean()) / data2.std()
  2. data2.head()
  3. Out[12]:
  4. Size Bedrooms Price
  5. 0 0.130010 -0.223675 0.475747
  6. 1 -0.504190 -0.223675 -0.084074
  7. 2 0.502476 -0.223675 0.228626
  8. 3 -0.735723 -1.537767 -0.867025
  9. 4 1.257476 1.090417 1.595389

现在我们重复第1部分的预处理步骤,并对新数据集运行线性回归程序。

  1. # add ones column
  2. data2.insert(0, 'Ones', 1)
  3. # set X (training data) and y (target variable)
  4. cols = data2.shape[1]
  5. X2 = data2.iloc[:,0:cols-1]
  6. y2 = data2.iloc[:,cols-1:cols]
  7. # convert to matrices and initialize theta
  8. X2 = np.matrix(X2.values)
  9. y2 = np.matrix(y2.values)
  10. theta2 = np.matrix(np.array([0,0,0]))
  11. # perform linear regression on the data set
  12. g2, cost2 = gradientDescent(X2, y2, theta2, alpha, iters)
  13. # get the cost (error) of the model
  14. computeCost(X2, y2, g2)
  15. Out[13]: 0.13070336960771892

我们也可以快速查看这一个的训练进程。

  1. fig, ax = plt.subplots(figsize=(12,8))
  2. ax.plot(np.arange(iters), cost2, 'r')
  3. ax.set_xlabel('Iterations')
  4. ax.set_ylabel('Cost')
  5. ax.set_title('Error vs. Training Epoch')
  6. plt.show()

我们也可以使用scikit-learn的线性回归函数,而不是从头开始实现这些算法。 我们将scikit-learn的线性回归算法应用于第1部分的数据,并看看它的表现。

  1. from sklearn import linear_model
  2. model = linear_model.LinearRegression()
  3. model.fit(X, y)
  4. Out[14]: LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)

scikit-learn model的预测表现

  1. x = np.array(X[:, 1].A1)
  2. f = model.predict(X).flatten()
  3. fig, ax = plt.subplots(figsize=(12,8))
  4. ax.plot(x, f, 'r', label='Prediction')
  5. ax.scatter(data.Population, data.Profit, label='Traning Data')
  6. ax.legend(loc=2)
  7. ax.set_xlabel('Population')
  8. ax.set_ylabel('Profit')
  9. ax.set_title('Predicted Profit vs. Population Size')
  10. plt.show()

 

3、Normal Equations(正规方程)

在课程视频中,我们学过线性回归的封闭解是:

θ=(XTX)1XTy

使用这个公式不需要进行任何特征缩放,将在一次计算中得到一个精确的解:没有像梯度下降法那样的“直到收敛为止的循环”。虽然你不需要扩展功能,我们仍然需要对X矩阵添加一个列全为1的项, 让X矩阵有一个截距项(θ0)。

正规方程是通过求解下面的方程来找出使得代价函数最小的参数的:θjJ(θj)=0

假设我们的训练集特征矩阵为 X(包含了x0=1)并且我们的训练集结果为向量 y,则利用正规方程解出向量 \theta = \left ( X^{T}X \right )^{-1} X^{T}y 。

上标T代表矩阵转置,上标-1 代表矩阵的逆。设矩阵A=XTX,则:(XTX)1=A1

梯度下降与正规方程的比较:

梯度下降:需要选择学习率α,需要多次迭代,当特征数量n大时也能较好适用,适用于各种类型的模型

正规方程:不需要选择学习率α,一次计算得出,需要计算(XTX)1,如果特征数量n较大则运算代价大,因为矩阵逆的计算时间复杂度为O(n3),通常来说当n小于10000 时还是可以接受的,只适用于线性模型,不适合逻辑回归模型等其他模型

  1. # 正规方程
  2. def normalEqn(X, y):
  3. theta = np.linalg.inv(X.T@X)@X.T@y#X.T@X等价于X.T.dot(X)
  4. return theta
'
运行
  1. final_theta2=normalEqn(X, y)#感觉和批量梯度下降的theta的值有点差距
  2. final_theta2
  3. Out[15]:
  4. matrix([[-3.89578088],
  5. [ 1.19303364]])
  6. #梯度下降得到的结果是matrix([[-3.89578088, 1.19303364]])

 

 

 

 

 

 

 

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/807487
推荐阅读
相关标签
  

闽ICP备14008679号