问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

机器学习中的特征工程与多项式回归:原理、应用及代码示例

创作时间:
作者:
@小白创作中心

机器学习中的特征工程与多项式回归:原理、应用及代码示例

引用
CSDN
1.
https://blog.csdn.net/m0_49243785/article/details/140753052

特征工程和多项式回归是机器学习中非常重要的两个概念。特征工程涉及创建、选择或修改原始数据中的特征,以提高模型的性能。多项式回归则是一种使用多项式函数来建立输入特征与输出目标之间关系的回归分析方法。本文将详细介绍特征工程的基本概念、多项式回归的原理及其应用,并通过具体的Python代码示例展示如何通过特征工程来构建更复杂的模型。

引言

在机器学习中,特征工程(Feature Engineering)是一个关键步骤,它涉及创建、选择或修改原始数据中的特征,以提高模型的性能。机器学习中的多项式回归(Polynomial Regression)是一种使用多项式函数来建立输入特征(自变量)与输出目标(因变量)之间的线性关系的回归分析方法。它允许特征之间的关系以非线性的方式进行建模,这对于数据中存在非线性关系的情况非常有用。

一、特征工程(Feature Engineering)

特征工程可以包括以下几个方面:

1.1 选择特征

从原始数据中选择最相关的特征,以减少模型的复杂性和过拟合的风险。

1.2 创建新特征

基于现有特征创建新的特征,这些新特征可能有助于模型更好地理解数据。例如,计算特征之间的比率或差值。

1.3 修改特征

对原始特征进行转换,如标准化、归一化或缩放,以提高模型的训练效率和性能。

1.4 特征编码

将分类特征转换为数值特征,以便于机器学习算法处理。

1.5 特征组合

将多个特征组合成一个新的特征,以捕获原始特征之间的相互作用。

1.6 特征选择

使用统计测试、算法评估或其他技术来选择对目标变量最有用的特征。

1.7 特征提取

从原始数据中提取新的特征,这些特征可能是原始数据的简化表示,有助于提高模型的性能。

特征工程是一个迭代过程,通常需要数据科学家和领域专家的密切合作。通过有效的特征工程,可以显著提高机器学习模型的准确性和效率。

二、多项式回归(Polynomial Regression)

2.1 多项式回归的基本思想

假设输入特征与输出之间存在一个多项式函数关系。例如,如果只有一个输入特征x,那么假设的关系可以表示为:

y = ax^2 + bx + c

其中,a、b、c是模型参数,需要通过训练数据集来估计。

2.2 多项式回归的优点

多项式回归可以捕捉到数据中的非线性关系,但它也存在一些缺点,如过拟合(模型过于复杂,无法很好地泛化到新数据)和计算复杂度随着多项式次数的增加而增加。为了克服这些缺点,通常会对模型进行正则化,如使用岭回归(Ridge Regression)或LASSO回归(Least Absolute Shrinkage and Selection Operator),或者使用交叉验证来选择合适的多项式次数。

2.3 多项式回归的实际应用

多项式回归可以用于各种问题,如时间序列分析、预测模型等,尤其是在数据呈现非线性趋势时。

三、特征工程(Feature Engineering)和多项式回归(Polynomial Regression)结合

3.1 工具

使用之前实验室开发的函数以及matplotlib和NumPy

# 导入numpy库
import numpy as np
# 导入matplotlib库
import matplotlib.pyplot as plt
# 从lab_utils_multi导入函数
from lab_utils_multi import zscore_normalize_features, run_gradient_descent_feng
# 设置NumPy数组的显示精度
np.set_printoptions(precision=2)  # 减少NumPy数组的显示精度

3.2 特征工程和多项式回归概述

3.2.1 线性回归提供了一种构建模型的方法:

f w , b = w 0 x 0 + w 1 x 1 + . . . + w n − 1 x n − 1 + b (1) f_{\mathbf{w},b} = w_0x_0 + w_1x_1+ ... + w_{n-1}x_{n-1} + b \tag{1}fw,b =w0 x0 +w1 x1 +...+wn−1 xn−1 +b(1)

