Logo
Section 1 / 8

特征空间

通过实现特征空间探索、子空间分析和特征变换,学习特征工程技巧。

导入

特征空间

通过实现特征空间探索、子空间分析和特征变换,学习特征工程技巧。

在监督学习和聚类中,都使用了“数据点”这一术语。具体而言,训练数据集中的每个数据点 x\bold x 都表示为 Rd\R^d 空间中的一个 dd 维向量,即 x∈Rd\bold x \in \R^d。向量 x\bold x 的各个元素称为特征,因此 x\bold x 也被称为特征向量。

特征空间

特征空间 是一种数学空间,用于表示给定数据集的特征或属性。数据集中的每一条观测都由特征空间中的一个向量表示,其中该向量的每一维对应观测的一个特定特征或属性。

例如,假设我们有一个汽车数据集,每辆汽车由其品牌、型号、年份、马力和燃油效率来描述。那么该数据集的特征空间就是一个五维空间,每一维对应上述一个特征。通过分析特征空间中特征向量之间的模式和关系,我们可以深入了解数据集的内在结构和特性。

...

特征空间是包含数据集所有特征向量的向量空间,每个特征向量都属于该空间,且满足 $\bold x \in \R^d$。数据集是从该特征空间中采集的样本。大多数情况下,特征空间是 $\R^d$ 的一个子空间,反映了数据集的内在结构。

子空间示例

考虑一个汽车数据集 D={(x1,y1),(x2,y2),…,(xn,yn)}D = \{(\bold x_1, y_1), (\bold x_2, y_2), \dots, (\bold x_n, y_n)\},其中每个 xi∈Rd\bold x_i \in \R^d 是描述一辆汽车的特征向量,如品牌、型号、年份、马力和燃油效率。假设我们希望定义一个仅包含马力大于 250 的汽车的子空间,可以通过以下代码实现:

1import numpy as np 2 3# 汽车数据集的特征向量示例 4# [品牌, 型号, 年份, 马力, 燃油效率 (mpg)] 5car1 = np.array(['Toyota', 'Corolla', 2015, 132, 29]) 6car2 = np.array(['Honda', 'Accord', 2020, 252, 33]) 7car3 = np.array(['Tesla', 'Model S', 2018, 518, 98]) 8car4 = np.array(['Ford', 'Mustang', 2010, 315, 22]) 9car5 = np.array(['Chevrolet', 'Impala', 2012, 300, 23]) 10 11# 创建特征向量数组 12cars = np.array([car1, car2, car3, car4, car5]) 13 14# 定义马力大于 250 的汽车子空间 15horsepower_subspace = cars[cars[:, 3].astype(int) > 250, :] 16 17# 打印子空间 18print("马力大于 250 的汽车子空间:\n") 19print(horsepower_subspace)

以上代码说明如下:

  • 第 5–9 行:生成一组汽车特征的示例数据。
  • 第 12 行:创建一个二维数组,每一行代表一辆汽车的特征。
  • 第 15 行:通过筛选出马力特征大于 250 的行,定义马力大于 250 的汽车子空间。
  • 第 18–19 行:输出该子空间。

注意:在真实世界的数据集中,特征空间通常是一个子空间,但其维度仍指特征向量的分量个数 dd。因此,我们可以将其视为一个 dd 维向量空间,其中包含所有的特征向量。

特征变换

考虑一个回归数据集,其中 d=1d=1,此时特征向量实际上是实数。假设目标值 yiy_i 也是实数。现考虑两个不同的模型:fw1(xi)=w1xif_{w_1}(x_i)=w_1x_i 和 gw1,w2(xi)=w2xi2+w1xig_{w_1,w_2}(x_i)=w_2x^2_i+w_1x_i,用于预测 yiy_i。显然,在一维特征空间 R1\R^1 中,ff 表示一条直线,而 gg 表示一个二次多项式。

