使用python实现LDA线性判别分析

这篇具有很好参考价值的文章主要介绍了使用python实现LDA线性判别分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

实验原理

LDA(Linear Discriminant Analysis)线性判别分析是一种监督学习的线性分类算法,它可以将一个样本映射到一条直线上,从而实现对样本的分类。LDA的目标是找到一个投影轴,使得经过投影后的两类样本之间的距离最大,而同一类样本之间的距离最小。

LDA的过程可以分为以下几步:

1.计算每个类别的均值向量。

2.计算类内散度矩阵(Within-class scatter matrix)。类内散度矩阵是各类别中所有样本与各自均值向量之差的协方差矩阵之和。
python lda,机器学习,python,机器学习,深度学习

3.计算类间散度矩阵(Between-class scatter matrix)。类间散度矩阵是各类别均值向量之差的协方差矩阵。
python lda,机器学习,python,机器学习,深度学习

4.通过对类内散度矩阵进行奇异值分解,得到类内散度矩阵的逆矩阵。

5.计算投影向量w。通过将类间散度矩阵与类内散度矩阵的逆矩阵相乘,得到投影向量w,使得样本经过投影后不同类别之间的距离最大。
python lda,机器学习,python,机器学习,深度学习

6.通过计算样本与投影向量w的点积,将样本映射到一条直线上。

7.根据映射后的样本值进行分类。

实验目的

本实验旨在使用线性判别分析(LDA)来对数据集进行分类,通过划分训练集和测试集,训练模型并得出模型的投影方向,进而计算测试集的准确率acc。同时,希望能够通过可视化方式展示数据的分析结果,从而更好地理解数据集的特征和模型分类的结果。

实验内容

  1. 划分数据集

    index = random.sample(range(748), 748)
    train = df.iloc[index[:600], :]
    train = np.array(train)
    test = df.iloc[index[600:], :]
    test = np.array(test)
    
    • random.sample(range(748), 748):生成一个长度为748的随机数列,其中包含了0~747之间的所有整数,且每个整数在数列中仅出现一次。
    • train = df.iloc[index[:600], :]:从数据集df中,根据前600个随机数的下标,选出对应的行作为训练集train。
    • train = np.array(train):将训练集转换成numpy数组类型。
    • test = df.iloc[index[600:], :]:从数据集df中,根据从第601个随机数开始到最后一个随机数的下标,选出对应的行作为测试集test。
    • test = np.array(test):将测试集转换成numpy数组类型。
  2. 定义计算类内散度矩阵

    def cov(self, X, Y=None):
            # X = (X - np.mean(X, axis=0)) / np.std(X, axis=0)
            X = X - np.mean(X, axis=0)
            return np.dot(X.T, X)
    
  3. 计算w

    def fit(self, X):
            x0 = X[X[:, -1] == 0]
            x0 = x0[:, :-1]
            x1 = X[X[:, -1] == 1]
            x1 = x1[:, :-1]
            sigma0 = self.cov(x0)
            sigma1 = self.cov(x1)
            Sw = sigma1 + sigma0
            # 求均值差
            u0, u1 = np.mean(x0, axis=0), np.mean(x1, axis=0)
            mean_diff = u0 - u1
            # 奇异值分解的方法
            # 对类内散度矩阵进行奇异值分解
            U, S, V = np.linalg.svd(Sw)
            # # # # 计算类内散度矩阵的逆
            Sw_ = np.dot(np.dot(V.T, np.linalg.pinv(np.diag(S))), U.T)
            # # # # 计算w
            self.w = Sw_.dot(mean_diff)
    

    在代码中,首先根据标签将数据集分为两类,然后计算每个类别的协方差矩阵sigma0和sigma1,将它们相加得到总的类内散度矩阵Sw。接着计算两个类别的均值差mean_diff。为了得到最优的投影方向w,需要计算Sw的逆矩阵,然后将其乘以mean_diff得到w。这里使用了奇异值分解的方法计算Sw的逆矩阵。最终,训练得到的模型中包含了投影方向w,可以用于将新的数据点映射到低维空间中进行分类。

  4. 得到投影

    def getY(self, X):
            res = []
            for i in range(X.shape[0]):
                item = X[i, :].dot(self.w.T)
                res.append(item)
            return res
    
    • 函数名为 getY,接受一个参数 X,表示要对其进行预测的数据集,类型为 Numpy 数组。
    • 在函数内部,首先创建一个空列表 res,用于保存预测结果。
    • 然后,通过一个 for 循环遍历数据集 X 的每一行。
    • 对于每一行,调用训练好的模型的权重向量 self.w,计算其与该行数据的点积(即内积),得到一个标量值,表示该行数据的投影结果。将该值添加到 res 列表中。
    • 最后,函数返回 res 列表,其中保存了对每个数据样本的预测结果。
  5. 预测

    def predict(self, x):
            res = []
            # x = (x - np.mean(x, axis=0)) / np.std(x, axis=0)
            for i in range(x.shape[0]):
                item = x[i, :].dot(self.w.T)
                res.append(int(1 * (item < 0)))
            return res
    

    对于每个输入的样本x,通过将其投影到已学习的线性判别函数(通过线性判别分析得到的投影方向w)上,得到其在这个方向上的分量。如果分量小于0,就认为其属于类别0,否则属于类别1。这里将bool类型的结果通过int()函数转换成0或1来表示所属的类别。最终返回一个预测类别的列表。

  6. 选取最优参数应用于测试集

    for i in range(100):
            # 划分训练集和测试集
            index = random.sample(range(748), 748)
            train = df.iloc[index[:600], :]
            train = np.array(train)
            test = df.iloc[index[600:], :]
            test = np.array(test)
            # 拟合训练
            lda = LDA()
            try:
                lda.fit(train)
            except:
                print("无法求逆")
                continue
            # 测试集测试
            predata = lda.predict(test[:, :-1])
            acc = (test[predata == test[:, -1]]).shape[0] / test.shape[0]
            # print(acc)
            res.append(acc)
            wlist.append(lda.w)
        print("最佳准确率:", max(res), '\t', "最低准确率:", min(res), '\t', "平均准确率:", np.mean(res))
        print(res.index(max(res)))
        lda2 = LDA()
        lda2.w = wlist[res.index(max(res))]
        index = random.sample(range(748), 748)
        test = df.iloc[index[600:], :]
        test = np.array(test)
        res = lda2.getY(test[:, :-1])
        predata = lda.predict(test[:, :-1])
        acc = (test[predata == test[:, -1]]).shape[0] / test.shape[0]
        print("测试集准确率为:", acc)
    
    1. 对数据集进行100次随机划分,每次划分将前600个样本作为训练集,后148个样本作为测试集;
    2. 对每次划分后的训练集进行线性判别分析拟合;
    3. 使用拟合的模型对测试集进行预测,并计算测试集准确率;
    4. 记录每次测试的准确率和投影方向 w;
    5. 打印最佳准确率、最低准确率、平均准确率,并输出最佳准确率对应的投影方向;
    6. 选取最佳准确率对应的投影方向,使用该模型对另一个随机划分的测试集进行预测,并计算准确率。

