☀️机器学习入门☀️(四) PCA 和 LDA 降维算法 | 附加小练习(文末送书)

简介: 目录1. PCA 主成分分析1.1 算法简介1.2 实现思路1.3 公式推算1.3.1 PCA顺序排序1.3.2 样本协方差矩阵1.4 小练习2. LDA 线性判断分析2.1 算法简介2.2 实现思路2.3 小练习3. 福利送书最后

目录

1. PCA 主成分分析

1.1 算法简介

1.2 实现思路

1.3 公式推算

1.3.1 PCA顺序排序

1.3.2 样本协方差矩阵

1.4 小练习

2. LDA 线性判断分析

2.1 算法简介

2.2 实现思路

2.3 小练习

3. 福利送书

最后

1. PCA 主成分分析

1.1 算法简介

数据样本虽然是高维的,但是与学习任务紧密相关的或许仅仅是一个低维嵌入,因此可以对数据进行有效的降维。


image.png


主成分分析是一种统计分析、简化数据集的方法。


它利用正交变换来对一系列可能相关的变量的观测值进行线性变换,从而投影为一系列线性不相关变量的值,这些不相关变量称为主成分。


1.2 实现思路

一般来说,欲获得低维子空间,最简单的是对原始高维空间进行线性变换。


给定𝒎维空间中的数据点,将其投影到低维空间中,同时尽可能多地保留信息。


数据在低维线性空间的正交投影

最大化投影数据的方差(紫色线)。 最小化数据点与投影之间的均方距离(蓝色线之和)。


image.png


主成分概念:


主成分分析(PCA)的思想是将𝒎维特征映射到𝒌维上(𝒌<𝒎),这𝒌维是全新的正交特征。

这𝒌维特征称为主成分(PC),是重新构造出来的𝒌维特征。

主成分特点:


源于质心的矢量。

主成分#1指向最大方差的方向。

各后续主成分与前一主成分正交,且指向残差子空间最大方差的方向

1.3 公式推算

1.3.1 PCA顺序排序

给定中心化的数据{𝒙_𝟏,𝒙_𝟐,⋯,𝒙_𝒎},计算主向量:

image.png

我们最大化𝒙的投影方差

image.png


我们使残差子空间中投影的方差最大

image.png


1.3.2 样本协方差矩阵

给定数据{𝒙_𝟏,𝒙_𝟐,⋯,𝒙_𝒎}, 计算协方差矩阵


image.png


证明不写了,太多公式了,自行百度吧。


1.4 小练习

给定的图像数据集,探讨pca降维后特征个数与聚类性能的关系。

image.png

from PIL import Image
import numpy as np
import os
from ex1.clustering_performance import clusteringMetrics
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
def getImage(path):
    images = []
    for root, dirs, files in os.walk(path):
        if len(dirs) == 0:
            images.append([root + "\\" + x for x in files])
    return images
# 加载图片
images_files = getImage('face_images')
y = []
all_imgs = []
for i in range(len(images_files)):
    y.append(i)
    imgs = []
    for j in range(len(images_files[i])):
        img = np.array(Image.open(images_files[i][j]).convert("L"))  # 灰度
        # img = np.array(Image.open(images_files[i][j])) #RGB
        imgs.append(img)
    all_imgs.append(imgs)
# 可视化图片
w, h = 180, 200
pic_all = np.zeros((h * 10, w * 10))  # gray
for i in range(10):
    for j in range(10):
        pic_all[i * h:(i + 1) * h, j * w:(j + 1) * w] = all_imgs[i][j]
pic_all = np.uint8(pic_all)
pic_all = Image.fromarray(pic_all)
pic_all.show()
# 构造输入X
label = []
X = []
for i in range(len(all_imgs)):
    for j in all_imgs[i]:
        label.append(i)
        # temp = j.reshape(h * w, 3) #RGB
        temp = j.reshape(h * w)  # GRAY
        X.append(temp)
def keams_in(X_Data, k):
    kMeans1 = KMeans(k)
    y_p = kMeans1.fit_predict(X_Data)
    ACC, NMI, ARI = clusteringMetrics(label, y_p)
    t = "ACC:{},NMI:{:.4f},ARI:{:.4f}".format(ACC, NMI, ARI)
    print(t)
    return ACC, NMI, ARI
# PCA
def pca(X_Data, n_component, height, weight):
    X_Data = np.array(X_Data)
    pca1 = PCA(n_component)
    pca1.fit(X_Data)
    faces = pca1.components_
    faces = faces.reshape(n_component, height, weight)
    X_t = pca1.transform(X_Data)
    return faces, X_t