1import numpy as np 2from matplotlib import pyplot as plt 3 4def f(w1, x): 5 return w1*x 6def g(w1, w2, x): 7 return w2*(x**2) + w1*x 8 9w1, w2 = 1, 2 10x_total = np.linspace(-3,3,50) 11 12# 绘图 13fig, ax = plt.subplots() 14ax.plot(x_total, f(w1, x_total), linewidth=1, label="f", color = "green") 15ax.plot(x_total, g(w1, w2, x_total), linewidth=1, label="g", color = "blue") 16plt.grid(color = 'b', linestyle = '--', linewidth = 0.3) 17plt.xlabel(r'$x$',fontsize=20) 18plt.ylabel(r'$\hat y$',fontsize=20) 19plt.title('$f(x)=w_1x$, $g(x)=w_2x^2+w_1x$',fontsize=15) 20ax.legend() 21ax.set_ylim(-5, 20) 22plt.show()

为了进行特征变换,我们可以构造一个 R2\R^2 中的向量 zi\bold z_i,令 z1i=xiz_{1i} = x_i,z2i=xi2z_{2i} = x_i^2。于是函数 gw1,w2(zi)=w2z2i+w1z1ig_{w_1,w_2}(\bold z_i)=w_2z_{2i}+w_1z_{1i} 就表示在变换后的特征空间 zi\bold z_i 中的一个平面。

注意:这种变换后的特征空间非常有用,因为线性模型可以高效地估计由 gw1,w2(zi)g_{w_1,w_2}(\bold z_i) 所表示平面的参数。换句话说,模型 gg 在变换后的特征空间 zi\bold z_i 中是线性的。

1import numpy as np 2from matplotlib import pyplot as plt 3from mpl_toolkits import mplot3d 4 5def g_linear(w1, w2, z1, z2): 6 return w2*z2 + w1*z1 7def g_poly(w1, w2, x): 8 return w2*(x**2) + w1*x 9 10x_total = np.linspace(-3, 3, 50) 11z1 = x_total 12z2 = z1**2 13w1, w2 = 1, 2 14Z1, Z2 = np.meshgrid(z1, z2) 15y_hat_linear = g_linear(w1, w2, Z1, Z2) 16y_hat_poly = g_poly(w1, w2, x_total) 17 18fig = plt.figure() 19ax = fig.add_subplot(1, 2, 1) 20ax.plot(x_total, y_hat_poly, linewidth=1, label="g", color = "blue") 21ax.scatter(x_total, y_hat_poly,label="$(x,\hat{y})$", color = '#65b2ff', edgecolors='black') 22plt.grid(color = 'b', linestyle = '--', linewidth = 0.3) 23plt.xlabel(r'$x$') 24plt.ylabel(r'$\hat y$') 25plt.title('$\hat{y}=g(x)=w_2x^2+w_1x$') 26ax.legend() 27 28 29ax = fig.add_subplot(1, 2, 2, projection='3d') 30ax.plot_surface(Z1, Z2, y_hat_linear, rstride=1, cstride=1, 31 cmap='viridis', edgecolor='none') 32 33ax.set_title('$\hat{y}=g(z_1,z_2)=w_2z_2+w_1z_1$') 34ax.set_xlabel('$z_1$') 35ax.set_ylabel('$z_2$') 36ax.set_zlabel('$\hat{y}$') 37plt.show()

更具体地,定义一个映射函数 ϕ\phi,将输入特征 xi\bold x_i 映射到变换后的特征 zi\bold z_i,即 zi=ϕ(xi)\bold z_i = \phi(\bold x_i)。模型 fw(xi)=wTϕ(xi)f_\bold{w}(\bold x_i) = \bold w^T \phi(\bold x_i) 在参数空间(w\bold w 空间)和变换后的特征空间(z\bold z 空间)中都是线性的,但在原始输入特征空间(x\bold x 空间)中可能非线性。

注意:以下几点值得注意:

  • 当模型 fwf_\bold{w} 在参数上是线性的时,即使它在输入特征 x\bold x 上是非线性的,我们仍然可以使用线性方法处理,只需在预处理阶段选择合适的变换函数 ϕ\phi 对特征进行变换即可。
  • 此后,我们将统一使用 ϕ(xi)\phi(\bold x_i) 代替 xi\bold x_i,以涵盖任何可能的特征变换情况;若无特征变换,则 ϕ\phi 为恒等函数。

聚类

广义线性模型