如果特征/数据是非线性的或特征的组合呢?例如,房价并不倾向于与居住面积线性相关,而是对非常小或非常大的房子进行惩罚。我们如何使用线性回归的“机械装置”来拟合这条曲线?回想一下,我们有的“机械装置”是修改(1)中的参数w \mathbf{w}w,b \mathbf{b}b以“适应”方程到训练数据。然而,无论怎样调整(1)中的w \mathbf{w}w,b \mathbf{b}b,都无法实现对非线性曲线的拟合。

3.2.2 多项式特征

上述我们考虑了一种数据非线性的情况。让我们尝试使用我们目前所知道的知识来拟合非线性曲线。我们将从简单的二次方程开始:y = 1 + x 2 y = 1+x^2y=1+x2

您熟悉我们正在使用的所有例程。它们可以在lab_utils.py文件中查看。我们将使用np.c_[..],这是一个NumPy例程,用于沿列边界拼接。

# 创建目标数据
x = np.arange(0, 20, 1)
y = 1 + x**2
X = x.reshape(-1, 1)
model_w,model_b = run_gradient_descent_feng(X, y, 迭代次数=1000, alpha = 1e-2)
plt.scatter(x, y, marker='x', c='r', label="实际值"); plt.title("没有特征工程"); plt.plot(x, X@model_w + model_b, label="预测值"); plt.xlabel("X"); plt.ylabel("y"); plt.legend(); plt.show()

输出结果:

正如预期地不是很好的拟合。我们需要的是类似于y = w 0 x 0 2 + b y= w_0x_0^2 + by=w0 x02 +b的项,或者是一个多项式特征。为了实现这一点,你可以修改输入数据以生成所需的特征。如果你用原始数据的平方版本替换X,那么你可以实现y = w 0 x 0 2 + b y= w_0x_0^2 + by=w0 x02 +b。让我们试一试。在下面交换X为X**2:

# 创建目标数据
x = np.arange(0, 20, 1)
y = 1 + x**2
# 工程特征
X = x**2  #<-- 添加了工程特征
X = X.reshape(-1, 1)  #X应该是一个2-D矩阵
model_w,model_b = run_gradient_descent_feng(X, y, iterations=10000, alpha=1e-7)
plt.scatter(x, y, marker='x', c='r', label="实际值"); plt.title("添加了x**2特征"); plt.plot(x, np.dot(X,model_w) + model_b, label="预测值"); plt.xlabel("x"); plt.ylabel("y"); plt.legend(); plt.show()

输出结果:

如图所示几乎完美的拟合。注意图表上方打印的w \mathbf{w}w和b的值:w,b由梯度下降找到:w: [1.], b: 0.049。梯度下降修改了我们的初始w , b \mathbf{w},bw,b值,使其成为(1.0,0.049)或模型y = 1 ∗ x 0 2 + 0.049 y=1x_0^2+0.049y=1∗x02 +0.049,非常接近我们的目标y = 1 ∗ x 0 2 + 1 y=1x_0^2+1y=1∗x02 +1。如果迭代次数更多,将会更好地拟合。

3.3 选择特征

在上面的例子中,我们知道需要一个x 2 x^2x2项。并非总是明显哪些特征是必需的。我们可以尝试添加各种潜在的特征来找到最有用的特征。例如,如果我们尝试的是:y = w 0 x 0 + w 1 x 1 2 + w 2 x 2 3 + b y=w_0x_0 + w_1x_1^2 + w_2x_2^3+by=w0 x0 +w1 x12 +w2 x23 +b

# 创建目标数据
x = np.arange(0, 20, 1)
y = x**2
# 工程特征
X = np.c_[x, x**2, x**3]   #<-- 添加了工程特征
model_w,model_b = run_gradient_descent_feng(X, y, 迭代次数=10000, alpha=1e-7)
plt.scatter(x, y, marker='x', c='r', label="实际值"); plt.title("x, x**2, x**3特征"); plt.plot(x, X@model_w + model_b, label="预测值"); plt.xlabel("x"); plt.ylabel("y"); plt.legend(); plt.show()

输出结果:

注意w \mathbf{w}w的值,[0.08 0.54 0.03],b是0.0106。这表明,在拟合/训练后,模型为:0.08 x + 0.54 x 2 + 0.03 x 3 + 0.0106 0.08x + 0.54x^2 + 0.03x^3 + 0.01060.08x+0.54x2+0.03x3+0.0106

