监督学习
- 回归模型
- 线性回归
- 分类模型
- k近邻(kNN)
- 决策树
- 逻辑斯谛回归
无监督学习
- 聚类
- k均值(k-means)
- 降维
监督学习 —— 回归模型
① 线性回归模型
-
- 一元线性回归
- 多元线性回归
② 非线性回归模型
③ 最小二乘法
线性回归模型:
- 线性回归(linear regression)是一种线性模型,它假设输入变量 x 和单个输出变量 y 之间存在线性关系
- 具体来说,利用线性回归模型,可以从一组输入变量 x 的线性组合中,计算输出变量 y
线性方程求解
假设我们有一个如下的二元一次方程:
?="ax + b"
我们已知两组数据: x = 1 时,y = 3,即(1, 3)
x = 2 时,y = 5,即(2, 5)
将数据输入方程中,可得:
a + b = 3
2a + b = 5
解得: a = 2,b = 1
即方程为: 2x + 1 = y
当我们有任意一个 x 时,输入方程,就可以得到对应的 y ;例如 x = 5时,y = 11。
线性回归模型
给定有d个属性(特征)描述的示例 x =(x1; x2; …; xd),其中xi是x在第i个属性(特征)上的取值,线性模型(linear model)试图学得一个通过属性(特征)的线性组合来进行预测的函数,即:
一般用向量形式写成: , 其中
- 假设特征和结果都满足线性,即不大于一次方。
- w和b学得之后,模型就得以确定。
- 许多功能更为强大的非线性模型可在线性模型的基础上通过引入层级结构或高维映射而得。
最小二乘法
基于均方误差最小化来进行模型求解的方法称为“最小二乘法”(least square method)
它的主要思想就是选择未知参数,使得理论值与观测值之差的平方和达到最小。
我们假设输入属性(特征)的数目只有一个:
在线性回归中,最小二乘法就是试图找到一条直线,使所有样本到直线上的欧式距离之和最小:
求解线性回归 -- 求偏导
多元线性回归
- 如果有两个或两个以上的自变量,这样的线性回归分析就称为多元线性回归
- 实际问题中,一个现象往往是受多个因素影响的,所以多元线性回归比一元线性回归的实际应用更广
梯度下降法求解线性回归
- α 在梯度下降算法中被称作为学习率或者步长; 步长 * 梯度
- 这意味着我们可以通过 α 来控制每一步走的距离,以保证不要走太快,错过了最低点;同时也要保证收敛速度不要太慢
- 所以 α 的选择在梯度下降法中往往是很重要的,不能太大也不能太小
梯度下降法和最小二乘法
相同点:
本质和目标相同:两种方法都是经典的学习算法,在给定已知数据的前提下利用求导算出一个模型(函数),使得损失函数最小,然后对给定的新数据进行估算预测
不同点:
- 损失函数:梯度下降可以选取其它损失函数,而最小二乘一定是平方损失函数
- 实现方法:最小二乘法是直接求导找出全局最小;而梯度下降是一种迭代法
- 效果:最小二乘找到的一定是全局最小,但计算繁琐,且复杂情况下未必有解;梯度下降迭代计算简单,但找到的一般是局部最小,只有在目标函数是凸函数时才是全局最小;到最小点附近时收敛速度会变慢,且对初始点的选择极为敏感
代码的实现:
简单线性回归(最小二乘法)
import numpy as np import matplotlib.pyplot as plt
1. 导入数据(data.csv) points = np.genfromtxt('data.csv', delimiter=',') points[0,0] # 提取points中的两列数据,分别作为x,y x = points[:, 0] y = points[:, 1] # 用plt画出散点图 plt.scatter(x, y) plt.show()
#2. 定义损失函数 #定义线性模型y = wx + b # 损失函数是系数的函数,另外还要传入数据的x,y def compute_cost(w, b, points): total_cost = 0 M = len(points) # 逐点计算平方损失误差,然后求平均数 sum(y-mx-b)^2 for i in range(M): x = points[i, 0] y = points[i, 1] total_cost += ( y - w * x - b ) ** 2 return total_cost/M
#3.定义算法拟合函数 # 先定义一个求均值的函数 def average(data): sum = 0 num = len(data) for i in range(num): sum += data[i] return sum/num # 定义核心拟合函数;开始迭代每个点的x,y def fit(points): M = len(points) x_bar = average(points[:, 0]) sum_yx = 0 sum_x2 = 0 sum_delta = 0 for i in range(M): x = points[i, 0] y = points[i, 1] sum_yx += y * ( x - x_bar ) # yi*(xi - xavg) sum_x2 += x ** 2 # 令偏导等于0,根据公式计算w,可得到: w = sum_yx / ( sum_x2 - M * (x_bar**2) ) for i in range(M): x = points[i, 0] y = points[i, 1] sum_delta += ( y - w * x ) b = sum_delta / M return w, b
#4. 测试 w, b = fit(points) print("w is: ", w) print("b is: ", b) cost = compute_cost(w, b, points) print("cost is: ", cost) ===>
w is: 1.3224310227553846 b is: 7.991020982269173 cost is: 110.25738346621313
#5. 画出拟合曲线 plt.scatter(x, y) # 针对每一个x,计算出预测的y值 pred_y = w * x + b plt.plot(x, pred_y, c='r') plt.show()
简单线性回归(梯度下降法)
import numpy as np import matplotlib.pyplot as plt points = np.genfromtxt('data.csv', delimiter=',') points[0,0] # 提取points中的两列数据,分别作为x,y x = points[:, 0] y = points[:, 1] # 用plt画出散点图 plt.scatter(x, y) plt.show()
2.定义损失函数 # 损失函数是系数的函数,另外还要传入数据的x,y def compute_cost(w, b, points): total_cost = 0 M = len(points) # 逐点计算平方损失误差,然后求平均数 for i in range(M): x = points[i, 0] y = points[i, 1] total_cost += ( y - w * x - b ) ** 2 return total_cost/M
3. 定义模型的超参数 #包括:步长(学习速率),初始点,迭代次数 alpha = 0.0001 #步长 initial_w = 0 initial_b = 0 # θ num_iter = 10 #迭代10次
4. 定义核心梯度下降算法函数 def grad_desc(points, initial_w, initial_b, alpha, num_iter): w = initial_w b = initial_b # 定义一个list保存所有的损失函数值,用来显示下降的过程 cost_list = [] for i in range(num_iter): cost_list.append( compute_cost(w, b, points) ) #算出损失 w, b = step_grad_desc( w, b, alpha, points) return [w, b, cost_list] def step_grad_desc( current_w, current_b, alpha, points ): sum_grad_w = 0 sum_grad_b = 0 M = len(points) # 对每个点,代入公式求和 for i in range(M): x = points[i, 0] y = points[i, 1] sum_grad_w += ( current_w * x + current_b - y ) * x sum_grad_b += current_w * x + current_b - y # 用公式求当前梯度 grad_w = 2/M * sum_grad_w grad_b = 2/M * sum_grad_b # 梯度下降,更新当前的w和b updated_w = current_w - alpha * grad_w updated_b = current_b - alpha * grad_b return updated_w, updated_b
测试:运行梯度下降算法计算最优的w和b w, b, cost_list = grad_desc( points, initial_w, initial_b, alpha, num_iter ) print("w is: ", w) print("b is: ", b) cost = compute_cost(w, b, points) print("cost is: ", cost) plt.plot(cost_list) plt.show()
6. 画出拟合曲线 plt.scatter(x, y) # 针对每一个x,计算出预测的y值 pred_y = w * x + b plt.plot(x, pred_y, c='r') plt.show()
3_线性回归调sklearn库实现
import numpy as np import matplotlib.pyplot as plt points = np.genfromtxt('data.csv', delimiter=',') points[0,0] # 提取points中的两列数据,分别作为x,y x = points[:, 0] y = points[:, 1] # 用plt画出散点图 plt.scatter(x, y) plt.show()
# 损失函数是系数的函数,另外还要传入数据的x,y def compute_cost(w, b, points): total_cost = 0 M = len(points) # 逐点计算平方损失误差,然后求平均数 for i in range(M): x = points[i, 0] y = points[i, 1] total_cost += ( y - w * x - b ) ** 2 return total_cost/M
from sklearn.linear_model import LinearRegression lr = LinearRegression() x_new = x.reshape(-1, 1) y_new = y.reshape(-1, 1) lr.fit(x_new, y_new)
# 从训练好的模型中提取系数和截距 w = lr.coef_[0][0] b = lr.intercept_[0] print("w is: ", w) print("b is: ", b) cost = compute_cost(w, b, points) print("cost is: ", cost)
plt.scatter(x, y) # 针对每一个x,计算出预测的y值 pred_y = w * x + b plt.plot(x, pred_y, c='r') plt.show()