吴恩达机器学习C1W2Lab04-特征工程与多项式回归

目标

在本实验室你可以:
探索特征工程和多项式回归,它们允许您使用线性回归的机制来拟合非常复杂,甚至是非线性的函数。

工具

您将利用在以前的实验中开发的函数以及matplotlib和NumPy。

import numpy as np
import matplotlib.pyplot as plt
from lab_utils_multi import zscore_normalize_features, run_gradient_descent_feng
np.set_printoptions(precision=2)  # reduced display precision on numpy arrays

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

线性回归提供了一种建立形式模型的方法:
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=w0x0+w1x1+...+wn1xn1+b(1)
如果你的特征/数据是非线性的,或者是特征的组合呢?
比如:
房价不倾向于与居住面积成线性关系,而是对非常小或非常大的房子不利,导致上图所示的曲线。我们如何使用线性回归的机制来拟合这条曲线呢?回顾一下,我们有能力去修改式子1中的参数w,b达到拟合训练数据中。然而,w和b再多的调整也实现不了(1)中对非线性曲线的拟合。

生成多项式特征

上面我们考虑的是一个数据是非线性的场景。我们试着用已知的知识来拟合非线性曲线。我们从一个简单的二次函数开始: y = 1 + x 2 y = 1+x^2 y=1+x2
这些都可以在 lab_utils.py file 中被使用,We’ll use np.c_[…]。这一个NumPy例程,用于沿着列边界进行连接。
【注解】X@model_w计算的是X和model_w的矩阵乘法。@操作符在Python中表示矩阵乘法

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

plt.scatter(x, y, marker='x', c='r', label="Actual Value"); plt.title("no feature engineering")
plt.plot(x,X@model_w + model_b, label="Predicted Value");  plt.xlabel("X"); plt.ylabel("y"); plt.legend(); plt.show()

在这里插入图片描述在这里插入图片描述不出所料,不太合适。类似于 y = w 0 x 0 2 + b y= w_0x_0^2 + b y=w0x02+b或者多项式特征。要实现这一点,您可以修改输入数据来设计所需的特性。如果将原始数据与平方的版本交换X值。那么就可以实现 y = w 0 x 0 2 + b y= w_0x_0^2 + b y=w0x02+b。接下来试试把X换成X**2:

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

plt.scatter(x, y, marker='x', c='r', label="Actual Value"); plt.title("Added x**2 feature")
plt.plot(x, np.dot(X,model_w) + model_b, label="Predicted Value"); plt.xlabel("x"); plt.ylabel("y"); plt.legend(); plt.show()

在这里插入图片描述在这里插入图片描述太棒了!近乎完美的契合。注意w和b的值在图的正上方打印:w,b 由梯度下降可以看到: w: [1.], b: 0.0490。梯度下降修正了的初始值W和b成为(1.0,0.049) y = 1 ∗ x 0 2 + 0.049 y=1*x_0^2+0.049 y=1x02+0.049的模型。非常接近我们的目标 y = 1 ∗ x 0 2 + 1 y=1*x_0^2+1 y=1x02+1,如果你把它跑久一点,它可能是一个更好的匹配。

特征选取

上面,我们知道需要 x 2 x^2 x2项非常需要,需要哪些特性可能并不总是很明显。我们可以添加各种潜在的特性来尝试找到最有用的。 例如,如果我们尝试: 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+b y=w0x0+w1x12+w2x23+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=[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.0106 0.08x+0.54x2+0.03x3+0.0106
梯度下降强调了最适合 x 2 x^2 x2数据的数据,通过增加相对于其他数据的 w 1 w_1 w1项。如果你要跑很长时间,它会继续减少其他条款的影响。

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

让我们回顾一下这个想法:
最初,这些特征被重新缩放,使它们彼此具有可比性
更小的权重值意味着更不重要/正确的特征,在极端情况下,当权重变为零或非常接近于零时,相关的特征有助于将模型拟合到数据中。
上面,在拟合之后,与 x 2 x^2 x2特征相关的权值比 x x x x 3 x^3 x3的权值大得多,因为它在拟合数据时最有用。

备用视图

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

# 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']
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^2 x2特征映射到目标值 y y y是线性的。然后,线性回归可以很容易地使用该特征生成模型。

标度特性

如上一个实验所述,如果数据集具有明显不同尺度的特征,则应将特征缩放应用于速度梯度下降。在上面的例子中,有 x x x x 2 x^2 x2 x 3 x^3 x3,它们自然会有非常不同的尺度。让我们把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)}")

现在我们可以用一个更激进的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)

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_1 w1项,也就是 x 2 x^2 x2 项是最重要的。梯度下降法几乎消除了 x 3 x^3 x3项。

复数函数

通过特征工程,即使是非常复杂的函数也可以建模:

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()

在这里插入图片描述在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值