PCA 机器学习实战Demo

PCA算法框架

  1. 找到数据方差最大的投影方向;
  2. 利用数据协方差矩阵的特征值向量矩阵作为基,定义了新空间。
输入:训练数据集X
输出:以新的基表示的特征Y

1). 数据清洗,并规范化训练数据,使变量中心为0,方差为1;(减均值,除方差)
2). 求数据的协方差矩阵∑:∑=XTX;(T代表X的转置)
3). 求协方差矩阵的特征值λ:det(X-λI)=0;
4). 求协方差矩阵特征向量v:∑v = λv;(求出的特征向量要进行标准化处理)
5). 创建协方差矩阵∑的特征向量矩阵:E=[v1, v2, ..., vn]
6). 求变换后的矩阵Y:Y = XE

编码实现采用Numpy,numpy中的cov函数已经实现了中心化的步骤,并且numpy采用无偏估计,如下代码所示,cov_mat1与cov_mat2是相等的

matrix = np.mat([[4, 4, 0, 2, 2],
                 [4, 0, 0, 3, 3],
                 [4, 0, 0, 1, 1],
                 [1, 1, 1, 2, 0],
                 [2, 2, 2, 0, 0],
                 [1, 1, 1, 0, 0],
                 [5, 5, 5, 0, 0]])
meaned_matrix = matrix - np.mean(matrix, axis=0)
cov_mat1 = np.cov(matrix, rowvar=False)
cov_mat2 = meaned_matrix.T * meaned_matrix / (meaned_matrix.shape[0] - 1)

利用numpy进行PCA,只需要进行4步:

# 1. 计算协方差矩阵
cov_matrix = np.cov(matrix, rower=False)
# 2. 计算特征值及特征向量
eig_vals, eig_vects = np.linalg.eig(cov_matrix) 
# 3. 生成主成分的特征向量矩阵
eig_val_index = np.argsort(eig_vals)[:-(dimension + 1):-1]
eig_vectors_mat = eig_vects[:, eig_val_index]
# 4. 求压缩后的矩阵
transformed_mat = mean_removed * eig_vectors_mat
# 5. 重建降维后的矩阵
reconstructed_mat = (transformed_mat * eig_vectors_mat.T) + mean_vals

问题概述

半导体是在一些极为先进的工厂中制造出来的。设备的生命早期有限,并且花费极其巨大。
虽然通过早期测试和频繁测试来发现有瑕疵的产品,但仍有一些存在瑕疵的产品通过测试。
如果我们通过机器学习技术用于发现瑕疵产品,那么它就会为制造商节省大量的资金。

具体来讲,它拥有590个特征。我们看看能否对这些特征进行降维处理。

对于数据的缺失值的问题,我们有一些处理方法(参考第5章)
目前该章节处理的方案是:将缺失值NaN(Not a Number缩写),全部用平均值来替代(如果用0来处理的策略就太差劲了)。

一. 首先分析数据,获取主成分方向的数目

def analyse_data(data_mat, threshold=0.9):
    # 返回结果
    pri_dir_num = -1

    # 协方差矩阵
    cov_mat = np.cov(data_mat, rowvar=False)
    # 求特征值和特征向量
    eig_vals, eig_vects = np.linalg.eig(cov_mat)
    # 将特征值从大到小排序,返回对应的下标;特征值越大说明数据在对应的特征向量方向方差越大,越重要
    eig_val_index = np.argsort(eig_vals)[:-(data_mat.shape[1] + 1):-1]

    '''
    特征值的重要性评估,如果选出的主方向的重要性比例达到threshold要求,
    则停止,并返回主方向数
    '''
    cov_all_score = np.float(sum(eig_vals))
    sum_cov_score = 0
    for i in range(0, len(eig_val_index)):
        line_cov_score = np.float(eig_vals[eig_val_index[i]])
        sum_cov_score += line_cov_score
        # 方差占比
        variance_ratio = line_cov_score / cov_all_score * 100
        # 累积方差占比,压缩的精度
        cumulative_variance_ratio = sum_cov_score / cov_all_score * 100
        print('主成分:%s, 方差占比:%s%%, 累积方差占比:%s%%' % (format(i + 1, '2.0f'),
                                                  format(variance_ratio, '5.2f'),
                                                  format(cumulative_variance_ratio, '4.1f')))
        # 如果满足精度要求则返回主方向数目
        if cumulative_variance_ratio >= threshold * 100:
            pri_dir_num = i + 1
            break
    return pri_dir_num

二. 根据最佳的主成分列,压缩数据

def pca(data_matrix, dimension=9999999):
    """
    PCA降维
    :param data_matrix:     原数据集矩阵
    :param dimension:       保留的特征维数
    :return:
        transformed_mat     降维后数据集
        reconstructed_mat   新的数据集空间
    """
    # 计算每一列的均值
    mean_vals = np.mean(data_matrix, axis=0)

    # 每个向量同时都减去 均值
    mean_removed = data_matrix - mean_vals

    # cov协方差=[(x1-x均值)*(y1-y均值)+(x2-x均值)*(y2-y均值)+...+(xn-x均值)*(yn-y均值)]/(n-1)
    # 协方差矩阵:(多维)度量各个维度偏离其均值的程度
    covariance_mat = np.cov(data_matrix, rowvar=False)

    # eig_vals为特征值, eig_vects为特征向量
    eig_vals, eig_vects = np.linalg.eig(covariance_mat)
    # 对特征值,进行从小到大的排序,返回从小到大的index下标
    # -1表示倒序,将特征值从大到小排序
    eig_val_index = np.argsort(eig_vals)[:-(dimension + 1):-1]

    # 创建特征向量矩阵,eig_vects从大到小排序
    eig_vectors_mat = eig_vects[:, eig_val_index]
    # 求变换后的矩阵
    transformed_mat = mean_removed * eig_vectors_mat
    # 重建数据,由于特征向量矩阵满足正交性,所以特征值矩阵的逆和转置是相等的
    reconstructed_mat = (transformed_mat * eig_vectors_mat.T) + mean_vals

    return transformed_mat, reconstructed_mat

由于特征向量的矩阵是正交的,所以ET=E-1,ETE=E-1E=I。
因此,设R代表reconstructed_mat,MR代表mean_removed,E代表eig_vectors_mat,MV代表mean_vals:

R = MR * E * ET + MV = MR + MV (即原矩阵抽取主成分后的结果)

红色为主成分

补充:

  1. 两个对称方阵A,B,满足A = PTBP,P是正交矩阵:ET=E-1,那么A和B为正交相似
  2. 任何一个对称矩阵A都可以正交相似于一个对角矩阵D,总存在一个正交矩阵P,使得A=PTDP
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容