机器学习系列(14)_PCA对图像数据集的降维_03

简介: 降维的目的之一是希望抛弃对模型带来负面影响的特征,同时,带有效信息的特征的方差应该是远大于噪音的,所以相比噪音,有效的特征所带来的信息不会在PCA当中大量抛弃。

一、噪音过滤



降维的目的之一是希望抛弃对模型带来负面影响的特征,同时,带有效信息的特征的方差应该是远大于噪音的,所以相比噪音,有效的特征所带来的信息不会在PCA当中大量抛弃。inverse_transform能够在不恢复原始数据的情况下,将降维后的数据返回到原本的高维空间。(即能够实现:“保证维度,但是去除方差很小的特征所带来的信息”)。我们可以利用·inverse_transform来实现噪音的过滤。


寻找确定关键特征是降噪的前提,只保留关键特征,其他都可以看做是噪音。


重要参数:n_components,svd_solver,random_state


三个重要属性:components_,explained_variance_以及explained_variance_ratio_


接口:fit,transform,fit_transform以及inverse_transform


1、案例:手写图像识别加噪与降噪


# 1. 导入所需要的库和模块
from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import numpy as np
# 2. 导入数据,探索数据
digits = load_digits()
digits.data.shape
69b61dcce945458da24c5c8156dea25b.png
set(digits.target.tolist())

c70ea378dd514c35a9e38089df5ed74b.png

# 3. 定义画图函数
def plot_digits(data):  
    fig, axes = plt.subplots(4,10,figsize=(10,4)
                            ,subplot_kw = {"xticks":[],"yticks":[]}
                            )
    for i, ax in enumerate(axes.flat):
        ax.imshow(data[i].reshape(8,8),cmap="binary")
plot_digits(digits.data)

53534b80412f4a65a70127fcc0cb831c.png

# 4. 为数据加上噪音
np.random.RandomState(42)
noisy = np.random.normal(digits.data,2) 
plot_digits(noisy)

为手写数据加上噪音之后的图片:

d5306d72843740df9d145f47226a16a4.png

# 5. PCA降维
pca = PCA(0.5).fit(noisy)    #改变参数
X_dr = pca.transform(noisy)
X_dr.shape

d00b01b093644badb414cc743aaae521.png

# 6. 逆转降维结果,实现降噪
without_noise = pca.inverse_transform(X_dr)
plot_digits(without_noise)
plt.show()


使用inverse_transform降噪后:

1f57c90895884963b581f371610b3a0d.png


原来没有噪声的时候的维度:

without_noise.shape



2、案例:手写图像识别寻找最佳维度


# 1. 导入需要的模块和库
from sklearn.decomposition import PCA
from sklearn.ensemble import RandomForestClassifier as RFC
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# 2. 导入数据,探索数据
data = pd.read_csv(r"digit recognizor.csv")
X = data.iloc[:,1:]
y = data.iloc[:,0]
X.shape

0d29bc21ee044288b88a2ef08f71200a.png

# 3. 画累计方差贡献率曲线,找最佳降维后维度的范围
pca_line = PCA().fit(X)    #PCA,不填n_components,使用X.shape中的最小值
plt.figure(figsize=[20,5])
plt.plot(np.cumsum(pca_line.explained_variance_ratio_))
plt.xlabel("number of components after dimension reduction")  #降维后的特征书目
plt.ylabel("cumulative explained variance ratio")  #累计可解释性方差累计曲线
plt.show()  #0-200之间

68e4f596df1e4acbbfd6ab795b49ec46.png


# 4. 降维后维度的学习曲线,继续缩小最佳维度的范围
score = []
for i in range(1,101,10): #取得0-100,用随机森林来跑
    X_dr = PCA(i).fit_transform(X)
    once = cross_val_score(RFC(n_estimators=10,random_state=0)  #默认为10,保持稳定。
                            ,X_dr,y,cv=5).mean()  #5次交叉验证的值,取平均值
    score.append(once)
plt.figure(figsize=[20,5])
plt.plot(range(1,101,10),score)
plt.show()

682519d1cf51437081036bec5fb1c0cf.png


# 5. 细化学习曲线,找出降维后的最佳维度
score = []
for i in range(10,25):  #再截取
    X_dr = PCA(i).fit_transform(X)
    once = cross_val_score(RFC(n_estimators=10,random_state=0),X_dr,y,cv=5).mean()
    score.append(once)
plt.figure(figsize=[20,5])
plt.plot(range(10,25),score)
plt.show()
# 6. 导入找出的最佳维度进行降维,查看模型效果
X_dr = PCA(21).fit_transform(X)  #取23、21
cross_val_score(RFC(n_estimators=100,random_state=0),X_dr,y,cv=5).mean()

164145311b9244e1b31ac32391016169.png


# 7. 更换模型
from sklearn.neighbors import KNeighborsClassifier as KNN
cross_val_score(KNN(),X_dr,y,cv=5).mean()

49cdb8a04a694792ae71f12d9bf6bfaa.png

