七、特征工程

作者:Chris Albon

译者:飞龙

协议:CC BY-NC-SA 4.0

稀疏特征矩阵上的降维

  1. # 加载库
  2. from sklearn.preprocessing import StandardScaler
  3. from sklearn.decomposition import TruncatedSVD
  4. from scipy.sparse import csr_matrix
  5. from sklearn import datasets
  6. import numpy as np
  7. # 加载数据
  8. digits = datasets.load_digits()
  9. # 标准化特征矩阵
  10. X = StandardScaler().fit_transform(digits.data)
  11. # 生成稀疏矩阵
  12. X_sparse = csr_matrix(X)
  13. # 创建 TSVD
  14. tsvd = TruncatedSVD(n_components=10)
  15. # 在稀疏矩阵上使用 TSVD
  16. X_sparse_tsvd = tsvd.fit(X_sparse).transform(X_sparse)
  17. # 展示结果
  18. print('Original number of features:', X_sparse.shape[1])
  19. print('Reduced number of features:', X_sparse_tsvd.shape[1])
  20. '''
  21. Original number of features: 64
  22. Reduced number of features: 10
  23. '''
  24. # 前三个主成分的解释方差比之和
  25. tsvd.explained_variance_ratio_[0:3].sum()
  26. # 0.30039385372588506

核 PCA 降维

七、特征工程 - 图1

  1. # 加载库
  2. from sklearn.decomposition import PCA, KernelPCA
  3. from sklearn.datasets import make_circles
  4. # 创建线性不可分的数据
  5. X, _ = make_circles(n_samples=1000, random_state=1, noise=0.1, factor=0.1)
  6. # 应用带有径向基函数(RBF)核的核 PCA
  7. kpca = KernelPCA(kernel="rbf", gamma=15, n_components=1)
  8. X_kpca = kpca.fit_transform(X)
  9. print('Original number of features:', X.shape[1])
  10. print('Reduced number of features:', X_kpca.shape[1])
  11. '''
  12. Original number of features: 2
  13. Reduced number of features: 1
  14. '''

使用 PCA 的降维

七、特征工程 - 图2

  1. # 加载库
  2. from sklearn.preprocessing import StandardScaler
  3. from sklearn.decomposition import PCA
  4. from sklearn import datasets
  5. # 加载数据
  6. digits = datasets.load_digits()
  7. # 标准化特征矩阵
  8. X = StandardScaler().fit_transform(digits.data)
  9. # 创建保留 99% 方差的 PCA
  10. pca = PCA(n_components=0.99, whiten=True)
  11. # 使用 PCA
  12. X_pca = pca.fit_transform(X)
  13. # 展示结果
  14. print('Original number of features:', X.shape[1])
  15. print('Reduced number of features:', X_pca.shape[1])
  16. '''
  17. Original number of features: 64
  18. Reduced number of features: 54
  19. '''

PCA 特征提取

主成分分析(PCA)是数据科学中常见的特征提取方法。 从技术上讲,PCA 找到具有最高特征值的协方差矩阵的特征向量,然后使用这些特征向量将数据投影到相等或更小维度的新子空间。 实际上,PCA 将 n 个特征矩阵转换为(可能)小于 n 个特征的新数据集。 也就是说,它通过构造新的较少变量来减少特征的数量,这些变量捕获原始特征中找到的信息的重要部分。 但是,本教程的目的不是要解释 PCA 的概念,这在其他地方做得非常好,而是用于演示 PCA 的实际应用。

  1. # 导入库
  2. import numpy as np
  3. from sklearn import decomposition, datasets
  4. from sklearn.preprocessing import StandardScaler
  5. # 加载乳腺癌数据集
  6. dataset = datasets.load_breast_cancer()
  7. # 加载特征
  8. X = dataset.data

请注意,原始数据包含 569 个观测和 30 个特征。

  1. # 查看数据集的形状
  2. X.shape
  3. # (569, 30)