def draw(n_component, faces):
    plt.figure(figsize=(10, 4))
    plt.subplots_adjust(hspace=0, wspace=0)
    for i in range(n_component):
        plt.subplot(2, 5, i + 1)
        plt.imshow(faces[i], cmap='gray')
        plt.title(i + 1)
        plt.xticks(())
        plt.yticks(())
    plt.show()
score = []
for i in range(10):
    _, X_trans = pca(X, i + 1, h, w)
    acc, nmi, ari = keams_in(X_trans, 10)
    score.append([acc, nmi, ari])
score = np.array(score)
bar_width = 0.25
x = np.arange(1, 11)
plt.bar(x, score[:, 0], bar_width, align="center", color="orange", label="ACC", alpha=0.5)
plt.bar(x + bar_width, score[:, 1], bar_width, color="blue", align="center", label="NMI", alpha=0.5)
plt.bar(x + bar_width*2, score[:, 2], bar_width, color="red", align="center", label="ARI", alpha=0.5)
plt.xlabel("n_component")
plt.ylabel("精度")
plt.legend()
plt.show()

2. LDA 线性判断分析

2.1 算法简介

当我们映射的时候,由于映射的位置不同,所以我们会有不同的降维后的结果。对于下面两个,我们可以看出方法2的分类更明显,方法2是更好的。

image.png

和PCA的映射对比。

image.png


2.2 实现思路

投影后类内方差最小,类间方差最大


就像是上面的那个三维映射例子一样,我们可以看到,方法2之所以更好,就是因为类内方差最小,类间方差最大。


数据映射到Rk(从d维降到k维),且希望该变换将属于同一类的样本映射得越近越好(即最小的类内距离),而将不同类的样本映射得越远越好 (即最大的类间距离)。同时还能尽能多地保留样本数据的判别信息。


image.png


记𝒁_𝒊={𝑻(𝒙)|𝒙∊𝑿_𝒊},从而根据线性判别分析的基本思想,我们希望:


(𝒛_𝟏 ) ̅和(𝒛_2 ) ̅离的越远越好


类间离散度

image.png

𝒁_𝒊 中的元素集中在(𝒛_𝒊 ) ̅附近越好


类内离散度

image.png

image.png


输入:训练样本〖{𝒙_𝒊,𝒚_𝒊}〗_(𝒊=𝟏)^𝒏,降维后的维数(特征个数)k.


输出:𝑿=[𝒙_𝟏, …,𝒙_𝒏 ]的低维度表示𝒁=[𝐳_𝟏, …,𝐳_𝒏 ].


步骤

1.计算类内散度矩阵 Sw;

2.计算类间散度矩阵 Sb;

3.计算矩阵S的负一次方wSb;

4.计算S的负一次方wSb的最大的k个特征值和对应的k个特征向量(w1, w2, …, wk),得到投影矩阵W

5.对样本集中的每一个样本特征xi转化为新的样本zi=WTxi

6.得到输出样本集〖{𝒛_𝒊,𝒚_𝒊}〗_(𝒊=𝟏)^𝒏.


2.3 小练习

给定的图像数据集,探讨LDA的降维效果

image.png

from sklearn import datasets#引入数据集
from sklearn.neighbors import KNeighborsClassifier #KNN
from sklearn.decomposition import PCA
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.model_selection import train_test_split
import numpy as np
import matplotlib.pyplot as plt #plt用于显示图片
from matplotlib import offsetbox
def calLDA(k):
    # LDA
    lda = LinearDiscriminantAnalysis(n_components=k).fit(data,label) # n_components设置降维到n维度
    dataLDA = lda.transform(data)  # 将规则应用于训练集
    return dataLDA
def calPCA(k):
    # PCA
    pca = PCA(n_components=k).fit(data)
    # 返回测试集和训练集降维后的数据集
    dataPCA = pca.transform(data)
    return dataPCA
def draw():
    # matplotlib画图中中文显示会有问题,需要这两行设置默认字体
    fig = plt.figure('example', figsize=(11, 6))
    # plt.xlabel('X')
    # plt.ylabel('Y')
    # plt.xlim(xmax=9, xmin=-9)
    # plt.ylim(ymax=9, ymin=-9)
    color = ["red","yellow","blue","green","black","purple","pink","brown","gray","Orange"]
    colors = []
    for target in label:
        colors.append(color[target])
    plt.subplot(121)
    plt.title("LDA 降维可视化")
    plt.scatter(dataLDA.T[0], dataLDA.T[1], s=10,c=colors)
    plt.subplot(122)
    plt.title("PCA 降维可视化")
    plt.scatter(dataPCA.T[0], dataPCA.T[1], s=10, c=colors)
    #plt.legend()
    plt.show()
