zoukankan      html  css  js  c++  java
  • 《机器学习实战》学习笔记——第13章 PCA

    1. 降维技术

    1.1 降维的必要性

    1. 多重共线性--预测变量之间相互关联。多重共线性会导致解空间的不稳定,从而可能导致结果的不连贯。2. 高维空间本身具有稀疏性。一维正态分布有68%的值落于正负标准差之间,而在十维空间上只有0.02%。

    3. 过多的变量会妨碍查找规律的建立。

    4. 仅在变量层面上分析可能会忽略变量之间的潜在联系。例如几个预测变量可能落入仅反映数据某一方面特征的一个组内。

    1. 2 降维的目的:

    1. 减少预测变量的个数

    2. 确保这些变量是相互独立的

    3. 提供一个框架来解释结果

    1. 3 降维的方法:

    • 主成分分析(PCA)
      • 从原来的坐标系转换到了新的坐标系,新坐标系的选择是由数据本身决定的
      • 第一个新坐标轴选择的是原始数据中方差最大的方向,第二个新坐标轴的选择和第一个坐标轴正交且具有最大方差的方向 
      • 该过程一直重复,重复次数为原始数据中特征的数目。 
      • 我们会发现,大部分方差都包含在最前面的几个新坐标轴中。因此,我们可以忽略余下的坐标轴,即对数据进行了降维处理 
    • 因子分析(Factor Analysis)
      • 我们假设在观察数据的生成中有一些观察不到的隐变量( latentvariable)。
      • 假设观察数据是这些隐变量和某些噪声的线性组合。那么隐变量的数据可能比观察数据的数目少,也就是说通过找到隐变量就可以实现数据的降维。
      • 因子分析已经应用于社会科学、金融和其他领域中了。
    • 独立成分分析(Independent Component Analysis ICA) 
      • 假设数据是从N个数据源生成的,这一点和因子分析有些类似,假设数据为多个数据源的混合观察结果。
      • 这些数据源之间在统计上是相互独立的,而在PCA中只假设数据是不相关的。
      • 同因子分析一样,如果数据源的数目少于观察数据的数目,则可以实现降维过程。 

    2. PCA

    数学推倒过程:http://blog.codinglabs.org/articles/pca-tutorial.html

    具体的细节,Andrew Ng的网页教程:http://deeplearning.stanford.edu/wiki/index.php/%E4%B8%BB%E6%88%90%E5%88%86%E5%88%86%E6%9E%90 ,写得很详细。

    2.1 优势:

    通过PCA进行降维处理,我们就可以同时获得SVM和决策树的优点:

    • 一方面,得到了和决策树一样简单的分类器,同时分类间隔和SVM— 样好。
    • 另外,由于只需要考虑一维信息,因此数据就可以通过比SVM 简单得多的很容易采用的规则进行区分

     

    2.2 实现:

     1 import numpy as np
     2 from numpy import linalg as la
     3 import matplotlib.pyplot as plt
     4 
     5 def pca(data,topNfeat = 999999):
     6     # data = np.array(data)
     7     # 1.计算各属性的平均值
     8     meanValues = np.mean(data, axis=0)
     9     # 2.减去平均值
    10     meanRemoved = data - meanValues
    11     # 3. 计算协方差矩阵的特征值和特征向量
    12     covData = np.cov(meanRemoved, rowvar=False)
    13     eigVal, eigVects = la.eig(covData)
    14     # 4. 将特征值的索引从大到小排序
    15     eigValInd = np.argsort(eigVal) # 从小到大
    16     eigValInd = eigValInd[: -(topNfeat + 1) : -1] # 逆序:从大到小
    17     # 5. 保留topNfeat个最大的特征向量
    18     redEigVects = eigVects[:, eigValInd]
    19     # 6. 将数据转换到上述topNfeat个特征向量构建的新空间中
    20     lowDData = np.dot(meanRemoved, redEigVects)
    21     # 7. 重构
    22     reconData = np.dot(lowDData, redEigVects.T) + meanValues
    23     return lowDData, reconData
    24 
    25 
    26 data = np.loadtxt('testSet.txt', delimiter='	')
    27 lowDData, reconData = pca(data, 2)
    28 
    29 # 画出原始数据/降维数据
    30 fig = plt.figure()
    31 plt.scatter(data[:, 0].flatten(), data[:, 1], marker='^', s=90)
    32 plt.scatter(reconData[:, 0].flatten(), reconData[:, 1].flatten(), marker='o', s=50, c='red')
    33 plt.show()

    2.3 选择主成分个数

    文章写到这里还没有完,应用PCA的时候,对于一个1000维的数据,我们怎么知道要降到几维的数据才是合理的?即n要取多少,才能保留最多信息同时去除最多的噪声?一般,我们是通过方差百分比来确定n的,这一点在Ufldl教程中说得很清楚,并且有一条简单的公式,下面是该公式的截图:

    所以代码修改:

     1 import numpy as np
     2 from numpy import linalg as la
     3 import matplotlib.pyplot as plt
     4 from sklearn import preprocessing
     5 def calculateN(eigVal, percentage):
     6     # 根据百分比确认选择特征向量的个数n的值
     7     eigValSorted = np.sort(eigVal) #升序
     8     eigValSorted = eigValSorted[-1::-1] #逆序(从大到小)
     9     eigValSum = sum(eigValSorted)
    10     num = 0
    11     tmpSum = 0
    12     for i in eigValSorted:
    13         tmpSum += i
    14         num +=1
    15         if tmpSum >= eigValSum * percentage:
    16             return num
    17 
    18 
    19 def pca(data,percentage = 0.99):
    20     # data = np.array(data)
    21     # 1.计算各属性的平均值
    22     meanValues = np.mean(data, axis=0)
    23     # 2.减去平均值
    24     meanRemoved = data - meanValues
    25     # 3. 计算协方差矩阵的特征值和特征向量
    26     covData = np.cov(meanRemoved, rowvar=False) # 按列存放
    27     eigVal, eigVects = la.eig(covData)
    28 
    29     # 4.计算要特征向量的个数n
    30     n = calculateN(eigVal, percentage=percentage)
    31     print(n)
    32 
    33     # 4. 将n个特征值的索引从大到小排序
    34     eigValInd = np.argsort(eigVal) # 从小到大
    35     eigValInd = eigValInd[-1:-(n+1):-1] # 逆序:从大到小
    36 
    37     # 5. 保留n个最大的特征向量
    38     redEigVects = eigVects[:, eigValInd]
    39     # 6. 将数据转换到上述topNfeat个特征向量构建的新空间中
    40     lowDData = np.dot(meanRemoved, redEigVects)
    41     # 7. 重构
    42     reconData = np.dot(lowDData, redEigVects.T) + meanValues
    43     return lowDData, reconData
    44 
    45 # 画出原始数据/降维数据
    46 def plotData(data, reconData):
    47     fig = plt.figure()
    48     plt.scatter(data[:, 0].flatten(), data[:, 1], marker='^', s=90)
    49     plt.scatter(reconData[:, 0].flatten(), reconData[:, 1].flatten(), marker='o', s=50, c='red')
    50     plt.show()
    51 
    52 def replaceWithMean():
    53     data = np.loadtxt('D:\学习\机器学习实战(中+英+源码)_FILES\machinelearninginaction\Ch13\secom.data', delimiter=' ')
    54     impute = preprocessing.Imputer()
    55     data = impute.fit_transform(data)
    56     return data
    57 
    58 data = replaceWithMean()
    59 lowDData, reconData = pca(data)
    60 plotData(data, reconData)

    ps:

  • 相关阅读:
    (基于Java)编写编译器和解释器第5章:解析表达式和赋值语句第一部分(连载)
    (基于Java)编写编译器和解释器第6章:解释执行表达式和赋值语句(连载)
    (基于Java)编写编译器和解释器第9章:解析声明第一部分(连载)
    (基于Java)编写编译器和解释器第5章:解析表达式和赋值语句第二部分(连载)
    (基于Java)编写编译器和解释器第4章:符号表(连载)
    (基于Java)编写编译器和解释器第8A章:基于Antlr解析&解释执行Pascal控制语句(连载)
    (基于Java)编写编译器和解释器第7章:解析(Parsing)控制语句第一部分(连载)
    (基于Java)编写编译器和解释器第5A章:基于Antlr解析表达式和赋值语句及计算(连载)
    (基于Java)编写编译器和解释器第7章:解析(Parsing)控制语句第二部分(连载)
    (基于Java)编写编译器和解释器第8章:解释Pascal控制语句(连载)
  • 原文地址:https://www.cnblogs.com/lesleysbw/p/6067063.html
Copyright © 2011-2022 走看看