山东大学机器学习实验 实验3 LDA 线性判别 python

请勿直接复制代码

代码地址 https://github.com/W1412X/SDU_mechine_learning/tree/main/lab3

点击此处直接进入

两个类别

导入数据
import numpy as np 
red_class=np.loadtxt('/home/wangxv/Files/hw/ml/lab3/data/ex3Data/ex3red.dat')
blue_class=np.loadtxt('/home/wangxv/Files/hw/ml/lab3/data/ex3Data/ex3blue.dat')
red_class
array([[2.95, 6.63],
       [2.53, 7.79],
       [3.57, 5.65],
       [3.16, 5.47],
       [2.78, 6.42],
       [2.78, 7.42],
       [3.18, 8.27],
       [3.28, 6.42],
       [3.68, 7.42],
       [3.58, 8.16],
       [2.78, 8.42],
       [2.78, 6.42],
       [2.78, 7.42],
       [2.78, 8.42]])
计算平均向量
red_mean=np.array([red_class[:,0].mean(),red_class[:,1].mean()])
blue_mean=np.array([blue_class[:,0].mean(),blue_class[:,1].mean()])
计算red/blue点类协方差矩阵
s_red=np.dot((red_class-red_mean).T,(red_class-red_mean))
s_blue=np.dot((blue_class-blue_mean).T,(blue_class-blue_mean))
计算类内散度矩阵以及类间散度矩阵
s_w=np.array(s_blue+s_red)
s_b=np.dot(np.array([(red_mean-blue_mean)]).T,np.array([(red_mean-blue_mean)]))
print(s_w)
print(s_b)
[[ 4.80081429 -1.41724286]
 [-1.41724286 29.07295714]]
[[1.54824694 3.28313673]
 [3.28313673 6.96205918]]
得到方程

S w − 1 ⋅ S B ⋅ w = λ ⋅ w {S_w}^{-1} \cdot S_B \cdot w = \lambda \cdot w Sw1SBw=λw

进一步

S w − 1 ⋅ S B = λ ⋅ I {S_w}^{-1} \cdot S_B = \lambda \cdot I Sw1SB=λI



m=np.dot(np.linalg.inv(s_w),s_b)
lamda=[0,m[0,0]+m[1,1]]
lamda
[0, 0.6378184048755453]
直接计算 w

w=np.dot(np.linalg.inv(s_w),np.array([red_mean-blue_mean]).T)
length = np.sqrt(w[0]**2 + w[1]**2)
w=w/length
w
array([[0.94042471],
       [0.34000199]])
画图
import matplotlib.pyplot as plt
fig1=plt.figure(0)
plt.scatter(red_class[:,0],red_class[:,1],marker='o',color='red')
plt.scatter(blue_class[:,0],blue_class[:,1],marker='o',color='blue')
plt.axline((0,0),(w[0][0],w[1][0]), linestyle='-', color='black')
#映射点
red_projection_len=np.array(np.dot(red_class[:,0],w[0][0])+np.dot(red_class[:,1],w[1][0]))
blue_projection_len=np.array(np.dot(blue_class[:,0],w[0][0])+np.dot(blue_class[:,1],w[1][0]))
red_projection=np.array([red_projection_len*w[0][0],red_projection_len*w[1][0]])
blue_projection=np.array([np.multiply(blue_projection_len,w[0][0]),np.multiply(blue_projection_len,w[1][0])])
plt.scatter(red_projection[0],red_projection[1],marker='o',color='red')
plt.scatter(blue_projection[0],blue_projection[1],marker='o',color='blue')
<matplotlib.collections.PathCollection at 0x7f5696a26f70>

在这里插入图片描述

多个类别

导入数据
import numpy as np
red_class=np.loadtxt('/home/wangxv/Files/hw/ml/lab3/data/ex3Data/ex3red.dat')
green_class=np.loadtxt('/home/wangxv/Files/hw/ml/lab3/data/ex3Data/ex3green.dat')
blue_class=np.loadtxt('/home/wangxv/Files/hw/ml/lab3/data/ex3Data/ex3blue.dat')
red_class
array([[2.95, 6.63],
       [2.53, 7.79],
       [3.57, 5.65],
       [3.16, 5.47],
       [2.78, 6.42],
       [2.78, 7.42],
       [3.18, 8.27],
       [3.28, 6.42],
       [3.68, 7.42],
       [3.58, 8.16],
       [2.78, 8.42],
       [2.78, 6.42],
       [2.78, 7.42],
       [2.78, 8.42]])
