机器学习实战---读书笔记:第13章 利用PCA来简化数据

#!/usr/bin/env python
# encoding: utf-8

import matplotlib.pyplot as plt
from numpy import *

'''

机器学习实战---读书笔记:第13章 利用PCA来简化数据

关键:
1 降维技术
降维作用: 使数据集更容易使用,降低算法开销,去除噪声
主要关注未标注数据上的降维技术。
降维方法:
1) 主成分分析
Principal Component Analysis, PCA。
含义:数据从原来的坐标系转换到新的坐标系,新坐标系的选择是由数据本身决定的。
第一个新坐标轴选择的是: 原始火速局中方差最大的方向
第二个新坐标轴选择的是: 和第一个坐标轴蒸饺且具有最大放长的方向。
该过程一直重复,重复次数为原始数据中特征的数目。
会发现: 大部分方差都包含在最前面的几个新坐标轴中。忽略剩余的坐标轴,即对数据进行了降维处理。

2) 因子分析
Factor Analysis
含义: 假设在观察数据的生成中有一些观察不到的隐变量(latent variable)。假设观察数据是这些隐变量
和某些噪声的线性组合。那么隐变量的数据可能比观察数据的数目少,也就是说通过找到隐变量就可以实现
数据的降维。

3) 独立成分分析
Independent Componennt Analysis, ICA
含义: ICA假设数据是从N个数据源生成的,这一点和因子分析有些类似。假设数据为多个数据源的混合观察结果,
这些数据源之间在统计上是相互独立的,而PCA值假设数据是不相关的。同因子分析一样,如果数据源的数目少于
观察数据的数目,可以实现降维。

PCA应用最广泛。

2 PCA
优点: 降低数据的复杂性,识别最重要的多个特征
缺点: 不一定需要,且可能损失有用信息
适用数据类型: 数值型数据

2.1 移动坐标轴
选择覆盖数据最大差异性的坐标轴,选择第二条坐标轴。
假如该坐标轴与第一条坐标轴垂直,它就是覆盖数据次
大差异性的坐标轴。

坐标轴的旋转并没有减少数据的维度。
通过PCA进行降维处理,可以同时获得SVM和决策树的优点,
得到了和决策树一样简单的分类器,同时分类间隔和SVM一样好。

第一个主成分就是从数据差异性最大(即方差最大)的方向提取出来的,第二个主成分则来自于
数据差异性次大的方向,并且该方向与第一个主成分方向蒸饺。
通过数据集的协方差矩阵及其特征值分析,就可以求得这些主成分的值。
一旦得到协方差矩阵的特征向量,就可以保留最大的N个值。这些特征向量也给出了
N个最重要特征的真实结构。可以通过将数据乘以这N个特征向量而将它转换到新的空间。


2.2 特征值分析
特征值分析师线性代数中的,它能够通过数据的一般格式来揭示数据的真实结构,
即我们常说的特征向量和特征值。在等式Av = lamba v中,v是特征向量,lambda是特征值。
特征值都是简单的标量值,因此Av = lambda v代表的是:
如果特征想想v被某个矩阵A左乘,那么它就等于某个标量lambda乘以v。
Numpy何种有寻找特征向量和特征值的模块linalg,它有eig()方法,该方法用于求解特征向量和特征值。

3 在Numpy中实现PCA
将数据转换成前N个主成分的伪代码大致如下:
1) 去除平均值
2) 计算协方差矩阵,计算协方差矩阵的特征值和特征向量
3) 将特征值从大到小排序,保留最上面的N个特征向量
4) 将数据转换到上述N个特征向量构建的新空间中

输入参数:
dataMat: 用于进行PCA主成分分析的数据集
topNFeature: 可选参数,即应用的N个特征。如果不指定,则会返回前9999999个特征,或者原始数据中全部的特征
返回结果: 降维后的矩阵,降维之后的数据集
算法:
步骤1: 计算原始数据集的平均值,去除平均值
步骤2: 计算协方差矩阵机及其特征值
步骤3: 对特征值按照从大到小排序
步骤4: 将其对应的k个特征向量分别作为列向量组成特征向量矩阵
步骤5: 将样本点投影到选取的特征向量上,得到降维后的数据
步骤6: 还原数据
步骤7: 返回降维数据和还原的数据

总结:
PCA降维过程主要就是:
计算数据集的协方差矩阵和特征值,将特征值找到大到小排序,选取对应
特征值的特征向量组成的矩阵,将数据转换到新空间

参考:
https://www.cnblogs.com/lzllovesyl/p/5235137.html
http://www.dataguru.cn/thread-733306-1-1.html

5 numpy中相关方法的使用
1) numpy.mean
numpy.mean(a, axis, dtype, out,keepdims )

mean()函数功能:求取均值
经常操作的参数为axis,以m * n矩阵举例:

axis 不设置值,对 m*n 个数求均值,返回一个实数
axis = 0:压缩行,对各列求均值,返回 1* n 矩阵
axis =1 :压缩列,对各行求均值,返回 m *1 矩阵

参考:https://blog.csdn.net/lilong117194/article/details/78397329


2) numpy.cov
var:表示方差,各项减均值的平凡求和后再除以N
std:标准差
cov:协方差,与var类似,但是除以N-1

numpy.cov(m, y=None, rowvar=True, bias=False, 
          ddof=None, fweights=None, aweights=None)

作用: 对给定的数据和权重,估计协方差矩阵
协方差表示两个变量在一起变化的水平。如果我们检查N维样本,则X = [x_1,x_2,... x_N] ^ T,则协方差矩阵元素C_ {ij}是x_i和x_j的协方差。元素C_ {ii}是x_i的方差。

参数:
(1)m :array_like
包含多个变量和观察值的1-D或2-D数组。M的每一行代表一个变量(即特征),
每一列都是对所有这些变量的单一观察(即每一列代表一个样本)。 另见下面的rowvar。

(2)y :array_like, optional
另外一组变量和观察结果。 y具有与m相同的形式。至于有什么作用,参考后面的实例。

(3)rowvar : bool,optional
如果rowvar为True(默认值),则每行代表一个变量,并在列中显示(即每一列为一个样本)。 否则,关系被转置:每列代表变量,而行包含观察值。

(4)bias : bool,optional
默认归一化(False)为(N-1),其中N为给定观测次数(无偏估计)。如果bias为True,则归一化为N. 这些值可以通过使用numpy版本> = 1.5中的关键字ddof来覆盖。

(5)ddof : int,optional
如果不是,偏移所隐含的默认值将被覆盖。请注意,ddof = 1将返回无偏估计,即使指定了权重和权重,ddof = 0将返回简单平均值。详见附注。 默认值为None。

(6)fweights :array_like, int, optional
整数频率权重组成的1-D数组; 代表每个观察向量应重复的次数。

(7)aweights :array_like, optional
观测矢量权重的1-D数组。对于被认为“重要”的观察,这些相对权重通常很大,而对于被认为不太重要的观察,这些相对权重较小如果ddof = 0,则可以使用权重数组将概率分配给观察向量。


参考:
https://blog.csdn.net/zhuzuwei/article/details/77848323
https://blog.csdn.net/tumin999/article/details/78355861
https://blog.csdn.net/maoersong/article/details/21823397
https://blog.csdn.net/chixujohnny/article/details/51063562


3) argsort
numpy.argsort(a, axis=-1, kind='quicksort', order=None)

作用: argsort函数返回的是数组值从小到大的索引值
输入参数:
返回结果: 返回的是数组值从小到大的索引值

参考:
https://blog.csdn.net/maoersong/article/details/21875705

4) 数组切片
b = a[i:j:s]表示:i,j与上面的一样,但s表示步进,缺省为1.
所以a[i:j:1]相当于a[i:j]
当s<0时,i缺省时,默认为-1. j缺省时,默认为-len(a)-1
所以a[::-1]相当于 a[-1:-len(a)-1:-1],也就是从最后一个元素到第一个元素复制一遍,即倒序。

参考:https://blog.csdn.net/mingyuli/article/details/81604795
'''