这里是数据的样子

  1. # 查看数据
  2. X
  3. '''
  4. array([[ 1.79900000e+01, 1.03800000e+01, 1.22800000e+02, ...,
  5. 2.65400000e-01, 4.60100000e-01, 1.18900000e-01],
  6. [ 2.05700000e+01, 1.77700000e+01, 1.32900000e+02, ...,
  7. 1.86000000e-01, 2.75000000e-01, 8.90200000e-02],
  8. [ 1.96900000e+01, 2.12500000e+01, 1.30000000e+02, ...,
  9. 2.43000000e-01, 3.61300000e-01, 8.75800000e-02],
  10. ...,
  11. [ 1.66000000e+01, 2.80800000e+01, 1.08300000e+02, ...,
  12. 1.41800000e-01, 2.21800000e-01, 7.82000000e-02],
  13. [ 2.06000000e+01, 2.93300000e+01, 1.40100000e+02, ...,
  14. 2.65000000e-01, 4.08700000e-01, 1.24000000e-01],
  15. [ 7.76000000e+00, 2.45400000e+01, 4.79200000e+01, ...,
  16. 0.00000000e+00, 2.87100000e-01, 7.03900000e-02]])
  17. '''
  18. # 创建缩放器对象
  19. sc = StandardScaler()
  20. # 使缩放器拟合特征并转换
  21. X_std = sc.fit_transform(X)

请注意,PCA 包含一个参数,即成分数。 这是输出特征的数量,需要进行调整。

  1. # 创建 PCA 对象,使用两个成分作为参数
  2. pca = decomposition.PCA(n_components=2)
  3. # 拟合 PCA 并转换数据
  4. X_std_pca = pca.fit_transform(X_std)

在 PCA 之后,新数据已降到了两个特征,其行数与原始特征相同。

  1. # 查看新特征数据的形状
  2. X_std_pca.shape
  3. # (569, 2)
  4. # 查看新特征数据
  5. X_std_pca
  6. '''
  7. array([[ 9.19283683, 1.94858307],
  8. [ 2.3878018 , -3.76817174],
  9. [ 5.73389628, -1.0751738 ],
  10. ...,
  11. [ 1.25617928, -1.90229671],
  12. [ 10.37479406, 1.67201011],
  13. [ -5.4752433 , -0.67063679]])
  14. '''

使用 KMeans 聚类对观测分组

  1. # 加载库
  2. from sklearn.datasets import make_blobs
  3. from sklearn.cluster import KMeans
  4. import pandas as pd
  5. # 制作模拟特征矩阵
  6. X, _ = make_blobs(n_samples = 50,
  7. n_features = 2,
  8. centers = 3,
  9. random_state = 1)
  10. # 创建 DataFrame
  11. df = pd.DataFrame(X, columns=['feature_1','feature_2'])
  12. # 创建 KMeans 聚类器
  13. clusterer = KMeans(3, random_state=1)
  14. # 拟合聚类器
  15. clusterer.fit(X)
  16. '''
  17. KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300,
  18. n_clusters=3, n_init=10, n_jobs=1, precompute_distances='auto',
  19. random_state=1, tol=0.0001, verbose=0)
  20. '''
  21. # 预测值
  22. df['group'] = clusterer.predict(X)
  23. # 前几个观测
  24. df.head(5)
feature_1feature_2group
0-9.877554-3.3361450
1-7.287210-8.3539862
2-6.943061-7.0237442
3-7.440167-8.7919592
4-6.641388-8.0758882

为 LDA 选择最佳数量的成分

在 scikit-learn 中,LDA 是使用LinearDiscriminantAnalysis实现的,包含一个参数n_components,表示我们想要返回的特征数。 为了找出用于n_components的参数值(例如,要保留多少参数),我们可以利用一个事实,explain_variance_ratio_告诉我们每个输出特征的解释方差并且是有序数组。