def plot_embedding(X,title=None):
    x_min, x_max = np.min(X, 0), np.max(X, 0)
    X = (X - x_min) / (x_max - x_min)  # 对每一个维度进行0-1归一化,注意此时X只有两个维度
    colors = ['#5dbe80', '#2d9ed8', '#a290c4', '#efab40', '#eb4e4f', '#929591','#ababab','#eeeeee','#aaaaaa','#213832']
    ax = plt.subplot()
    # 画出样本点
    for i in range(X.shape[0]):  # 每一行代表一个样本
        plt.text(X[i, 0], X[i, 1], str(label[i]),
                 # color=plt.cm.Set1(y[i] / 10.),
                 color=colors[label[i]],
                 fontdict={'weight': 'bold', 'size': 9})  # 在样本点所在位置画出样本点的数字标签
    # 在样本点上画出缩略图,并保证缩略图够稀疏不至于相互覆盖
    if hasattr(offsetbox, 'AnnotationBbox'):
        shown_images = np.array([[1., 1.]])  # 假设最开始出现的缩略图在(1,1)位置上
        for i in range(data.shape[0]):
            dist = np.sum((X[i] - shown_images) ** 2, 1)  # 算出样本点与所有展示过的图片(shown_images)的距离
            if np.min(dist) < 4e-3:  # 若最小的距离小于4e-3,即存在有两个样本点靠的很近的情况,则通过continue跳过展示该数字图片缩略图
                continue
            shown_images = np.r_[shown_images, [X[i]]]  # 展示缩略图的样本点通过纵向拼接加入到shown_images矩阵中
            imagebox = offsetbox.AnnotationBbox(
                offsetbox.OffsetImage(datasets.load_digits().images[i], cmap=plt.cm.gray_r),
                X[i])
            ax.add_artist(imagebox)
    #plt.xticks([]), plt.yticks([])  # 不显示横纵坐标刻度
    if title is not None:
        plt.title(title)
    plt.show()
data = datasets.load_digits().data#一个数64维,1797个数
label = datasets.load_digits().target
dataLDA = calLDA(2)
dataPCA = calPCA(2)
#draw() #普通图
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plot_embedding(dataLDA,"LDA 降维可视化")
plot_embedding(dataPCA,"PCA 降维可视化")

3. 福利送书

点赞、评论即可在参与评论区的抽奖活动,抽一位小伙伴送书~


零基础也能快速入门。本书从最基础的高等数学基础讲起,由浅入深,层层递进,在巩固固有知识的同时深入讲解人工智能的算法原理,无论读者是否从事计算机相关行业,是否接触过人工智能,都能通过本书实现快速入门。

全新视角介绍数学知识。采用计算机程序模拟数学推论的介绍方法,使数学知识更为清晰易懂,更容易让初学者深入理解数学定理、公式的意义,从而激发起读者的学习兴趣。

理论和实践相结合。每章最后提供根据所在章的理论知识点精心设计的“综合性实例”,读者可以通过综合案例进行实践操作,为以后的算法学习奠定基础。

大量范例源码+习题答案,为学习排忧解难。本书所有示例都有清晰完整的源码,每章之后设有习题并配套题目答案,讲解清晰,解决读者在学习中的所有困惑。

image.png


【作者简介】


唐宇迪,计算机专业博士,网易云课堂人工智能认证行家,51CTO学院讲师,CSDN博客专家。

李琳,河南工业大学副教授,在软件工程、机器学习、人工智能和模式识别等领域有深入研究。

侯惠芳,教授,解放军信息工程大学通信与信息系统专业博士,擅长机器学习、大数据检索、人工智能和模式识别等。

王社伟,河南工业大学副教授,西北工业大学航空宇航制造专业博士,挪威科技大学访问学者,对数字化制造、企业管理系统、机器学习、数据挖掘等有丰富的实战经验。