def loadDataSet(fileName, delim='\t'):
    results = []
    with open(fileName, 'r') as fr:
        for line in fr.readlines():
            if not line:
                continue
            result = line.strip().split(delim)
            results.append(result)
    dataArray = [map(float, result) for result in results]
    data = mat(dataArray)
    return data


'''
作用:
输入参数:
dataMat: 用于进行PCA主成分分析的数据集
topNFeature: 可选参数,即应用的N个特征。如果不指定,则会返回前9999999个特征,或者原始数据中全部的特征
返回结果: 降维后的矩阵,降维之后的数据集
算法:
步骤1: 计算原始数据集的平均值,去除平均值
步骤2: 计算协方差矩阵机及其特征值
步骤3: 对特征值按照从大到小排序
步骤4: 将其对应的k个特征向量分别作为列向量组成特征向量矩阵
步骤5: 将样本点投影到选取的特征向量上,得到降维后的数据
步骤6: 还原数据
步骤7: 返回降维数据和还原的数据

总结:
PCA降维过程主要就是:
计算数据集的协方差矩阵和特征值,将特征值找到大到小排序,选取对应
特征值的特征向量组成的矩阵,将数据转换到新空间

参考:
https://www.cnblogs.com/lzllovesyl/p/5235137.html
http://www.dataguru.cn/thread-733306-1-1.html

'''
def pca(dataMat, topNFeature=9999999):
    meanVals = mean(dataMat, axis=0)
    meanRemoved = dataMat - meanVals
    covMat = cov(meanRemoved, rowvar=0)
    eigVals, eigVectors = linalg.eig(mat(covMat))
    eigValIndexes = argsort(eigVals)
    # NOTE, it needs to reverse it
    eigValIndexes = eigValIndexes[: -(topNFeature + 1): -1]
    redEigVector = eigVectors[:, eigValIndexes]
    lowDDataMat = meanRemoved * redEigVector
    recoverMat = (lowDDataMat * redEigVector.T) + meanVals
    return lowDDataMat, recoverMat


def process():
    dataMat = loadDataSet('testSet.txt')
    lowDDataMat, recoverMat = pca(dataMat, 1)
    # print "low demension data"
    # print lowDDataMat
    # print "recover data"
    # print recoverMat
    print shape(lowDDataMat)
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.scatter(dataMat[:, 0].flatten().A[0], dataMat[:, 1].flatten().A[0], marker='^', s=90)
    ax.scatter(recoverMat[:, 0].flatten().A[0], recoverMat[:, 1].flatten().A[0], marker='o', s=50, c='red')
    plt.show()

if __name__ == "__main__":
    process()

猜你喜欢

转载自blog.csdn.net/qingyuanluofeng/article/details/87168801
今日推荐