梯度下降通过增加w 1 w_1w1 项相对于其他项的权重来强调数据的最佳拟合x 2 x^2x2数据。如果您运行很长时间,它将继续减少其他项的影响。

梯度下降通过强调相关的参数为我们选择了“正确”的特征

让我们回顾这个想法:

  • 最初,特征被重新缩放,使其相互可比
  • 较小的权重值意味着不太重要/正确的特征,在极端情况下,当权重变为零或非常接近零时,与拟合模型到数据相关的特征在拟合模型到数据时有用。
  • 在上面的例子中,拟合后与x 2 x^2x2特征相关的权重远大于x xx或x 3 x^3x3的权重,因为它是拟合数据最有用的特征。

3.4 另一种观点

在上面的例子中,多项式特征是基于它们与目标数据匹配的程度选择的。另一种思考方式是注意到我们仍然在使用线性回归,一旦我们创建了新的特征。考虑到这一点,最佳特征将与目标线性相关。这最好通过一个例子来理解。

# 创建目标数据
x = np.arange(0, 20, 1)
y = x**2
# 工程特征
X = np.c_[x, x**2, x**3]   #<-- 添加了工程特征
X_features = ['x','x^2','x^3']
fig,ax=plt.subplots(1, 3, figsize=(12, 3), sharey=True)
for i in range(len(ax)):
    ax[i].scatter(X[:,i],y)
    ax[i].set_xlabel(X_features[i])
ax[0].set_ylabel("y")
plt.show()

输出结果:

在上图中,x 2 x^2x2特征相对于目标值y yy是线性的。线性回归可以轻松地使用该特征生成模型。

3.5 特征缩放

如上所述,如果数据集的特征具有显著不同的尺度,应应用特征缩放以加速梯度下降。在上面的例子中,有x xx、x 2 x^2x2和x 3 x^3x3,自然会有非常不同的尺度。让我们对我们的示例应用Z-score标准化。

# 创建目标数据
x = np.arange(0,20,1)
X = np.c_[x, x**2, x**3]
print(f"Peak to Peak range by column in Raw        X:{np.ptp(X,axis=0)}")
# 添加均值标准化
X = zscore_normalize_features(X)     
print(f"Peak to Peak range by column in Normalized X:{np.ptp(X,axis=0)}")

输出结果:

现在我们可以再次尝试使用更大的alpha值:

x = np.arange(0,20,1)
y = x**2
X = np.c
X = zscore_normalize_features(X) 
model_w, model_b = run_gradient_descent_feng(X, y, iterations=100000, alpha=1e-1)
plt.scatter(x, y, marker='x', c='r', label="Actual Value"); plt.title("Normalized x x**2, x**3 feature")
plt.plot(x,X@model_w + model_b, label="Predicted Value"); plt.xlabel("x"); plt.ylabel("y"); plt.legend(); plt.show()

输出结果:

特征缩放使这个模型能够更快地收敛。

再次注意w \mathbf{w}w的值。w 1 w_1w1 项,即x 2 x^2x2项,是最受强调的。梯度下降几乎消除了x 3 x^3x3项。

3.6 复杂函数

通过特征工程,即使是相当复杂的函数也可以进行建模:

x = np.arange(0,20,1)
y = np.cos(x/2)
X = np.c_[x, x**2, x**3,x**4, x**5, x**6, x**7, x**8, x**9, x**10, x**11, x**12, x**13]
X = zscore_normalize_features(X) 
model_w,model_b = run_gradient_descent_feng(X, y, iterations=1000000, alpha = 1e-1)
plt.scatter(x, y, marker='x', c='r', label="Actual Value"); plt.title("Normalized x x**2, x**3 feature")
plt.plot(x,X@model_w + model_b, label="Predicted Value"); plt.xlabel("x"); plt.ylabel("y"); plt.legend(); plt.show()

输出结果:

四、总结

  1. 学习如何使用特征工程来构建线性回归模型,这些模型可以模拟复杂甚至高度非线性的函数
  2. 认识到在特征工程时应用特征缩放的重要性
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号
机器学习中的特征工程与多项式回归:原理、应用及代码示例