介绍
在本实验中,你将实现线性判别分析。实验之前需要上传图片:LDA_figure.png至默认路径。
评分标准如下:
- 要点1:计算每类均值-------------------------(10分)
- 要点2:类内散度矩阵-------------------------(20分)
- 要点3:类间散度矩阵-------------------------(20分)
- 要点4:线性判别分析-------------------------(20分)
- 要点5:可视化降维结果----------------------(30分)
1 计算每类均值
在该部分实验中,为实现线性判别分析,首先需要计算每类样本的均值。
# 引入所需要的库文件
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import os
%matplotlib inline
# 创建仿真数据集
X = np.array([[4,2], [2,4], [2,3], [3,6], [4,4], [9,10], [6,8], [9,5], [8,7], [10,8]])
y = np.hstack((np.zeros(5), np.ones(5)))
X= X.T
#可视化
plt.figure()
colors = ["red", "blue"]
classes = ["class 1", "class 2"]
for color, i in zip(colors, [0, 1]):
plt.scatter(
X[0, y == i], X[1, y == i], alpha=0.8, color=color, label=classes[i]
)
plt.legend(loc="best", shadow=False, scatterpoints=1)
plt.title("Simulation data of 2 classes")
plt.grid(linestyle='--')
plt.show()
1 计算每类均值
在该部分实验中,为实现线性判别分析,首先需要计算每类样本的均值。
**要点 1:** 计算每类样本的均值,并合并为矩阵:[,
]。 如果结果为
[[3 8.4][3.8 7.6]]则计算通过。
# ====================== 在这里填入代码 =======================
def ClassMean(X, y):
X0 = X[:,y==0]
X1 = X[:,y==1]
# 计算每类样本的均值
mean0 = np.mean(X0, axis=1)
mean1 = np.mean(X1, axis=1)
# 合并每类均值为一个矩阵
class_means = np.vstack((mean0, mean1)).T
return class_means
# =============================================================
class_means=ClassMean(X, y)
print('类均值矩阵:\n',class_means)
# print(class_means)
**要点 2:** 计算类内散度矩阵,公式如下
其中和
为两类样本的协方差矩阵。 如果结果为[[13.2 −1.2][−1.2 22]]则计算通过。
# ====================== 在这里填入代码 =======================
def ScatterWithin(X, y):
X0 = X[:, y == 0]
X1 = X[:, y == 1]
m0 = np.mean(X0, axis=1).reshape(-1, 1)
m1 = np.mean(X1, axis=1).reshape(-1, 1)
y0 = (X0 - m0) @ (X0 - m0).T
y1 = (X1 - m1) @ (X1 - m1).T
Sw = y0 + y1
return Sw
# =============================================================
Sw=ScatterWithin(X, y)
print('类内散度矩阵:\n',Sw)
**要点 3:** 计算类间散度矩阵,公式如下
其中和
为两类样本的均值向量。 如果结果为[[29.16 20.52]20.52 14.44]]则计算通过。
# ====================== 在这里填入代码 =======================
def ScatterBetween(X, y):
m0 = np.mean(X[:, y == 0], axis=1).reshape(-1, 1)
m1 = np.mean(X[:, y == 1], axis=1).reshape(-1, 1)
Sb = (m0 - m1) @ (m0 - m1).T
return Sb
# =============================================================
Sb=ScatterBetween(X, y)
print('类间散度矩阵:\n',Sb)
**要点 4:** 实现线性判别分析,计算投影向量w和投影后数据Z。 如果w结果为
[0.9
10.42]
Z结果为[4.47,3.49,3.07,5.23,5.3,12.35,8.79,10.27,10.19,12.43]则计算通过。
# ====================== 在这里填入代码 =======================
def LDA(X, y):
Sw = ScatterWithin(X, y)
Sb = ScatterBetween(X, y)
eig_vals, eig_vecs = np.linalg.eig(np.linalg.inv(Sw) @ Sb)
w = eig_vecs[:, np.argmax(eig_vals)]
Z = X.T @ w
return w, Z
# =============================================================
w,Z=LDA(X, y)
print('投影向量:\n',np.around(w,decimals=2))
print('投影后数据:\n',np.around(Z,decimals=2))
**要点 5:** 可视化投影结果.
w,Z=LDA(X,y)
plt.figure()
colors = ["red", "blue"]
classes = ["class 1", "class 2"]
projections=["class 1 projections","class 2 projections"]
for color, i in zip(colors, [0, 1]):
plt.scatter(X[0,y==i], X[1,y == i], alpha=0.8, color=color, label=classes[i])
plt.scatter(Z[y == i],Z[y==i]*w[1]/w[0], alpha=0.8, color=color, marker='^',label=projections[i])
plt.plot([0, w[0]*12], [0, w[1]*12], color='green', label='Projection vector')
plt.legend(loc="best", shadow=False, scatterpoints=1)
plt.title("LDA of 2 classes")
plt.grid(linestyle="--")
plt.show()