相关文章
|
1天前
|
机器学习/深度学习 存储 人工智能
文本情感识别分析系统Python+SVM分类算法+机器学习人工智能+计算机毕业设计
使用Python作为开发语言,基于文本数据集(一个积极的xls文本格式和一个消极的xls文本格式文件),使用Word2vec对文本进行处理。通过支持向量机SVM算法训练情绪分类模型。实现对文本消极情感和文本积极情感的识别。并基于Django框架开发网页平台实现对用户的可视化操作和数据存储。
11 0
文本情感识别分析系统Python+SVM分类算法+机器学习人工智能+计算机毕业设计
|
8天前
|
机器学习/深度学习 人工智能 算法
探索AI的奥秘:机器学习入门之旅
【8月更文挑战第43天】本文将带领读者开启一段奇妙的学习之旅,探索人工智能背后的神秘世界。我们将通过简单易懂的语言和生动的例子,了解机器学习的基本概念、算法和应用。无论你是初学者还是有一定基础的学习者,都能从中获得启发和收获。让我们一起踏上这段激动人心的学习之旅吧!
|
15天前
|
机器学习/深度学习 数据采集 算法
数据挖掘和机器学习算法
数据挖掘和机器学习算法
|
18天前
|
机器学习/深度学习 数据采集 存储
一文读懂蒙特卡洛算法:从概率模拟到机器学习模型优化的全方位解析
蒙特卡洛方法起源于1945年科学家斯坦尼斯劳·乌拉姆对纸牌游戏中概率问题的思考,与约翰·冯·诺依曼共同奠定了该方法的理论基础。该方法通过模拟大量随机场景来近似复杂问题的解,因命名灵感源自蒙特卡洛赌场。如今,蒙特卡洛方法广泛应用于机器学习领域,尤其在超参数调优、贝叶斯滤波等方面表现出色。通过随机采样超参数空间,蒙特卡洛方法能够高效地找到优质组合,适用于处理高维度、非线性问题。本文通过实例展示了蒙特卡洛方法在估算圆周率π和优化机器学习模型中的应用,并对比了其与网格搜索方法的性能。
117 1
|
19天前
|
机器学习/深度学习 算法 数据挖掘
|
11天前
|
机器学习/深度学习 人工智能 TensorFlow
神经网络入门到精通:Python带你搭建AI思维,解锁机器学习的无限可能
【9月更文挑战第10天】神经网络是开启人工智能大门的钥匙,不仅是一种技术,更是模仿人脑思考的奇迹。本文从基础概念入手,通过Python和TensorFlow搭建手写数字识别的神经网络,逐步解析数据加载、模型定义、训练及评估的全过程。随着学习深入,我们将探索深度神经网络、卷积神经网络等高级话题,并掌握优化模型性能的方法。通过不断实践,你将能构建自己的AI系统,解锁机器学习的无限潜能。
12 0
|
20天前
|
机器学习/深度学习 人工智能 算法
探索AI的奥秘:机器学习入门之旅
【8月更文挑战第31天】本文将带领读者开启一段奇妙的学习之旅,探索人工智能背后的神秘世界。我们将通过简单易懂的语言和生动的例子,了解机器学习的基本概念、算法和应用。无论你是初学者还是有一定基础的学习者,都能从中获得启发和收获。让我们一起踏上这段激动人心的学习之旅吧!
|
20天前
|
Java 前端开发 Apache
Apache Wicket与Spring MVC等Java Web框架大PK,究竟谁才是你的最佳拍档?点击揭秘!
【8月更文挑战第31天】在Java Web开发领域,众多框架各具特色。Apache Wicket以组件化开发和易用性脱颖而出,提高了代码的可维护性和可读性。相比之下,Spring MVC拥有强大的生态系统,但学习曲线较陡;JSF与Java EE紧密集成,但在性能和灵活性上略逊一筹;Struts2虽成熟,但在RESTful API支持上不足。选择框架时还需考虑社区支持和文档完善程度。希望本文能帮助开发者找到最适合自己的框架。
27 0
|
20天前
|
机器学习/深度学习 自然语言处理 TensorFlow
TensorFlow 入门超简单!从零开始构建你的第一个神经网络,开启机器学习精彩之旅!
【8月更文挑战第31天】本文介绍了流行开源机器学习框架 TensorFlow,涵盖其安装与首个神经网络构建步骤。TensorFlow 由 Google 开发,适用于计算机视觉及自然语言处理等领域。掌握它不仅提升就业机会,还加深对机器学习的理解。通过安装 Python 并使用 pip 命令安装 TensorFlow,即可按照示例构建、训练并评估简单的线性回归模型,快速开启机器学习之旅。
21 0
|
22天前
|
机器学习/深度学习 存储 算法
图解最常用的 10 个机器学习算法!
图解最常用的 10 个机器学习算法!