主成分分析PCA学习笔记

简介:

主成分分析(principal components analysis,PCA)是一个简单的机器学习算法,主要思想是对高维数据进行降维处理,去除数据中的冗余信息和噪声。
算法:
输入样本:$D=\left \{ x_{1},x_{2},\cdots ,x_{m}\right \}$

               低纬空间的维数

过程:·
1:对所有样本进行中心化:$x_i\leftarrow x_i-\frac{1}{m}\sum_{i=1}^{m}x_i$;
2:计算所有样本的协方差矩阵:$XX^T$;
3:对协方差矩阵$XX^T$做特征值分解;
4:取最大的${d}'$个特征值做所对应的特征向量$w_1,w_2,\cdots ,w_{d'}$.
输出:投影矩阵$W=(w_1,w_2,\cdots ,w_{d'})$
PCA算法主要用在图像的压缩,图像的融合,人脸识别上:

PCA

在python的sklearn包中给出了PCA的接口:

from sklearn.decomposition import PCA
import numpy as np

X=np.array([[-1,-1],[-2,-1],[-3,-2],[1,1],[2,1],[3,2]])
#pca=PCA(n_components=2)
pca=PCA(n_components='mle')
pca.fit(X)
print(pca.explained_variance_ratio_)

以自己造的数据集进行测试并测试
程序提取了一个特征值

对二维数据进行降维

用PCA算法对testSet.txt数据集进行降维处理


import numpy as np
import matplotlib.pyplot as plt


def loadDataSet(filename, delim='\t'):
    fr = open(filename)
    StringArr = [line.strip().split(delim) for line in fr.readlines()]
    datArr = [map(float, line) for line in StringArr]
    return np.mat(datArr)


def pca(dataMat, topNfeat=9999999):
    meanVals = np.mean(dataMat, axis=0)
    meanRemoved = dataMat - meanVals  # remove mean
    covMat = np.cov(meanRemoved, rowvar=0)  # 寻找方差最大的方向a,Var(a'X)=a'Cov(X)a方向误差最大
    eigVals, eigVects = np.linalg.eig(np.mat(covMat))
    eigValInd = np.argsort(eigVals)  # sort, sort goes smallest to largest
    eigValInd = eigValInd[:-(topNfeat + 1):-1]  # cut off unwanted dimensions
    redEigVects = eigVects[:, eigValInd]  # reorganize eig vects largest to smallest
    lowDDataMat = meanRemoved * redEigVects  # transform data into new dimensions
    reconMat = (lowDDataMat * redEigVects.T) + meanVals
    return lowDDataMat, reconMat


dataMat = loadDataSet( 'testSet.txt')
print(dataMat)
lowDMat, recoMat = pca(dataMat, 1)
print(u'特征值是:')
print(lowDMat)
print(u'特征向量是:')
print(recoMat)

fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(np.array(dataMat[:, 0]),np.array(dataMat[:, 1]), marker='^', s=90)
ax.scatter(np.array(recoMat[:, 0]), np.array(recoMat[:, 1]), marker='o', s=50, c='red')
plt.show()


def replaceNanWithMean():
    datMat = loadDataSet('secom.data', ' ')
    numFeat = np.shape(datMat)[1]
    for i in range(numFeat):
        meanVal = np.mean(datMat[np.nonzero(~np.isnan(datMat[:, i].A))[0], i])
        datMat[np.nonzero(np.isnan(datMat[:, i].A))[0], i] = meanVal
    return datMat


dataMat = replaceNanWithMean()
meanVals = np.mean(dataMat, axis=0)
meanRemoved = dataMat - meanVals  # remove mean
covMat = np.cov(meanRemoved, rowvar=0)
eigVals, eigVects = np.linalg.eig(np.mat(covMat))
eigValInd = np.argsort(eigVals)  # sort, sort goes smallest to largest
eigValInd = eigValInd[::-1]  # reverse
sortedEigVals = eigVals[eigValInd]
total = sum(sortedEigVals)
varPercentage = sortedEigVals / total * 100
# 计算主成分方差
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(range(1, 21), varPercentage[:20], marker='^')
plt.xlabel('Principal Component Number')
plt.ylabel('Percentage of Variance')
plt.show()

结果:
蓝色三角形为原始数据,红色圆为数据的主方向,可以看到PCA算法很好地找到了数据的主方向
20171227201211150

人脸识别:

att_faces中含有40张脸,每张脸10张92*112像素灰度照片的数据集
faces

这里以att_faces数据集为例:

import os
import operator
from numpy import *
import matplotlib.pyplot as plt
import cv2

# define PCA
def pca(data,k):
    data = float32(mat(data))
    rows,cols = data.shape#取大小
    data_mean = mean(data,0)
    data_mean_all = tile(data_mean,(rows,1))
    Z = data - data_mean_all#中心化
    T1 = Z*Z.T #计算样本的协方差
    D,V = linalg.eig(T1) #特征值与特征向量
    V1 = V[:,0:k]#取前k个特征向量
    V1 = Z.T*V1
    for i in range(k): #特征向量归一化
        L = linalg.norm(V1[:,i])
        V1[:,i] = V1[:,i]/L

    data_new = Z*V1 # 降维后的数据
    return data_new,data_mean,V1#训练结果

#covert image to vector
def img2vector(filename):
    img = cv2.imread(filename,0) #读取图片
    rows,cols = img.shape
    imgVector = zeros((1,rows*cols)) #create a none vectore:to raise speed
    imgVector = reshape(img,(1,rows*cols)) #change img from 2D to 1D
    return imgVector

#load dataSet
def loadDataSet(k):  #choose k(0-10) people as traintest for everyone
    ##step 1:Getting data set
    print ("--Getting data set---")
    #note to use '/'  not '\'
    dataSetDir = 'att_faces/orl_faces'
    #读取文件夹
    choose = random.permutation(10)+1 #随机排序1-10 (0-9)+1
    train_face = zeros((40*k,112*92))
    train_face_number = zeros(40*k)
    test_face = zeros((40*(10-k),112*92))
    test_face_number = zeros(40*(10-k))
    for i in range(40): #40 sample people
        people_num = i+1
        for j in range(10): #everyone has 10 different face
            if j < k:
                filename = dataSetDir+'/s'+str(people_num)+'/'+str(choose[j])+'.pgm'
                img = img2vector(filename)
                train_face[i*k+j,:] = img
                train_face_number[i*k+j] = people_num
            else:
                filename = dataSetDir+'/s'+str(people_num)+'/'+str(choose[j])+'.pgm'
                img = img2vector(filename)
                test_face[i*(10-k)+(j-k),:] = img
                test_face_number[i*(10-k)+(j-k)] = people_num

    return train_face,train_face_number,test_face,test_face_number

# calculate the accuracy of the test_face
def facefind():
    # Getting data set
    train_face,train_face_number,test_face,test_face_number = loadDataSet(4)
    # PCA training to train_face
    data_train_new,data_mean,V = pca(train_face,40)
    num_train = data_train_new.shape[0]
    num_test = test_face.shape[0]
    temp_face = test_face - tile(data_mean,(num_test,1))
    data_test_new = temp_face*V #对测试集进行降维
    data_test_new = array(data_test_new) # mat change to array
    data_train_new = array(data_train_new)
    true_num = 0
    for i in range(num_test):
        testFace = data_test_new[i,:]
        diffMat = data_train_new - tile(testFace,(num_train,1))
        sqDiffMat = diffMat**2
        sqDistances = sqDiffMat.sum(axis=1)
        sortedDistIndicies = sqDistances.argsort()
        indexMin = sortedDistIndicies[0]
        if train_face_number[indexMin] == test_face_number[i]:
            true_num += 1

    accuracy = float(true_num)/num_test
    print ('The classify accuracy is: %.2f%%'%(accuracy * 100))

def main():
    facefind()

if __name__=='__main__':
    main()

结果:
_

由于每次选择训练的图片是随机的,随后的准确率也是会变化的,当提高低维空间的维度时能提高准确率
timg

目录
相关文章
|
10月前
|
搜索推荐 数据可视化 数据挖掘
银行员工在线培训考试系统
银行员工在线培训考试系统,依托互联网技术实现碎片化学习与精准考核。支持多维度课程管理、智能组卷、防作弊考试及可视化数据分析,助力银行构建高效、公平、个性化的培训体系,全面提升员工专业能力与合规水平。(238字)
|
2月前
|
人工智能 移动开发 小程序
0 代码也能一键上线应用!阿里云 Meoo 秒悟,一句话生成网站 / 小程序全链路开发工具
阿里云Meoo秒悟是国内首款面向非技术人群的AI闭环开发平台,支持“一句话生成应用”——自动产出前后端、数据库、云资源,并提供可视化编辑与一键部署。覆盖H5、小程序、官网等全终端,运营、学生、个体户皆可零代码快速上线商用应用。
|
9月前
|
存储 NoSQL Go
英伟达谷歌都在用的(开源特征存储平台Feast)-架构学习指南
欢迎来到Feast的世界!这是一个开源的生产级机器学习特征存储系统,专为解决特征数据高效管理与服务而设计。本指南将带你从零掌握其架构、核心概念与实战技巧,助你像架构师一样思考,像工匠一样编码,轻松应对训练与推理的一致性挑战。
1669 2
|
7月前
|
弹性计算 应用服务中间件 云计算
阿里云2026年最新【学生服务器】在哪申请?配置价格说明
阿里云2026年学生福利:完成学生认证,领取300元无门槛代金券,前往学生用券中心抵扣云服务器费用,即可免费获取。还可参与活动中心优惠,享38元/年起轻量服务器,配置丰富,续费同价,助力学生低成本入门云计算。
1430 15
|
11月前
|
机器学习/深度学习 存储 人工智能
AWQ: 面向设备端大语言模型压缩与加速的激活感知权重量化——论文阅读
AWQ是一种面向设备端大语言模型(LLM)压缩与加速的激活感知权重量化方法。与传统基于权重大小的量化策略不同,AWQ通过分析输入激活分布识别关键权重通道,并采用按通道缩放策略,在保持硬件效率的同时显著提升量化精度。实验表明,AWQ在多种LLM上实现了接近无损的低比特量化(如INT4),并在边缘设备上实现高达3倍以上的推理加速,为大模型的设备端部署提供了高效解决方案。
1324 1
|
10月前
|
Arthas 数据可视化 Java
深入理解JVM《火焰图:性能分析的终极可视化利器》
火焰图是Brendan Gregg发明的性能分析利器,将复杂调用栈可视化为“火焰”状图形,直观展示函数耗时与调用关系。通过宽度识别热点函数,结合async-profiler或Arthas工具生成,助力快速定位CPU、内存等性能瓶颈,提升优化效率。
|
人工智能 算法 机器人
开源极客桌面机器人 Desk-Emoji
Desk-Emoji 是一款开源的实体 AI 桌面陪伴机器人,具备酷炫外观、流畅 Emoji 表情、双自由度云台及大模型语音聊天功能,支持手势识别和情绪反馈,适合 DIY 和二次开发,是性价比极高的桌面机器人。
4622 1
开源极客桌面机器人 Desk-Emoji
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp微信小程序的校园二手交易平台系统的详细设计和实现
基于SpringBoot+Vue+uniapp微信小程序的校园二手交易平台系统的详细设计和实现
377 1
|
缓存 负载均衡 监控
dubbo3如何优化
dubbo3如何优化
752 1
|
小程序 JavaScript Java
暹罗外卖开源啦,一款java多商户外卖系统-商家入驻如美团饿了么
暹罗外卖是一款Java外卖配送系统,适用于多商户入驻,对标美团外卖、饿了么。系统包含用户端、商家端、配送端以及总管理后台; 前端使用uni-app开发,可打包部署到微信小程序、APP、H5 Web端使用vue + Element开发 服务端使用java语言开发,技术栈:Spring Cloud & Alibaba + Redis + RocketMQ + WebSocket + ElasticSearch + ELK + Sentinel + Seata + SkyWalking + SpringBoot Admin + Promethues + Grafana
1329 2
暹罗外卖开源啦,一款java多商户外卖系统-商家入驻如美团饿了么

热门文章

最新文章