前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >机器学习-多项式回归算法

机器学习-多项式回归算法

作者头像
唔仄lo咚锵
发布2023-05-23 10:40:07
5230
发布2023-05-23 10:40:07
举报

简介

多项式回归(Polynomial Regression)顾名思义是包含多个自变量的回归算法,也叫多元线性回归,多数时候利用一元线性回归(一条直线)不能很好拟合数据时,就需要用曲线,而多项式回归就是求解这条曲线。

也就是说一元回归方程是

y=wx+b

而多元回归方程是

y=w_nx^n+w_{n-1}x^{n-1}+···+w_1x+w_0

比如二元就是

y=ax^2+bx+c

,三元就是

y=ax^3+bx^2+cx+d

但是并不是元数越多越好,可能存在过拟合问题,在最后一节介绍。

一元线性回归可参考另一篇博客:回归-线性回归算法(房价预测项目)

原理


多元线性回归很复杂,特别是当特征数多元数多的时候,可视化难以想象。

用向量矩阵的来表达:

\bold y=\bold x\bold w
x=\begin{pmatrix}\begin{array}{ccccc}1& x_1 & x_1^2 &\cdots& x_1^n\\1& x_2 & x_2^2 &\cdots& x_2^n\\ \vdots & \vdots & \vdots&\ddots & \vdots\\ 1&x_k&x_k^2&\cdots&x_k^n \end{array}\end{pmatrix}

\bold w=\begin{pmatrix}\begin{array}{cccc}w_{01} & w_{02} &\cdots& w_{0k}\\w_{11} & w_{12} &\cdots& w_{1k}\\ \vdots & \vdots&\ddots & \vdots\\ w_{n1}&w_{n2}&\cdots&w_{nk} \end{array}\end{pmatrix}

比如一个特征量二元回归方程:

k=1

n=2

y=(\begin{array}{ccc}1&x_1&x_1^2 \end{array})\begin{pmatrix} w_{01}\\ w_{11}\\w_{21}\end{pmatrix}=w_{01}+w_{11}x_1+w_{21}x_1^2

再如两个特征量二元回归方程:

k=2

n=2

y= x=\begin{pmatrix}\begin{array}{ccc}1& x_1 & x_1^2\\1& x_2 & x_2^2 \end{array}\end{pmatrix}\begin{pmatrix} w_{01}&w_{02}\\ w_{11}&w_{12}\\w_{21}&w_{22}\end{pmatrix}=\begin{pmatrix}\begin{array}{cc}w_{01}+w_{11}x_1+w_{21}x_1^2 & w_{02}+w_{12}x_1+w_{22}x_1^2\\w_{01}+w_{11}x_2+w_{21}x_2^2& w_{02}+w_{12}x_2+w_{22}x_2^2 \end{array}\end{pmatrix}
|y|=w_{01}+w_{11}x_1+w_{21}x_1^2+w_{02}+w_{12}x_2+w_{22}x_2^2

可以看出计算量其实是很大的。

使用最小二乘法作为损失函数,并选择优化算法:正规方程或梯度下降。

正规方程:

\bold{w}=(\bold{x}^T\bold{x})^{-1}\bold{x}^T\bold{y}

如果

(\bold{x}^T\bold{x})

不可逆,则使用梯度下降求解即可。

可参考:浅谈梯度下降与模拟退火算法

代码


多元线性回归与一元线性回归其实只是

\bold x

的维度不同,也就是说通过设置

\bold x

的维度,调用线性模型LinearRegression即可进行求解,即对数据进行预处理,需要几次方即升到几维,如下2种方法。

  1. 使用hstack()hstack()叠加 如果维数低,我们可以手动添加即可。
代码语言:javascript
复制
import numpy as np

a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
print("水平方向叠加:", np.hstack((a, b)))
print("垂直方向叠加:", np.vstack((a, b)))
  1. 使用PolynomialFeatures()对特征预处理 如果维度多,可以用该函数计算生成
\bold x

包括参数:

degree:默认2,多项式特征的次数;

interaction_only:默认default=False,若为True,则不含自己和自己相结合的特征项;

include_bias:默认True,若为True,则包含一列为1的偏差项;

order:默认‘C’,若为’F’则计算更快,但是后续的拟合慢。

包括属性:

powers_:n维幂运算数组,根据degree的值而确定行,根据属性个数而确定列。

n_input_features_:输入特征的总数,即幂运算矩阵的列;

n_output_features_:输出特征的总数,即幂运算矩阵的行。

代码语言:javascript
复制
import numpy as np
from sklearn.preprocessing import PolynomialFeatures

x = np.arange(6).reshape(3, 2)
print(x)
poly = PolynomialFeatures(degree=2)
poly.fit(x)
print(poly.powers_)
print("输入特征:", poly.n_input_features_)
print("输出特征:", poly.n_output_features_)
x = poly.transform(x)
print(x)

插播反爬信息 )博主CSDN地址:https://wzlodq.blog.csdn.net/

代码语言:javascript
复制
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures

# 生成数据
X = np.linspace(-5, 5, 100)
Y = 2 * X ** 2 + 3 * X + 5 + np.random.randn(100) * 5
x = X.reshape(-1, 1)

# 数据预处理
# 法一、使用hstack直接添加x方
x1 = np.hstack([x, x ** 2])

# 法二、使用PolynomialFeatures计算二次方
poly = PolynomialFeatures()
poly.fit(x)
x2 = poly.transform(x)

model1 = LinearRegression()  # 创建模型1
model1.fit(x1, Y)  # 训练模型1
y_pred1 = model1.predict(x1)  # 测试1
plt.figure(figsize=(8, 4))
plt.subplot(1, 2, 1)  # 可视化1
plt.scatter(X, Y)
plt.plot(x, y_pred1, color='red')
plt.title("使用hstack()")

model2 = LinearRegression()  # 创建模型2
model2.fit(x2, Y)  # 训练模型2
y_pred2 = model2.predict(x2)  # 测试2
plt.subplot(1, 2, 2)  # 可视化2
plt.scatter(X, Y)
plt.plot(x, y_pred2, color='gold')
plt.title("使用PolynomialFeatures()")

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.show()

过拟合


正如前面所说的一样,多项式的幂次并不是越高越好,过高可能出现过拟合情况,导致泛化能力低,过低可能出现欠拟合情况,导致预测结果差,如下图所示。

代码语言:javascript
复制
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures

# 生成数据
np.random.seed(20221005)
X = np.linspace(-np.pi, np.pi, 100)
Y = np.sin(X) + np.random.randn(100) * 0.4
x = X.reshape(-1, 1)
plt.scatter(x, Y, color="lightblue")

for idx, degree in enumerate([1, 3, 30, 100]):
    print(degree)
    poly = PolynomialFeatures(degree=degree)
    poly.fit(x)
    x1 = poly.transform(x)
    model = LinearRegression()
    model.fit(x1, Y)
    y_pred = model.predict(x1)
    plt.plot(x, y_pred, label=("%d次方" % degree))

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.legend()
plt.show()

可见并不是幂次越高越好,一般遵循“奥卡姆剃刀”定律,也就是简单平滑的曲线即可。当然了,也有很多方法度量和避免欠拟合与过拟合。

原创不易,请勿转载本不富裕的访问量雪上加霜 ) 博主首页:https://wzlodq.blog.csdn.net/ 来都来了,不评论两句吗👀 如果文章对你有帮助,记得一键三连❤

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-11-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 原理
  • 代码
  • 过拟合
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档