机器学习实验2 线性判别分析

本文详细描述了一个使用Python进行线性判别分析(LDA)的实验,包括数据预处理、模型构建、求解w向量、测试集预测及准确率计算,最后通过matplotlib进行结果可视化。实验加深了对LDA算法的理解和Python操作技巧的掌握。
摘要由CSDN通过智能技术生成
  • 实验目的

1. 划分测试集(600)和训练集(148),对数据集进行线性判别分析

2. 将模型结果的投影方向 w 进行输出

3. 输出测试集的准确率acc

4. 最好能够将数据的分析结果进行可视化

  • 实验内容:

1、数据是存储在txt文件中,使用np.loadtxt将其读出并存入array中,文件中的数据是由’,’分隔,函数默认是空格分隔,所以参数delimiter=','。

然后使用切片,分割数据。

2、根据公式求出w。首先使用布尔索引将分离出两类的数据,并取均值得到均值向量u0和u1。然后根据公式进行Sw和w的求解,在矩阵运算时可以把ndarray使用asmatrix转换为矩阵,可以直接进行*、T、I等运算。得出w并输出。在运算过程中要注意矩阵的维度,防止出现错误。

3、已经得出了w向量,根据公式可以求出两个样本的中心在直线上的投影值,为后面预测做准备。

4、对测试集进行测试,得出准确率,并对结果进行可视化处理。由wT*x可以得出测试集的数据的投影值,根据LDA的原理:数据在低维度上进行投影,投影后希望每一种类别数据的投影点尽可能的接近,而不同类别的数据的类别中心之间的距离尽可能的大。那么找预测值离得最近的样本中心点,就是这个数据的预测类别。之后和标签进行比较并求出准确率。

可以使用matplotlib进行可视化输出,由于值都是一个标量,所以可以只在一个维度表示出来之间的关系。只要x轴,但是matplotlib是默认二维的,可以使用ax.axis[:].set_visible(False) 隐藏默认坐标轴,并自己创建x轴;使用xlim限定x轴的范围,之后找出各类的点并画在坐标轴上,两个中心使用红色,预测值分别使用蓝绿两色标出。

运行结果:(python版本为3.8,可能在运算精度等方面存在偏差)

可视化结果:

可以看到分类是根据离中心点远近进行分类的。

  • 实验原理:

  • 心得体会:

通过这次实验,我对于LDA算法的思想有了更清晰的了解,即数据在低维度上进行投影,投影后希望每一种类别数据的投影点尽可能的接近,而不同类别的数据的类别中心之间的距离尽可能的大。推导过程也根据南瓜书有了一定的了解。经过实践,可以对这个算法掌握地更加熟练。

同时在实验中也对python的一些操作,如布尔值索引、切片、列表推导式以及numpy函数等进一步熟悉。也学习了matplotlib进行数据的可视化处理。巩固所学知识,为以后的学习打下坚实的基础。

import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist as axisartist


def get_w(x, y):
    """
    根据公式得到w,和均值向量
    :param x:训练集
    :param y:训练集的标签
    :return:w和均值向量u0,u1
    """
    u0 = np.asmatrix(np.average(x[y[:] == 0], axis=0))
    u1 = np.asmatrix(np.average(x[y[:] == 1], axis=0))
    x0 = np.asmatrix(x[y[:] == 0])
    x1 = np.asmatrix(x[y[:] == 1])
    Sw = (x0 - u0).T * (x0 - u0) + (x1 - u1).T * (x1 - u1)
    w = Sw.I * np.asmatrix(u0 - u1).T
    print("w : ", w)
    return w, u0, u1


def get_centre(w, u0, u1):
    """
    求样本中心
    :param w: w向量
    :param u0: 均值向量u0
    :param u1: 均值向量u1
    :return: 样本中心投影值centre0、centre1
    """
    centre0 = np.array(w.T * u0.T)
    centre1 = np.array(w.T * u1.T)
    return centre0[0][0], centre1[0][0]


def test(w, x, lable, c0, c1):
    """
    进行预测和可视化
    :param w: w向量
    :param x: 训练集
    :param lable: 训练集标签
    :param c0: 样本0中心投影值
    :param c1: 样本1中心投影值
    """
    predict_value = np.array(np.asmatrix(w).T * x.T)
    y = [0 if abs(c0 - i) < abs(c1 - i) else 1 for i in predict_value[0]]
    acc = np.mean([y == lable])
    print("acc : ", acc)

    fig = plt.figure()
    ax = axisartist.Subplot(fig, 1, 1, 1)
    fig.add_axes(ax)
    ax.axis[:].set_visible(False)  # 隐藏默认坐标轴
    ax.axis["x"] = ax.new_floating_axis(0, 0)  # 创建X轴,通过(0,0)点
    # ax.axis["y"] = ax.new_floating_axis(1, 0)  # 创建Y轴,通过(0,0)点
    ax.axis["x"].set_axis_direction('top')  # 设置X轴刻度方向为上方
    # ax.axis["y"].set_axis_direction('left')  # 设置Y轴刻度方向为左侧
    plt.xlim([-0.001, 0.01])

    class0 = [i for i in predict_value[0] if abs(c0 - i) < abs(c1 - i)]
    class1 = [i for i in predict_value[0] if abs(c0 - i) >= abs(c1 - i)]
    ax.scatter(class0, np.zeros(len(class0)), color='green', alpha=0.5)
    ax.scatter(class1, np.zeros(len(class1)), color='blue', alpha=0.5)
    ax.scatter((c0, c1), (0, 0), color='red', alpha=1)
    plt.show()


if __name__ == '__main__':
    data = np.loadtxt(r'D:\A学习\机器学习\实验\实验2'
                      r'\输血服务中心数据集\blood_data.txt', delimiter=',')

    train_x = data[:600, :4]
    train_y = data[:600, 4]
    test_x = data[600:, :4]
    test_y = data[600:, 4]

    w, u0, u1 = get_w(train_x, train_y)
    centre0, centre1 = get_centre(w, u0, u1)
    test(w, test_x, test_y, centre0, centre1)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值