具体来说,我们可以运行Linear_iscriminantAnalysis,将n_components设置为None来返回由每个特征成分的解释方差比,然后计算需要多少成分才能超过解释方差的阈值(通常为 0.95 或 0.99)。

  1. # 加载库
  2. from sklearn import datasets
  3. from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
  4. # 加载鸢尾花数据集
  5. iris = datasets.load_iris()
  6. X = iris.data
  7. y = iris.target
  8. # 创建并运行 LDA
  9. lda = LinearDiscriminantAnalysis(n_components=None)
  10. X_lda = lda.fit(X, y)
  11. # 创建解释方差比的数组
  12. lda_var_ratios = lda.explained_variance_ratio_
  13. # 创建函数
  14. def select_n_components(var_ratio, goal_var: float) -> int:
  15. # 设置目前为止的初始解释方差
  16. total_variance = 0.0
  17. # 设置初始特征数
  18. n_components = 0
  19. # 对于每个特征的解释方差
  20. for explained_variance in var_ratio:
  21. # 将解释方差添加到总体
  22. total_variance += explained_variance
  23. # 成分数加一
  24. n_components += 1
  25. # 如果我们达到了我们的解释方差目标
  26. if total_variance >= goal_var:
  27. # 结束循环
  28. break
  29. # 返回成分数量
  30. return n_components
  31. # 执行函数
  32. select_n_components(lda_var_ratios, 0.95)
  33. # 1

为 TSVD 选择最佳数量的成分

  1. # 加载库
  2. from sklearn.preprocessing import StandardScaler
  3. from sklearn.decomposition import TruncatedSVD
  4. from scipy.sparse import csr_matrix
  5. from sklearn import datasets
  6. import numpy as np
  7. # 加载数据
  8. digits = datasets.load_digits()
  9. # Standardize the feature matrix
  10. X = StandardScaler().fit_transform(digits.data)
  11. # 制作系数矩阵
  12. X_sparse = csr_matrix(X)
  13. # 创建并使用特征数减一运行 TSVD
  14. tsvd = TruncatedSVD(n_components=X_sparse.shape[1]-1)
  15. X_tsvd = tsvd.fit(X)
  16. # 解释方差的列表
  17. tsvd_var_ratios = tsvd.explained_variance_ratio_
  18. # 创建函数
  19. def select_n_components(var_ratio, goal_var: float) -> int:
  20. # 设置目前为止的初始解释方差
  21. total_variance = 0.0
  22. # 设置初始特征数
  23. n_components = 0
  24. # 对于每个特征的解释方差
  25. for explained_variance in var_ratio:
  26. # 将解释方差添加到总体
  27. total_variance += explained_variance
  28. # 成分数加一
  29. n_components += 1
  30. # 如果我们达到了我们的解释方差目标
  31. if total_variance >= goal_var:
  32. # 结束循环
  33. break
  34. # 返回成分数量
  35. return n_components
  36. # 执行函数
  37. select_n_components(tsvd_var_ratios, 0.95)
  38. # 40

将 LDA 用于降维

  1. # 加载库
  2. from sklearn import datasets
  3. from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
  4. # 加载鸢尾花数据集
  5. iris = datasets.load_iris()
  6. X = iris.data
  7. y = iris.target
  8. # 创建 LDA,它将数据降维到 1 个特征
  9. lda = LinearDiscriminantAnalysis(n_components=1)
  10. # 运行 LDA 并使用它转换特征
  11. X_lda = lda.fit(X, y).transform(X)
  12. # 打印特征数
  13. print('Original number of features:', X.shape[1])
  14. print('Reduced number of features:', X_lda.shape[1])
  15. '''
  16. Original number of features: 4
  17. Reduced number of features: 1
  18. '''
  19. ## 查看解释方差比
  20. lda.explained_variance_ratio_
  21. # array([ 0.99147248])