-
模型表示
我们的第一个学习算法是线性回归算法。在这段视频中,你会看到这个算法的概况,更重要的是你将会了解监督学习过程完整的流程。
让我们通过一个例子来开始:这个例子是预测住房价格的,我们要使用一个数据集,数据集包含俄勒冈州波特兰市的住房价格。在这里,我要根据不同房屋尺寸所售出的价格,画出我的数据集。比方说,如果你朋友的房子是1250平方尺大小,你要告诉他们这房子能卖多少钱。那么,你可以做的一件事就是构建一个模型,也许是条直线,从这个数据模型上来看,也许你可以告诉你的朋友,他能以大约220000(美元)左右的价格卖掉这个房子。这就是监督学习算法的一个例子。
m 代表训练集中实例的数量
X 代表特征/输入变量
y 代表目标变量/输出变量
(X,y) 代表训练集中的实例
(X_i,y_i) 代表第 个观察实例
h 代表学习算法的解决方案或函数也称为假设(hypothesis)
我们该如何表达 h ?
一种可能的表达方式为:hθ(x)=θ0+θ1X
,因为只含有一个特征/输入变量,因此这样的问题叫作单变量线性回归问题。
- 代价函数
如何选择权重会导致我们构造模型的误差,如下图
我们的目标便是选择出可以使得建模误差的平方和能够最小的模型参数。 即使得代价函数 最小。
代价函数就是预测的值-实际的值,取平方是因为有正有负,全部加起来后取平均数,这里取2m是因为求导数好求
我们绘制一个等高线图,三个坐标分别为θ0,θ1,J(θ0,θ1),图像如下
代价函数也被称作平方误差函数,有时也被称为平方误差代价函数。我们之所以要求出误差的平方和,是因为误差平方代价函数,对于大多数问题,特别是回归问题,都是一个合理的选择。还有其他的代价函数也能很好地发挥作用,但是平方误差代价函数可能是解决回归问题最常用的手段了。
-
代价函数的直观理解
当然,我们真正需要的是一种有效的算法,能够自动地找出这些使代价函数J取的最小值的权重。
-
梯度下降
梯度下降是一个用来求函数最小值的算法,我们将使用梯度下降算法来求出代价函数J的最小值
梯度下降背后的思想是:开始时我们随机选择一个参数的组合,计算代价函数,然后我们寻找下一个能让代价函数值下降最多的参数组合。我们持续这么做直到到到一个局部最小值(local minimum),因为我们并没有尝试完所有的参数组合,所以不能确定我们得到的局部最小值是否便是全局最小值(global minimum),选择不同的初始参数组合,可能会找到不同的局部最小值。
批量梯度下降(batch gradient descent)算法的公式为:
其中α是学习率(learning rate),它决定了我们沿着能让代价函数下降程度最大的方向向下迈出的步子有多大,在批量梯度下降中,我们每一次都同时让所有的参数减去学习速率乘以代价函数的导数。
需要注意的是,更新参数的时候需要同时更新参数
梯度下降算法如下:
求导的目的,基本上可以说取这个红点的切线,就是这样一条红色的直线,刚好与函数相切于这一点,让我们看看这条红色直线的斜率,就是这条刚好与函数曲线相切的这条直线,这条直线的斜率正好是这个三角形的高度除以这个水平长度,现在,这条线有一个正斜率,也就是说它有正导数,因此,我得到的新的权重,更新后等于减去一个正数乘以a。
a决定的是移动的速率,如果太小,那么移动过于缓慢,如果太大的化,容易移动过头
-
梯度下降的线性回归
梯度下降算法和线性回归算法比较如图:
对我们之前的线性回归问题运用梯度下降法,关键在于求出代价函数的导数,即:
我们刚刚使用的算法,有时也称为批量梯度下降。实际上,在机器学习中,通常不太会给算法起名字,但这个名字”批量梯度下降”,指的是在梯度下降的每一步中,我们都用到了所有的训练样本,在梯度下降中,在计算微分求导项时,我们需要进行求和运算,所以,在每一个单独的梯度下降中,我们最终都要计算这样一个东西,这个项需要对所有个训练样本求和。因此,批量梯度下降法这个名字说明了我们需要考虑所有这一"批"训练样本,而事实上,有时也有其他类型的梯度下降法,不是这种"批量"型的,不考虑整个的训练集,而是每次只关注训练集中的一些小的子集。在后面的课程中,我们也将介绍这些方法。
但就目前而言,应用刚刚学到的算法,你应该已经掌握了批量梯度算法,并且能把它应用到线性回归中了,这就是用于线性回归的梯度下降法。
- 代码
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
path='E:\machine studdy\Coursera-ML-AndrewNg-Notes-master\code\ex1-linear regression\ex1data1.txt'
data=pd.read_csv(path,header=None,names=['Population', 'Profit']) #读取数据
def costfunction(X,y,theta): #计算代价函数的 函数
inner=np.power(((X*theta.T)-y),2)
return np.sum(inner)/(2*len(X)) #出上 长度乘上2,便于求导
def gradientDescent(X,y,theta,alpha,iters): #iters指的是迭代的次数
temp=np.matrix(np.zeros(theta.shape))
parameters = int(theta.ravel().shape[1])
cost = np.zeros(iters)
for i in range(iters): #迭代1500次
error = (X * theta.T) - y
for j in range(parameters): #每次同步更新theta的值
term = np.multiply(error, X[:,j]) # 为了求导,给theta求导会导致x变得越来越多,所以要不断地乘上x
temp[0, j] = theta[0, j] - ((alpha / len(X)) * np.sum(term)) #更新不同的θ的值保存在一个数组中,数组最开始为0
theta=temp
cost[i]= costfunction(X,y,theta)
return theta,cost
data.insert(0, 'Ones', 1) #控制theta0的大小,,因为是线性函数 y=x0+t x1
col=data.shape[1] #判断第二维度的长度
X=data.iloc[:,:-1] #切片,取除了最后一列的所有列 第一个冒号代表行,第二个冒号代表列
y=data.iloc[:,col-1:col] #取最后一列
X = np.matrix(X.values)
y = np.matrix(y.values) #矩阵化 X y
theta=np.matrix(np.array([0,0])) #讲θ初始化为0
alpha = 0.01
iters = 1500
g, cost = gradientDescent(X, y, theta, alpha, iters)
print(g)
#预测35000 和70000人口的小吃摊利润
predict1 = [1,3.5]*g.T
print("predict1:",predict1)
predict2 = [1,7]*g.T
print("predict2:",predict2)
x = np.linspace(data.Population.min(), data.Population.max(), 100)
f=g[0,0]+(g[0,1] * x)
fig,ax=plt.subplots(figsize=(12,8))
ax.plot(x,f,label="prediction")
ax.scatter(data.Population,data.Profit,label="traning date")
ax.legend(loc=2)
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size')
plt.show()
"""print(X.shape)
print("------------------")
print(y.shape)"""
"""print(theta)
print(costfunction(X,y,theta)) #最开始的代价函数
print(np.zeros(theta.shape))
print(theta.ravel().shape[1]) #列的长度是多少
"""
"""
temp=np.matrix(np.zeros(theta.shape))
print(X)
parameters = int(np.ravel(theta.shape[1]))
for j in range(parameters): # 每次同步更新theta的值
print(X[:,j])
"""
运行结果如图