赞
踩
前言:开始学习吴恩达教授的机器学习课程,记录并实现其中的算法。在实现过程中,还未理解如何准确的找到α这个值的取值。
一元线性回归其实就是从一堆训练集中去算出一条直线,使数据集到直线之间的距离差最小。举个例子,唯一特征X(工龄),共有m = 50个数据数量,Y(薪水)是实际结果,要从中找到一条直线,使数据集到直线之间的距离差最小,如下图所示:
这里的薪水数据为手动自定义的,导致了误差较大…
线性回归所提供的思路就是:
可以将特征X中每一个值xi都带入其中,得到对应的 h_θ(xi),可以将损失J(θ)定义为yi和hg(xi)之间的差值平方的和:
接着求出 min( θ_0, θ_1) J( θ_0, θ_1)的值。
将梯度下降应用到最小化平方差代价函数中,得出期望的J(θ_0, θ_1)。如下图所示:
其中最为关键的为梯度下降算法中的导数项,可以对其进行简化,如下所示:
通过对导数项的计算,就可以按照梯度下降的公式同步跟新θ_0, θ_1的值。
公式里的 α,表示学习速率,控制以多大幅度更新参数θj。
import numpy as np import matplotlib.pyplot as plt ### 载入数据----画出图像 # 导入数据 data = np.genfromtxt('data_1.csv', delimiter=',') #data = np.genfromtxt('data.csv', delimiter=',') # print(data) 列表 x_data = data[:, 0] y_data = data[:, 1] # 画图 plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False plt.title("工龄 与 薪水 散点图") plt.xlabel("X 工龄") plt.ylabel("Y 薪水(元)") plt.scatter(x_data,y_data) plt.show() # 学习率 learning_rate #lr = 0.0001 #lr = 0.003 lr = 0.35 # 截距 θ_0 theta_0 = 0 # 斜率 θ_1 theta_1 = 0 # 最大迭代次数 #iterations = 1000 iterations = 50 ###### 求解拟合此数据的直线参数 # 将梯度下降法应用到最小化平方差代价函数 ## 线性回归 # 线性假设 h_θ(x) = θ_0 + θ_1 * x # 平方差代价函数 J(θ) = 循环{ (h_θ(x^(i) - y^(i))** 2 } / 2m 其中 m为循环次数 ## 梯度下降 # θ_j = θ_j - α {J(θ_0, θ_1)的偏导} # 什么叫做损失函数?其实就是计算一个模型与各个点之间的差距到底有多大!!如果差距大,说明我们所选择的模型比较差,如果差距很小,说明这个模型不错。 # 平方差代价函数,求J(θ) def compute_error(theta_0, theta_1, x_data, y_data): totalError = 0 # 即J(θ) for i in range(0,len(x_data)): # 预测值 - 实际值 totalError += ( theta_0 + theta_1 * x_data[i] - y_data[i] ) ** 2 return totalError / float(len(x_data)) / 2.0 # 即得出 J(θ) # 梯度下降---算法思路 # 开始时 theta_0 和 theta_1通常 设置为0 # 持续改变 theta_0 和 theta_1 去减少 J(theta_0 ,theta_1), # 直到出现我们期望的结果出现 def gradient_descent(theta_0, theta_1, x_data, y_data, lr,iterations): # 数据集的总量 m m = float(len(x_data)) # 循环 迭代次数 iteartions for i in range(iterations): theta_0_grad = 0 theta_1_grad = 0 # 计算总和,再求平均 即==> 求梯度下降式子中的 导数项 for j in range(0, len(x_data)): theta_0_grad += (1/m) * (theta_0 + theta_1 * x_data[j] - y_data[j] ) theta_1_grad += (1/m) * (theta_0 + theta_1 * x_data[j] - y_data[j] ) * x_data[j] # 同步更新 theta_0 和 theta_1 梯度下降 theta_0 = theta_0 - lr * theta_0_grad theta_1 = theta_1 - lr * theta_1_grad # 每迭代2次,输出一次图像 if i % 5 == 0: print("当前迭代次数:",i + 1) plt.plot(x_data, y_data, 'b.') plt.plot(x_data, theta_0 + theta_1 * x_data, 'r') plt.title("工龄 与 薪水 散点图") plt.xlabel("工龄") plt.ylabel("薪水(元)") plt.show() # print中的字符串里面的 {0} 相当于索引,所取值对应于 format括号里的每个值的顺序 print(" theta_0 = {0}, theta_1 = {1}, 误差 = {2}".format(theta_0, theta_1,compute_error(theta_0, theta_1, x_data,y_data))) return theta_0, theta_1 # 开始运行 print("Running...") # 执行 梯度下降 theta_0, theta_1 = gradient_descent(theta_0, theta_1, x_data, y_data, lr, iterations) # 输出最终的值 print("final ==> theta_0 = {0}, theta_1 = {1}, 误差 = {2}".format(theta_0, theta_1, compute_error(theta_0, theta_1, x_data, y_data)))
可以看出,随着迭代次数的增加,其差值的缩减将会越来越小。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。