计算平均向量
red_mean=np.array([red_class[:,0].mean(),red_class[:,1].mean()])
blue_mean=np.array([blue_class[:,0].mean(),blue_class[:,1].mean()])
green_mean=np.array([green_class[:,0].mean(),green_class[:,1].mean()])
all_mean=(red_mean+blue_mean+green_mean)/3.0
计算协方差
s_red=np.cov(red_class.T)
s_blue=np.cov(blue_class.T)
s_green=np.cov(green_class.T)
计算类内散度矩阵(这里类内散度矩阵被重新定义为每个类别的散度矩阵之和)
s_w=s_red+s_green+s_blue
s_w
array([[ 0.83919725, -0.18908407],
       [-0.18908407,  2.66521923]])
计算类间散度矩阵
m=red_class.shape[0]
sb_red=m*np.dot(np.array([red_mean-all_mean]).T,np.array([red_mean-all_mean]))
sb_blue=m*np.dot(np.array([blue_mean-all_mean]).T,np.array([blue_mean-all_mean]))
sb_green=m*np.dot(np.array([green_mean-all_mean]).T,np.array([green_mean-all_mean]))
s_b=sb_red+sb_blue+sb_green
s_b
array([[ 78.55411429,  84.16194286],
       [ 84.16194286, 104.00893333]])

S w − 1 ⋅ S B {S_w}^{-1}\cdot S_B Sw1SB

inv_sw_sb=np.dot(np.linalg.inv(s_w),s_b)
inv_sw_sb
array([[102.35742211, 110.85345158],
       [ 38.83961935,  46.88903383]])
计算特征向量
values, vectors = np.linalg.eig(inv_sw_sb)
vectors
w1=vectors[:,0]
w2=vectors[:,1]
print(w1)
print(w2)
[0.93088546 0.36531119]
[-0.74595516  0.66599617]
画图
import matplotlib.pyplot as plt 
fig, ax = plt.subplots()
ax.scatter(red_class[:,0],red_class[:,1],marker='o',color='red')
ax.scatter(blue_class[:,0],blue_class[:,1],marker='o',color='blue')
ax.scatter(green_class[:,0],green_class[:,1],marker='o',color='green')
k1=w1[1]/w1[0]
k2=w2[1]/w2[0]
ax.axline((0,0),(1,k1),linestyle='-', color='black')
ax.axline((0,0),(1,k2),linestyle='-', color='black')
ax.set_xlim(-9,9)
ax.set_ylim(-10,20)

###
#映射点
red_projection_len=np.array(np.dot(red_class[:,0],w1[0])+np.dot(red_class[:,1],w1[1]))
blue_projection_len=np.array(np.dot(blue_class[:,0],w1[0])+np.dot(blue_class[:,1],w1[1]))
green_projection_len=np.array(np.dot(green_class[:,0],w1[0])+np.dot(green_class[:,1],w1[1]))
red_projection=np.array([red_projection_len*w1[0],red_projection_len*w1[1]])
blue_projection=np.array([np.multiply(blue_projection_len,w1[0]),np.multiply(blue_projection_len,w1[1])])
green_projection=np.array([green_projection_len*w1[0],green_projection_len*w1[1]])
plt.scatter(red_projection[0],red_projection[1],marker='o',color='red')
plt.scatter(blue_projection[0],blue_projection[1],marker='o',color='blue')
plt.scatter(green_projection[0],green_projection[1],marker='o',color='green')


red_projection_len1=np.abs(np.array(np.dot(red_class[:,0],w2[0])+np.dot(red_class[:,1],w2[1])))
blue_projection_len1=np.abs(np.array(np.dot(blue_class[:,0],w2[0])+np.dot(blue_class[:,1],w2[1])))
green_projection_len1=np.abs(np.array(np.dot(green_class[:,0],w2[0])+np.dot(green_class[:,1],w2[1])))
red_projection1=np.array([red_projection_len1*w2[0],red_projection_len1*w2[1]])
blue_projection1=np.array([np.multiply(blue_projection_len1,w2[0]),np.multiply(blue_projection_len1,w2[1])])
green_projection1=np.array([green_projection_len1*w2[0],green_projection_len1*w2[1]])
plt.scatter(red_projection1[0],red_projection1[1],marker='o',color='red')
plt.scatter(blue_projection1[0],blue_projection1[1],marker='o',color='blue')
plt.scatter(green_projection1[0],green_projection1[1],marker='o',color='green')
fig.show()
/tmp/ipykernel_4571/3613756043.py:35: UserWarning: FigureCanvasAgg is non-interactive, and thus cannot be shown
  fig.show()

在这里插入图片描述

可以看到使用第一个特征向量的分类效果明显好于第二个

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值