简述python的特点交互式_第42集 python机器学习:交互式特征和多项式特征

想要丰富的特征表示,特别是对于线性模型而言,另一种方法是添加原始数据的交互特征(interaction feature)和多项式特征(polynomial feature),这种特征工程通常用于统计建模,也常用语实际的机器学习中。

线性模型不仅可以用于学习偏移,也可以用于学习斜率。想要向分箱数据上的线性模型添加斜率,一种方法是重新加入原始特征,如下代码所示:

from sklearn.linear_model import LinearRegression

from sklearn.tree import DecisionTreeRegressor

from mglearn.datasets import make_wave

x, y = make_wave(n_samples=150)

line = np.linspace(-3, 3, 1000, endpoint=False).reshape(-1, 1)

reg = DecisionTreeRegressor(min_samples_split=3).fit(x, y)

plt.plot(x[:, 0], y, 'o', c='k')

plt.ylabel("Regression output")

plt.xlabel("Input feature")

plt.legend(loc="best")

#在-3-3之间创建距离相等的10个箱子

bins = np.linspace(-3, 3, 11)

print("bins: {}".format(bins))

#然后我们记录每个数据点所属的箱子,可以通过np.digitize公式计算出来、

which_bin = np.digitize(x, bins=bins)

print("\nData points:\n", x[:5])

print("\nBin membership for data points:\n", which_bin[:5])

from sklearn.preprocessing import OneHotEncoder

#使用OneHotEncoder进行变换

encoder = OneHotEncoder(sparse=False)

#encoder.fit找到which_bin中的唯一值

encoder.fit(which_bin)

#transform创建one-hot编码

x_binned = encoder.transform(which_bin)

print(x_binned[:5])

print("x_binned.shape: {}".format(x_binned.shape))

#下面我们在one-hot编码后的数据上构建新的线性模型和新的决策树模型。

line_binned = encoder.transform(np.digitize(line, bins=bins))

reg = LinearRegression().fit(x_binned, y)

plt.plot(line, reg.predict(line_binned), label = 'Decision tree binned')

reg = DecisionTreeRegressor(min_samples_split=3).fit(x_binned, y)

plt.plot(line, reg.predict(line_binned), label='Linear regression binned')

plt.plot(x[:, 0], y, 'o', c='k')

plt.vlines(bins, 3, -3, linewidth=1, alpha=.2)

plt.ylabel("Regression output")

plt.xlabel("Input feature")

x_combined = np.hstack([x, x_binned])

print(x_combined.shape)

reg = LinearRegression().fit(x_combined, y)

line_combined = np.hstack([line, line_binned])

plt.plot(line, reg.predict(line_combined), label='Linear regression combined')

for bin in bins:

plt.plot([bin, bin], [-3, 3], ':', c='k')

plt.legend(loc="best")

plt.ylabel("Regression output")

plt.xlabel("Input feature")

plt.plot(x[:, 0], y, 'o', c='k')

上述代码运行后部分结果如图所示:

使用分箱特征和单一全局斜率的线性回归

在这个例子中,模型在每个箱子中学到一个偏移量,还学到一个斜率。学到的斜率是向下的,并且在所有箱子中都相同——只有一个x特征,也就只有一个斜率。

因为斜率在所有箱子中都是相同的,所以它们似乎不是很有用,我们更希望每个箱子都有一个不同的斜率,为了实现这一点,我们可以添加交互特征或乘积特征,用来表示数据点所在的箱子以及数据在x轴上的位置,这个特征是箱子指示符与原始特征的乘积,下面我们来创建数据集并将其可视化:

x_product = np.hstack([x_binned, x*x_binned])

print(x_product.shape)

reg = LinearRegression().fit(x_product, y)

line_product = np.hstack([line_binned, line*line_binned])

plt.plot(line, reg.predict(line_product), label='linear regression product')

for bin in bins:

plt.plot([bin, bin], [-3, 3], ':', c='k')

plt.plot(x[:, 0], y, 'o', c='k')

plt.ylabel("Regression output")

plt.xlabel("Input feature")

plt.legend(loc="best")

运行后其结果如下

每个箱子具有不同斜率的回归

从运行结果可知,现在这个模型中每个箱子的斜率不再相同,使用分箱是扩展连续特征的一种方法,另一种方法是使用原始特征的多项式,对于给定的特征x,我们可以进行变换,如x**2, x**3等等,这在preprocession模块的PolynomialFeatures中实现。

from sklearn.preprocessing import PolynomialFeatures

#包含直到x**10的多项式,默认的“include_bias=True”添加恒等于1的常数特征

poly = PolynomialFeatures(degree=10, include_bias=False)

poly.fit(x)

x_poly = poly.transform(x)

#多项式次数为10,所以生成了10个特征:

print("x_poly.shape:{}".format(x_poly.shape))

#比较x和x_poly元素

print("Entries of x:{}".format(x[:5]))

print("Entries of x_poly: {}".format(x_poly[:, 5]))

#调用get_feature_names方法来获取特征的寓意,给出每个特征的指数

print("Poly feature names:\n{}".format(poly.get_feature_names))

运行后部分结果如下:

具有10个特征多项式的部分结果

将多项式特征与线性回归模型一起使用,我们可以得到经典的多项式回归模型:

reg = LinearRegression().fit(x_poly, y)

line_poly = poly.transform(line)

plt.plot(line, reg.predict(line_poly), label='polynomial linear regression')

plt.plot(x[:, 0], y, 'o', c='k')

plt.xlabel("Input value")

plt.ylabel("output regression value")

plt.legend(loc="best")

运行后结果为:

具有10次多项式特征的线性回归

由运行结果可以看出,多项式特征在这个一维数据集上得到了非常平滑的拟合,但是高次数多项式在边界上或数据很少的区域可能会有极端表现,下面我们在原始数据上不使用任何变换应用SVM来对比。

from sklearn.svm import SVR

for gamma in [1, 10]:

svr = SVR(gamma=gamma).fit(x, y)

plt.plot(line, svr.predict(line), label='SVR gamma={}'.format(gamma))

plt.plot(x[:,0], y, 'o', c='k')

plt.xlabel("input feature value")

plt.ylabel("output regression value")

plt.legend(loc="best")

运行后结果如图:

对于RBF核的SVM,使用不同的gamma参数的对比

由运行结果可以看出,使用更加复杂的模型(核SVM),我们能够学到一个与多项式回归复杂度类似的预测结果,且不需要进行显示的特征变换。

下次我们将以波士顿房价数据集来进行简单的说明对比。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值