python lda,机器学习,python,机器学习,深度学习

  1. 将结果可视化

    low0 = [i for i in res if i < 0]
        up0 = [i for i in res if i > 0]
        plt.scatter(low0, low0)
        plt.scatter(up0, up0)
        plt.show()
    

    python lda,机器学习,python,机器学习,深度学习文章来源地址https://www.toymoban.com/news/detail-726774.html

完整代码

import random

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd


class LDA():
    def __init__(self):
        # 初始化权重矩阵
        self.w = None

    # 计算类内散度矩阵
    def cov(self, X, Y=None):
        # X = (X - np.mean(X, axis=0)) / np.std(X, axis=0)
        X = X - np.mean(X, axis=0)
        return np.dot(X.T, X)

    # 得到投影
    def getY(self, X):
        res = []
        for i in range(X.shape[0]):
            item = X[i, :].dot(self.w.T)
            res.append(item)
        return res

    # 计算W
    def fit(self, X):
        x0 = X[X[:, -1] == 0]
        x0 = x0[:, :-1]
        x1 = X[X[:, -1] == 1]
        x1 = x1[:, :-1]
        sigma0 = self.cov(x0)
        sigma1 = self.cov(x1)
        Sw = sigma1 + sigma0
        # 求均值差
        u0, u1 = np.mean(x0, axis=0), np.mean(x1, axis=0)
        mean_diff = u0 - u1
        # 奇异值分解的方法
        # 对类内散度矩阵进行奇异值分解
        U, S, V = np.linalg.svd(Sw)
        # # # # 计算类内散度矩阵的逆
        Sw_ = np.dot(np.dot(V.T, np.linalg.pinv(np.diag(S))), U.T)
        # # # # 计算w
        self.w = Sw_.dot(mean_diff)
        # 直接矩阵求逆的方法
        Sw = np.mat(Sw)
        # self.w = Sw.I.dot(mean_diff)

    # 预测
    def predict(self, x):
        res = []
        # x = (x - np.mean(x, axis=0)) / np.std(x, axis=0)
        for i in range(x.shape[0]):
            item = x[i, :].dot(self.w.T)
            res.append(int(1 * (item < 0)))
        return res


if __name__ == '__main__':
    df = pd.read_csv('./data/blood_data.txt', header=None, index_col=None)
    res = []
    wlist = []
    # 进行100轮训练,选取最优的参数
    for i in range(100):
        # 划分训练集和测试集
        index = random.sample(range(748), 748)
        train = df.iloc[index[:600], :]
        train = np.array(train)
        test = df.iloc[index[600:], :]
        test = np.array(test)
        # 拟合训练
        lda = LDA()
        try:
            lda.fit(train)
        except:
            print("无法求逆")
            continue
        # 测试集测试
        predata = lda.predict(test[:, :-1])
        acc = (test[predata == test[:, -1]]).shape[0] / test.shape[0]
        # print(acc)
        res.append(acc)
        wlist.append(lda.w)
    print("最佳准确率:", max(res), '\t', "最低准确率:", min(res), '\t', "平均准确率:", np.mean(res))
    print(res.index(max(res)))
    lda2 = LDA()
    lda2.w = wlist[res.index(max(res))]
    index = random.sample(range(748), 748)
    test = df.iloc[index[600:], :]
    test = np.array(test)
    res = lda2.getY(test[:, :-1])
    predata = lda.predict(test[:, :-1])
    acc = (test[predata == test[:, -1]]).shape[0] / test.shape[0]
    print("测试集准确率为:", acc)
    low0 = [i for i in res if i < 0]
    up0 = [i for i in res if i > 0]
    plt.scatter(low0, low0)
    plt.scatter(up0, up0)
    plt.show()


