《机器学习》西⽠书课后习题3.5——python 实现线性判别分析
《机器学习》西⽠书课后习题3.5——python 实现线性判别分析
《机器学习》西⽠书P69
3.5 编程实现线性判别分析,并给出西⽠数据集3.0a上的结果
理论学习参见⽂章:
注意:在该⽂章中针对w的求法出现了两种⽅式,⼀种是
该⽅法指的应该是针对⼆类LDA,所以我们在解决西⽠数据集问题是求w的⽅法采⽤此⽅法。
另⼀种⽅法是:
此⽅法针对的解决多分类问题是采⽤的策略,在本问题中并不适⽤,具体详见下⽂。
⼆类线性判别分析的解决步骤:
1. 求出均值向量、协⽅差矩阵
2. 求散度矩阵
3. 求出w
下⾯我们按照上述思路逐步完成,并绘出图像。
⼀. 数据的预处理
将西⽠集中的数据进⾏分割、修改
#读取西⽠数据集中的数据并进⾏预处理
def  loadDataset (filename ):
dataset =[]
with  open (filename ,'r',encoding ='utf-8') as  csvfile :
csv_reader =csv .reader (csvfile )
header =next (csv_reader )
for  row in  csv_reader :
if  row [3] == '是':
row [3]=1
else :
row [3]=0
del (row [0])
dataset .append (copy .deepcopy (row ))
data =[[float (x ) for  x in  row ]for  row in  dataset ]
print (data )
return  data
⼆. LDA算法实现
关于求均值向量、协⽅差矩阵可参见python中numpy函数中的部分⽤法,在这不再赘述,直接适⽤。
w =S 1w (μ−μ)
−01计算S 1S 的最⼤的d 个特征值和对应的d 个特征向量(w ,w ,...w ),得到投影矩阵W
−w b 12d
def LDA(data):
data0=[]
linspace函数pythondata1=[]
for x in data:
if x[2]==1:
del(x[2])
data1.append(copy.deepcopy(x))
else:
del(x[2])
data0.append(copy.deepcopy(x))
# 求得两类数据的均值向量
mean0 = np.mean(data0)
mean1 = np.mean(data1)
# 得到两种数据的协⽅差矩阵
diff1 = data1 - mean1
diff0 = data0 - mean0
cov1 = np.anspose(diff1), diff1)
cov0 = np.anspose(diff0), diff0)
# 计算类内散度矩阵
Sw = cov1 + cov0
# 计算类间散度矩阵
Sb=np.anspose(mean0-mean1),(mean0-mean1))
Sw_Inv=np.linalg.inv(Sw)
# a,b=np.linalg.eig(np.dot(Sw_Inv,Sb))# 计算矩阵的特征值和所对应的特征向量
# index = np.argsort(-a)# 将-a中的元素从⼩到⼤排列,提取其对应的index(索引)
# maxIndex = index[:1]
# w = b[:, maxIndex]
# print(w)
w=np.dot(Sw_Inv,mean0-mean1)
print(w)
return w
注意:上⾯有⼀部分代码加以注释,在此予以说明,
a,b=np.linalg.eig(np.dot(Sw_Inv,Sb))# 计算矩阵的特征值和所对应的特征向量
index = np.argsort(-a)# 将-a中的元素从⼩到⼤排列,提取其对应的index(索引)
maxIndex = index[:1]
w = b[:, maxIndex]
这块代码是为了求在多类LDA⽅法中要求的特征向量和特征值,为了验证,我们也⽤此⽅法求得了⼀个w,也参与了后序的运算,最终得到了图像如下:
很明显,所有的点并未完全得到分离,尤其是在直线上存在点的重合现象,因此使⽤特征向量和特征值所求得的w并不能很好的适⽤于⼆分类问题,因此抛弃该⽅法!
三. 绘图
def DrawGraph(dataset,w):
# matplotlib画图中中⽂显⽰会有问题,需要这两⾏设置默认字体
plt.xlabel('密度')
plt.ylabel('含糖量')
plt.xlim(xmax=0.8, xmin=-0.3)
plt.ylim(ymax=0.5, ymin=-0.3)
# 画两条坐标轴并设置轴标签x,y
x1=[]
y1=[]
x2=[]
y2=[]
for x in dataset:
if x[2]==1:
x1.append(copy.deepcopy(x[0]))
y1.append(copy.deepcopy(x[1]))
else:
x2.append(copy.deepcopy(x[0]))
y2.append(copy.deepcopy(x[1]))
colors1 ='#00CED1'# 点的颜⾊
colors2 ='#DC143C'
area = np.pi *4**2# 点⾯积
# 画散点图
plt.scatter(x1, y1, s=area, c=colors1, alpha=0.4, label='好⽠')
plt.scatter(x2, y2, s=area, c=colors2, alpha=0.4, label='⾮好⽠')
plt.plot([0,9.5],[9.5,0], linewidth='0.5', color='#000000')
# plot line
w = w.flatten()
x1 = np.linspace(-1,1,102)
x2 =-w[0]* x1 / w[1]
plt.plot(x1, x2, label="LDA")
plt.legend()
#plt.savefig(r'C:\Users\hp\Desktop\《机器学习》笔记\LDA.png', dpi=300)
plt.show()
最终得到的图像如下:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。