# 8. KNN的k值学习曲线
score = []
for i in range(10):
    X_dr = PCA(23).fit_transform(X)
    once = cross_val_score(KNN(i+1),X_dr,y,cv=5).mean()
    score.append(once)
plt.figure(figsize=[20,5])
plt.plot(range(10),score)
plt.show()

45859debb4b9442cb3a36e1c129d5fd3.png

# 9. 定下超参数后,模型效果如何,模型运行时间如何?
cross_val_score(KNN(4),X_dr,y,cv=5).mean()

4221c5a2135641fe974a911bad47e49d.png


3、模拟PCA过程


##自适应求K值
import numpy as np
import cv2 as cv
# 数据中心化
def Z_centered(dataMat):
    rows, cols = dataMat.shape
    meanVal = np.mean(dataMat, axis=0)  # 按列求均值,即求各个特征的均值
    meanVal = np.tile(meanVal, (rows, 1))
    newdata = dataMat - meanVal
    return newdata, meanVal
# 最小化降维造成的损失,确定k
def Percentage2n(eigVals, percentage):
    sortArray = np.sort(eigVals)  # 升序
    sortArray = sortArray[-1::-1]  # 逆转,即降序
    arraySum = sum(sortArray)
    tmpSum = 0
    num = 0
    for i in sortArray:
        tmpSum += i
        num += 1
        if tmpSum >= arraySum * percentage:
            return num
# 得到最大的k个特征值和特征向量
def EigDV(covMat, p):
    D, V = np.linalg.eig(covMat)  # 得到特征值和特征向量
    k = Percentage2n(D, p)  # 确定k值
    print("保留99%信息,降维后的特征个数:" + str(k) + "\n")
    eigenvalue = np.argsort(D)
    K_eigenValue = eigenvalue[-1:-(k + 1):-1]
    K_eigenVector = V[:, K_eigenValue]
    return K_eigenValue, K_eigenVector
# 得到降维后的数据
def getlowDataMat(DataMat, K_eigenVector):
    return DataMat * K_eigenVector
# 重构数据
def Reconstruction(lowDataMat, K_eigenVector, meanVal):
    reconDataMat = lowDataMat * K_eigenVector.T + meanVal
    return reconDataMat
# PCA算法
def PCA(data, p):
    dataMat = np.float32(np.mat(data))
    # 数据中心化
    dataMat, meanVal = Z_centered(dataMat)
    # 计算协方差矩阵
    # covMat = Cov(dataMat)
    covMat = np.cov(dataMat, rowvar=0)
    # 得到最大的k个特征值和特征向量
    D, V = EigDV(covMat, p)
    # 得到降维后的数据
    lowDataMat = getlowDataMat(dataMat, V)
    # 重构数据
    reconDataMat = Reconstruction(lowDataMat, V, meanVal)
    return reconDataMat
def main():
    imagePath = '96014.jpg'
    image = cv.imread(imagePath)
    image = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    rows, cols = image.shape
    print("降维前的特征个数:" + str(cols) + "\n")
    print(image)
    print('----------------------------------------')
    reconImage = PCA(image, 0.6) # 通过改变保留信息的程度来看这个图片的特征值 
    reconImage = reconImage.astype(np.uint8)
    print(reconImage)
    cv.imshow('test', reconImage)
    cv.waitKey(0)
    cv.destroyAllWindows()
if __name__ == '__main__':
    main()


4、模拟SVD过程


def svd(img, topk_percent=0.1):
    """
    使用svd对图片降维,可作为一种数据增强手段
    每列作为一个向量,先构建方阵,再求特征值 特征向量,取前N个主成分,再重构图像
    :param img: 输入图像
    :param topk_percent: 图像恢复率,
    :return: img after svd
    """
    img_src = img[...]  #img要三维的?
    if len(img.shape) == 3:
        img_src = cv2.cvtColor(img_src, cv2.COLOR_BGR2GRAY)
    h, w = img_src.shape
    data = np.asarray(img_src, np.double)
    # 以下两种方式都可以
    # method 1
    U, s, V = np.linalg.svd(data)
    K = round(len(s) * topk_percent)
    S = np.diag(s)
    major_data = np.dot(U[:, :K], np.dot(S[:K, :K], V[:K, :]))
    # # method 2
    # feat_values, feat_vectors = np.linalg.eig(np.dot(data.T, data))
    # feat_index = np.argsort(np.sqrt(feat_values), axis=0)[::-1]
    # S = np.diag(feat_values)
    # V = feat_vectors[:, feat_index]
    # S_inv = np.asmatrix(S).I
    # V_inv = np.asmatrix(V).I
    # U = np.dot(np.dot(data, V), S_inv)
    # K = round(S.shape[0] * topk_percent)
    # major_data = np.dot(np.dot(U[:, :K], S[:K, :K]), V_inv[:K, :])
    rebuild_img = np.asarray(major_data, np.uint8)
    cv2.imshow('1', rebuild_img)
    cv2.waitKey(0)
    return rebuild_img
