本帖最后由 cc1989summer 于 2024-8-27 21:32 编辑
今天的学习分享,我们来学习第二部分机器学习的最后一个章节《回归算法》
回归算法应该说是我们比较熟悉的一个名词,在大学微积分、线性代数里应该都有涉及。
下面是网络上对回归算法的定义:
回归问题是预测一个连续值的输出(因变量)基于一个或多个输入(自变量或特征)的机器学习任务。 回归模型尝试找到自变量和因变量之间的内在关系。
例子: 假设您有一个包含房价和房子特性(如面积、房间数量等)的数据集。 回归模型可以帮助您根据房子的特性来预测其价格。
以下是一些常见的回归算法:
- 线性回归
- Robust 回归
- Ridge 回归
- LASSO 回归
- Elastic Net
- 多项式回归
- 多层感知机
- 随机森林回归
- 支持向量机
其实说来我们最熟悉的应该就是线性回顾,也就是一元线性方程:y=ax+b。
在这里,Y是我们试图预测的因变量,X是我们用来进行预测的自变量,a是回归线的斜率,b是一个常数,称为截距。
我们可以以身高(x)与体重(y)为例,二者是线性关系,身高正比于体重:
线性回归的目标就是让f(X)与y之间的差距最小,也就是权重a和偏置b取什么值的时候f(X)和y最接近。
损失函数是来度量模型预测值与真实值不一样的程度的,或者说度量预测错误的程度,损失函数值越小,模型就越好。
在回归问题中,误差平方和是回归任务中最常用的性能度量。这里就可以令损失函数L(a,b)等于误差平方和。
则损失函数为:
因此,将九个点分别带入该二元方程得到如下:
58=160a+b
63=165a+b
...
59=162a+b
62=171a+b
损失函数(总误差)为:
如何得到最佳的a和b,使得尽可能多的到(x,y)数据点落在或者更靠近这条拟合出来的直线上,最小二乘法就是一个较好的计算方法。
那么什么是最小二乘法呢?
通过最小化误差的平方和寻找数据的最佳函数匹配。最小二乘法在回归模型上的应用,就是要使得观测点和估计点的距离的平方和达到最小。“最小”指的是参数的估计值要保证各个观测点与估计点的距离的平方和达到最小,也就是刚才所说的使得尽可能多的(x,y)数据点落在或者更靠近这条拟合出来的直线上。
因此要求损失函数(误差平方和)值最小,可通过对L(a,b)求偏导数获得,并使得一阶倒数的值为0:
将该公式代入到上述案例中,得到关于求解未知变量a、b的二元一次方程:
在得到了身高与体重的线程方程式后,我们就可以通过身高对体重进行预测!
下面我们用Python跑以下上述例程。
import numpy as np
import matplotlib.pyplot as plt
# ---------------1. 准备数据----------
data = np.array([[160,58],[165,63],[158,57],[172,65],[159,62],[176,66],[160,58],[162,59],[171,62]])
# 提取data中的两列数据,分别作为x,y
x = data[:, 0]
y = data[:, 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.定义算法拟合函数-----------------
# 先定义一个求均值的函数
def average(data):
sum = 0
num = len(data)
for i in range(num):
sum += data[i]
return sum / num
# 定义核心拟合函数
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)
sum_x2 += x ** 2
# 根据公式计算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(data)
print("w is: ", w)
print("b is: ", b)
cost = compute_cost(w, b, data)
print("cost is: ", cost)
# ---------5. 画出拟合曲线------------
plt.scatter(x, y)
# 针对每一个x,计算出预测的y值
pred_y = w * x + b
plt.plot(x, pred_y, c='r')
plt.show()
运行结果跟上述计算结果一致:
其实简单的线性回归用EXCEL也可以办到。(趋势线——线性——显示公式)
如下图,算得y = 0.4212x - 8.2883
跟我们用python拟合的结果一致。
今天的分享就到这里,谢谢!