到了这里,关于使用python实现LDA线性判别分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 机器学习---LDA代码

    1. 获取投影坐标        该函数用于获取一个点到一条直线的投影点的坐标。函数中的参数point表示点的坐标,以[a,b] 的形式表示;参数line表示直线的参数,以[k,t]的形式表示,其中k表示直线的斜率,t表示直线的截 距。函数的返回值为投影点的坐标,以[a\\\',b\\\']的形式表示。

    2024年02月11日
    浏览(35)
  • 机器学习之LDA算法

    目录 LDA算法 LDA目标 LDA原理推导 LDA除法模型 LDA减法模型 LDA除法正则模型 LDA减法正则模型 证明:St=Sw+Sb LDA算法流程 LDA优点 LDA缺点 基于LDA的人脸识别 线性判别分析(linear discriminant analysis,LDA), 是一种经典的线性学习方法,其原理是:给定训练样例集,设法将样例投影到

    2024年02月11日
    浏览(34)
  • 机器学习之基于LDA的人脸识别

    目录 LDA降维 思想 matlab代码 fisherface 思想 matlab代码 人脸识别 思想 matlab代码 首先,代码通过使用 dir 函数获取指定路径下所有以\\\".bmp\\\"结尾的文件,并存储在变量 pictures 中。 然后,定义了一些参数: people 表示人数, personPictureNumber 表示每个人的图像数量, Dimension 表示图像的

    2024年02月11日
    浏览(33)
  • 机器学习之线性判别分析(Linear Discriminant Analysis)

    线性判别分析(Linear Discriminant Analysis,简称LDA)是一种经典的监督学习算法,也称\\\"Fisher 判别分析\\\"。LDA在模式识别领域(比如人脸识别,舰艇识别等图形图像识别领域)中有非常广泛的应用。 LDA的核心思想是给定训练样本集,设法将样例投影到一条直线上。使得同类样例的

    2024年02月15日
    浏览(38)
  • 基于机器学习的情绪识别算法matlab仿真,对比SVM,LDA以及决策树

    目录 1.算法理论概述 2.部分核心程序 3.算法运行软件版本 4.算法运行效果图预览 5.算法完整程序工程        情绪识别是一种重要的情感分析任务,旨在从文本、语音或图像等数据中识别出人的情绪状态,如高兴、悲伤、愤怒等。本文介绍一种基于机器学习的情绪识别算法,

    2024年02月15日
    浏览(228)
  • 【数据挖掘】PCA/LDA/ICA:A成分分析算法比较

            在深入研究和比较算法之前,让我们独立回顾一下它们。请注意,本文的目的不是深入解释每种算法,而是比较它们的目标和结果。 如果您想了解更多关于

    2024年02月15日
    浏览(44)
  • 【NLP】使用 LSA、PLSA、LDA 和 lda2Vec 进行主题建模

            本文是对 主题建模 及其相关技术的 更新全面概述 。 在自然语言理解(NLU)任务中,有一个镜头层次结构,通过它我们可以提取含义 - 从单词到句子到

    2024年02月15日
    浏览(36)
  • 基于爬虫+词云图+Kmeans聚类+LDA主题分析+社会网络语义分析对大唐不夜城用户评论进行分析

      🤵‍♂️ 个人主页:@艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞👍🏻 收藏 📂加关注+ 目录 一、项目简介 二、实验过程 2.1获取数据 2.2情感分析 2.3TF-IDF+Kmeans聚类分析 2.4LDA主题

    2024年02月08日
    浏览(53)
  • 基于sklearn实现LDA主题模型(附实战案例)

    目录 LDA主题模型 1.LDA主题模型原理 2.LDA主题模型推演过程 3.sklearn实现LDA主题模型(实战) 3.1数据集介绍 3.2导入数据 3.3分词处理  3.4文本向量化 3.5构建LDA模型 3.6LDA模型可视化  3.7困惑度          其实说到LDA能想到的有两个含义,一种是线性判别分析(Linear Discriminant

    2023年04月15日
    浏览(39)
  • 毕业论文案例-LDA主题模型实现文本聚类

    这是一篇以我毕业论文为背景的博客。由于对数据分析非常感兴趣,所以选择这个主题。在论文的撰写中,我参考了大量相关的CSDN博客。 时光匆匆,在毕业之际,我愿意分享论文过程的体会和心得,给各位兄弟姐妹们做个参考。 (以下内容知网查重过,勿搬运) LDA主题模型

    2024年02月03日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包