def pca(img, topk_percent=0.1):
    """
    使用pca对图片降维,可作为一种数据增强手段
    每列作为一个向量,先0均值化,再求协方差矩阵的特征值和特征向量,取前N个主成分,再重构图像
    :param img: 输入图像
    :param topk_percent: 图像恢复率,
    :return: img after pca
    """
    img_src = img[...]
    if len(img.shape) == 3:
        img_src = cv2.cvtColor(img_src, cv2.COLOR_BGR2GRAY)
    print(img_src.shape)
    h, w = img_src.shape
    data = np.asarray(img_src, np.double)
    # 计算每列的mean
    _mean = np.mean(data, axis=0)
    data -= _mean
    # 以 列为变量计算方式,计算协方差矩阵
    data_cov = np.cov(data, rowvar=False)
    feat_values, feat_vectors = np.linalg.eig(data_cov)
    feat_index = np.argsort(np.sqrt(feat_values), axis=0)[::-1]
    V = feat_vectors[:, feat_index]
    K = round(len(feat_values) * topk_percent)# 重建图像
    major_data = np.dot(np.dot(data, V[:, :K]), V[:, :K].T) + _mean
    rebuild_img = np.asarray(major_data, np.uint8)
    cv2.imshow('0', rebuild_img) #参数错误1应该为0
    cv2.waitKey(0)
    return rebuild_img


相关文章
|
6月前
|
机器学习/深度学习 算法 数据可视化
机器学习第11天:降维
机器学习第11天:降维
|
6月前
|
机器学习/深度学习 算法 数据可视化
JAMA | 机器学习中的可解释性:SHAP分析图像复刻与解读
JAMA | 机器学习中的可解释性:SHAP分析图像复刻与解读
1449 1
|
6月前
|
人工智能 编解码 算法
使用 PAI-DSW x Free Prompt Editing图像编辑算法,开发个人AIGC绘图小助理
在本教程中,您将学习在阿里云交互式建模平台PAI-DSW x Free Prompt Editing图像编辑算法,开发个人AIGC绘图小助理,实现文本驱动的图像编辑功能单卡即可完成AIGC图片风格变化、背景变化和主体变化等功能。让我们一同开启这场旅程,为您的图像编辑添上无限可能性的翅膀吧。
使用 PAI-DSW x Free Prompt Editing图像编辑算法,开发个人AIGC绘图小助理
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
【MM2024】阿里云 PAI 团队图像编辑算法论文入选 MM2024
阿里云人工智能平台 PAI 团队发表的图像编辑算法论文在 MM2024 上正式亮相发表。ACM MM(ACM国际多媒体会议)是国际多媒体领域的顶级会议,旨在为研究人员、工程师和行业专家提供一个交流平台,以展示在多媒体领域的最新研究成果、技术进展和应用案例。其主题涵盖了图像处理、视频分析、音频处理、社交媒体和多媒体系统等广泛领域。此次入选标志着阿里云人工智能平台 PAI 在图像编辑算法方面的研究获得了学术界的充分认可。
【MM2024】阿里云 PAI 团队图像编辑算法论文入选 MM2024
|
4月前
|
机器学习/深度学习 人工智能 自然语言处理
|
5月前
|
机器学习/深度学习 人工智能 自然语言处理
【CVPR2024】阿里云人工智能平台PAI图像编辑算法论文入选CVPR2024
近期,阿里云人工智能平台PAI发表的图像编辑算法论文在CVPR-2024上正式亮相发表。论文成果是阿里云与华南理工大学贾奎教授领衔的团队共同研发。此次入选标志着阿里云人工智能平台PAI自主研发的图像编辑算法达到了先进水平,赢得了国际学术界的认可。在阿里云人工智能平台PAI算法团队和华南理工大学的老师学生们一同的坚持和热情下,将阿里云在图像生成与编辑领域的先进理念得以通过学术论文和会议的形式,向业界传递和展现。
|
5月前
|
机器学习/深度学习 API Python
机器学习特征降维
这篇内容概述了特征降维在机器学习中的重要性,包括三个主要方法:低方差过滤法、PCA(主成分分析)和相关系数法。低方差过滤法通过删除方差低于阈值的特征来减少无关信息;PCA通过正交变换降低数据的维数,保留大部分信息;相关系数法(如皮尔逊和斯皮尔曼相关系数)用于评估特征间的相关性,去除高度相关的特征以简化模型。这些技术有助于提高模型效率和泛化能力。
|
5月前
|
机器学习/深度学习 计算机视觉
【机器学习】LoFTR:革命性图像特征批评技术等领跑者
【机器学习】LoFTR:革命性图像特征批评技术等领跑者
80 1
|
5月前
|
机器学习/深度学习 算法
【机器学习】剪贴画图像等文本引导运动生成技术革新
【机器学习】剪贴画图像等文本引导运动生成技术革新
49 1
|
5月前
|
机器学习/深度学习 自然语言处理 计算机视觉
【机器学习】HQ-Edit引领图像编辑新潮流
【机器学习】HQ-Edit引领图像编辑新潮流
56 1