Feature engineering

特征工程

特征工程和多项式回归,它允许你使用线性回归机制来拟合非常复杂甚至非常非线性的函数

特征工程和多项式回归 - Feature Engineering and Polynomial Regression Overview

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

fw,b=w0x0+w1x1+...+wn1xn1+bf_{\mathbf{w},b} = w_0x_0 + w_1x_1+ ... + w_{n-1}x_{n-1} + b

如果特征/数据是非线性的,或者是特征的组合,该怎么办?例如,住房价格与居住面积并不呈线性关系,而是会影响到非常小或非常大的房屋,从而形成上图所示的曲线。我们如何利用线性回归机制来拟合这条曲线呢?回想一下,我们所拥有的 "工具 "就是修改参数 𝐰𝐰 , 𝐛𝐛,使方程与训练数据 "拟合"。然而,无论怎样调整 𝐰𝐰 , 𝐛𝐛 都无法拟合非线性曲线。

多项式特征 - Polynomial Features

简单的二次方: 𝑦=1+𝑥2𝑦=1+𝑥2

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,iterations=1000, alpha = 1e-2)

拟合得不是很好。需要的是 y=w0x02+by= w_0x_0^2 + b多项式特征。为了实现这一点,你可以修改输入数据构建所需的特征。如果你将原始数据与一个平方 𝑥𝑥 值的版本交换,那么你可以实现 y=w0x02+by= w_0x_0^2 + b。将X换成下面的X**2

x = np.arange(0, 20, 1)
y = 1 + x**2

# Engineer features 
X = x**2      #<-- added engineered feature

X = X.reshape(-1, 1)  #X should be a 2-D Matrix
model_w,model_b = run_gradient_descent_feng(X, y, iterations=10000, alpha = 1e-5)
w,b found by gradient descent: w: [1.], b: 0.0490

w,b found by gradient descent: w: [1.], b: 0.0490 .梯度下降法将 𝐰,𝑏𝐰,𝑏 的初始值修改为 (1.0, 0.049),也就是 y=1x02+0.049y=1*x_0^2+0.049 的模型,非常接近我们的目标值 y=1x02+1y=1*x_0^2+1 。如果运行时间更长,匹配效果可能会更好

选择特征 - Selecting Features

通过上面,我们知道需要一个 𝑥2𝑥^2 术语。需要哪些功能并不总是显而易见的。我们可以添加各种潜在的特征,尝试找到最有用的特征。例如,如果尝试使用: y=w0x0+w1x12+w2x23+by=w_0x_0 + w_1x_1^2 + w_2x_2^3+b

# create target data
x = np.arange(0, 20, 1)
y = x**2

# engineer features .
X = np.c_[x, x**2, x**3]   #<-- added engineered feature
model_w,model_b = run_gradient_descent_feng(X, y, iterations=10000, alpha=1e-7)

plt.scatter(x, y, marker='x', c='r', label="Actual Value"); plt.title("x, x**2, x**3 features")
plt.plot(x, X@model_w + model_b, label="Predicted Value"); plt.xlabel("x"); plt.ylabel("y"); plt.legend(); plt.show()
w,b found by gradient descent: w: [0.08 0.54 0.03], b: 0.0106

𝐰𝐰 ,[0.08 0.54 0.03]和 b 的值为0.0106。这意味着拟合/训练后的模型是:

0.08x+0.54x2+0.03x3+0.0106 0.08x + 0.54x^2 + 0.03x^3 + 0.0106

梯度下降法通过增加 𝑤1𝑤_1 项与其他项的比较,强调了与 𝑥2𝑥^2 数据拟合度最高的数据。 如果运行很长时间,它将继续减少其他项的影响

梯度下降法通过强调相关参数,为我们挑选出 "正确 "的特征

权重值越小,意味着特征越不重要/越不正确,极端情况下,当权重为零或非常接近零时,相关特征对模型拟合数据就没有用处了

以上,在拟合后,与 𝑥2𝑥^2 特征相关的权重远大于 𝑥𝑥𝑥3𝑥^3 的权重,因为它对拟合数据最有用

另一种观点

多项式特征的选择基于它们与目标数据的匹配程度。另一种思考方式是,一旦我们创建了新特征,我们仍然在使用线性回归。因此,相对于目标数据,最佳特征将是线性的。通过一个例子可以更好地理解这一点

# create target data
x = np.arange(0, 20, 1)
y = x**2

# engineer features .
X = np.c_[x, x**2, x**3]   #<-- added engineered feature
X_features = ['x','x^2','x^3']

以上可以看出, 𝑥2𝑥^2 与目标值 𝑦𝑦 的映射特征是线性的。线性回归可以很容易地利用该特征生成一个模型

缩放特征 - Scaling features

如果数据集的特征尺度差异很大,则应使用特征缩放来加速梯度下降。在上面的例子中,有 𝑥𝑥𝑥2𝑥^2𝑥3𝑥^3它们的尺度自然会有很大不同。让我们将 Z 值归一化应用到示例中

# create target data
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)}")

# add mean_normalization 
X = zscore_normalize_features(X)     
print(f"Peak to Peak range by column in Normalized X:{np.ptp(X,axis=0)}")

Peak to Peak range by column in Raw        X:[  19  361 6859]
Peak to Peak range by column in Normalized X:[3.3  3.18 3.28]

用更激进的 alpha 值再试一次

x = np.arange(0,20,1)
y = x**2

X = np.c_[x, x**2, x**3]
X = zscore_normalize_features(X) 

model_w, model_b = run_gradient_descent_feng(X, y, iterations=100000, alpha=1e-1)

特征缩放使得收敛速度更快

请再次注意 𝐰𝐰 的值。 𝑤1𝑤_1 项,也就是 𝑥2𝑥^2 项最突出。梯度下降法几乎消除了 𝑥3𝑥^3

复杂函数 - Complex Functions

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)

Last updated

Was this helpful?