主成分分析算法(Principal Component AnalysisPCA)的目的是找到能用较少信息描述数据集的特征组合。它意在发现彼此之间没有相关性、能够描述数据集的特征,确切说这些特征的方差跟整体方差没有多大差距,这样的特征也被称为主成分。这也就意味着,借助这种方法,就能通过更少的特征捕获到数据集的大部分信息。

PCA跟其他转换器用法类似。它只有主成分数量这一个参数。它默认会返回数据集中的所有特征。然而,PCA会对返回结果根据方差大小进行排序,返回的第一个特征方差最大,第二个特征方差稍小,以此类推。因此,前几个特征往往就能够解释数据集的大部分信息

案例集中包括3279, 1559列数据,其中前1558列是图片的各种属性,最后一列是图表是否广告的标志,怎么从这1558列特征中找到哪些特征是判断广告的重要标准。

代码示例

  1. #http://archive.ics.uci.edu/ml/datasets/Internet+Advertisements, Data Folder,ad.data and ad.names

  2. import os

  3. import numpy as np

  4. import pandas as pd

  5. from collections import defaultdict

  6. #用pandas加载数据集,查看数据质量

  7. data_folder = ''

  8. data_filename = os.path.join(data_folder,  "ad.data")

  9. ads = pd.read_csv(data_filename, header=None)

  10. #print(ads[:5])

  11. #print(ads.shape)

  12. #(3279, 1559)

  13. #定义转换函数,主要是数据异常则返回Nan

  14. #转换函数

  15. #转换函数

  16. def convert_number(x):

  17.    try:

  18.        return float(x)

  19.    except ValueError:

  20.        return np.nan

  21. #我们创建一个字典存储所有特征及其转换结果,把所有的特征值转换为浮点型。

  22. converters = defaultdict(convert_number)

  23. #还想把最后一列的值转换为01,该列表示每条数据的类别。

  24. converters[1558] = lambda x: 1 if x.strip() == "ad." else 0

  25. #加载数据集,在参数中指定我们刚创建的转化函数。

  26. ads = pd.read_csv("ad.data", header=None, converters=converters)

  27. ads = ads.replace('?', np.nan)

  28. ads = ads.replace(' ?', np.nan)

  29. ads = ads.replace('   ?', np.nan)   #第1,2列转换为NAN

  30. ads = ads.replace('     ?', np.nan) #第3列转换为NAN

  31. ads = ads.replace(np.nan, 0) #缺失值处理不到位,以后不能直接化0。看情况处理,本题应该取前2列取均值,第三列为前两列的比。

  32. print(ads[:5])

  33. #数据集所描述的是网上的图像,目标是确定图像是不是广告。

  34. #从数据集表头中无法获知梅列数据的含义。其他文件有更多的信息。前三个特征分别指图像的高

  35. #度、宽度和宽高比。最后一列是数据的类别,1表示是广告,0表示不是广告。

  36. #抽取用于分类算法的x矩阵和y数组,x矩阵为数据框除去最后一列的所有列,y数组包含数据框的

  37. #最后一列。

  38. X = ads.drop(1558, axis=1).values

  39. y = ads[1558]

  40. # 主成分分析算法(Principal Component AnalysisPCA)的目的是找到能用较少信息描述数 据集的特征组合。

  41. # 它意在发现彼此之间没有相关性、能够描述数据集的特征,确切说这些特征的方差跟整体方差没有多大差距,这样的特征也被称为主成分

  42. from sklearn.decomposition import PCA

  43. pca = PCA(n_components=5)

  44. Xd = pca.fit_transform(X)

  45. #返回的结果Xd矩阵只有五个特征,但是不容小觑,我们看一下每个特征的方差。

  46. np.set_printoptions(precision=3, suppress=True)


  47. print(Xd)

  48. print(Xd.shape)

  49. print(pca.components_) #:返回具有最大方差的成分。

  50. print(pca.explained_variance_ratio_)#:返回 所保留的n个成分各自的方差百分比。

  51. print(pca.n_components_)#:返回所保留的成分个数n

  52. print(pca.mean_)#:

  53. print(pca.noise_variance_)#:

  54. from sklearn.tree import DecisionTreeClassifier

  55. from sklearn.cross_validation import cross_val_score

  56. clf = DecisionTreeClassifier(random_state=14)

  57. scores_reduced = cross_val_score(clf, Xd, y, scoring='accuracy')

  58. print("PCA performance: {0:.3f}".format(scores_reduced.mean()))


  59. from matplotlib import pyplot as plt

  60. #PCA算法的另一个优点是,你可以把抽象难懂的数据集绘制成图形

  61. #获取数据集中类别的所有取值(只有两个:是广告和不是广告)。

  62. classes = set(y)

  63. #指定在图形中用什么颜色表示这两个类别。

  64. colors = ['red', 'green']

  65. #用zip函数将这两个列表组合起来,同时遍历。

  66. for cur_class, color in zip(classes, colors):#为属于当前类别的所有个体创建遮罩层。

  67.    mask = (y == cur_class).values

  68.    #使用pyplotscatter函数显示它们的位置。图中的xy的值为前两个特征。

  69.    plt.scatter(Xd[mask, 0], Xd[mask, 1], marker='o', color=color, label=int(cur_class))

  70. #创建图示,显示图像,从中就能看到分属两个类别的个体。

  71. plt.legend()

  72. plt.show()