实验1(不同方差的高斯分布)
1.1 实验要求
从两个高斯分布中采样。一组采样为正类,一组采样为负类,两个高斯分布具有不同的方差。
编程实现线性回归,y为一1或1。保存参数,画出回归投影面,同时可视化显示结果。
编程实现线性判别分析,保留参数,对测试数据做出预测,同时可视化显示结果,画出分类面。
1.2 实验效果
1.3 线性回归代码
(1)不同高斯分布数据集生成
import numpy as np
import matplotlib.pyplot as plt
# 生成训练数据集,每类100个数据
def get_train_data(data_size=100):
data_label = np.zeros((2 * data_size, 1))
# class 1
x1 = np.reshape(np.random.normal(1, 0.6, data_size), (data_size, 1))
y1 = np.reshape(np.random.normal(1, 0.8, data_size), (data_size, 1))
data_train = np.concatenate((x1, y1), axis=1)
data_label[0:data_size, :] = -1
# class 2
x2 = np.reshape(np.random.normal(-1, 0.3, data_size), (data_size, 1))
y2 = np.reshape(np.random.normal(-1, 0.5, data_size), (data_size, 1))
data_train = np.concatenate((data_train, np.concatenate((x2, y2), axis=1)), axis=0)
data_label[data_size: 2 * data_size, :] = 1
return data_train, data_label
# 生成测试数据集,每类10个数据
def get_test_data(data_size=10):
testdata_label = np.zeros((2 * data_size, 1))
# class 1
xl = np.reshape(np.random.normal(1, 0.6, data_size), (data_size, 1))
yl = np.reshape(np.random.normal(1, 0.8, data_size), (data_size, 1))
data_test = np.concatenate((xl, yl), axis=1)
testdata_label[0:data_size, :] = -1
# class 2
x2 = np.reshape(np.random.normal(-1, 0.3, data_size), (data_size, 1))
y2 = np.reshape(np.random.normal(-1, 0.5, data_size), (data_size, 1))
data_test = np.concatenate((data_test, np.concatenate((x2, y2), axis=1)), axis=0)
testdata_label[data_size: 2 * data_size, :] = 1
return data_test, testdata_label
(2)线性回归函数LinearRegression
主要4个步骤:
首先将数据集组合成X矩阵,矩阵为m*(d+1),d=2,最后一列恒置为1;
标记label也表示为y向量;
求解w的闭式解,公式如下:
# 线性回归
def LinearRegression(data, label):
# 1. 将数据集组合成X矩阵,矩阵为m*(d+1),d=2,最后一列恒置为1
values = np.ones(200) # 添加最后一列的向量
X = np.matrix(np.insert(data, 2, values, axis=1)) # 此时X为200*3
# 2.标记label也表示为y向量 .T(转置问题?)
y = label
# 3. 求解w的闭式解为(X^T*X)^-1 X^T*y
X_t = np.matrix(X.T)
x1 = np.matmul(X_t, X) # 矩阵相乘
x2 = np.linalg.inv(x1) # 矩阵求逆
x3 = np.matmul(x2, X_t)
w_pre = np.matmul(x3, y)
w_pre = np.array(w_pre)
(3)绘制投影回归面
主要步骤如下:
绘制源数据点,生成平面连续的x与y坐标,通过计算得到的w生成投影回归平面方程f_x。
ax = plt.axes(projection='3d')
# 1. 绘制源数据点
# 第一类
X_o1 = np.asarray((X[0:100, 0])).flatten()
Y_o1 = np.asarray((X[0:100, 1])).flatten()
ax.scatter3D(X_o1, Y_o1, label[0:100, 0],label='Class1') # 绘制散点图
# 第二类
X_o2 = np.asarray((X[100:200, 0])).flatten()
Y_o2= np.asarray((X[100:200, 1])).flatten()
ax.scatter3D(X_o2, Y_o2, label[100:200, 0],label='Class2') # 绘制散点图
# 2. 生成平面连续的x与y坐标
X_f =np.arange(-2, 2, 0.1)
Y_f = np.arange(-2, 2, 0.1)
X_f, Y_f = np.meshgrid(X_f, Y_f) #取网格点
# 3. 通过计算得到的w生成平面方程f_x
f_x = w_pre[0] * X_f + w_pre[1] * Y_f + w_pre[2]
ax.plot_surface(X_f, Y_f, f_x,alpha=0.8,rstride=1, cstride=1,label='RegressionSurface')
plt.show()
1.4 LDA代码
def CovMatrix(T, S):
T = T[:, np.newaxis]
S = S[:, np.newaxis]
X = np.hstack((T, S))
return np.cov(X.T)
(2)LDA线性判别分析实现函数
主要步骤如下:
分别对第0类和第1类数据集进行初始化,包括均值方差等,再利用上面的计算协方差矩阵函数CovMatrix生成两个类别的协方差cov0,cov1。
第二步计算类间散度矩阵
,最后根据推算计算w
(3)绘制分类平面
ax = plt.axes(projection='3d')
#1. 绘制源数据点
X_o1 = np.asarray((X0[..., 0])).flatten()
Y_o1 = np.asarray((X0[..., 1])).flatten()
ax.scatter3D(X_o1, Y_o1, label[0:100, 0], label='Class1') # 绘制散点图
X_o2 = np.asarray((X1[..., 0])).flatten()
Y_o2 = np.asarray((X1[..., 1])).flatten()
ax.scatter3D(X_o2, Y_o2, label[100:200, 0], label='Class2') # 绘制散点图
# 2. 生成连续平面的x,y坐标
X_f = np.arange(-2, 2, 0.1)
Y_f = np.arange(-2, 2, 0.1)
X_f, Y_f = np.meshgrid(X_f, Y_f)
# 3. 平面方程
f_x = w_pre2[0] * X_f + w_pre2[1] * Y_f
ax.plot_surface(X_f, Y_f, f_x, alpha=0.8)
plt.show()
(4)对测试集进行分类并计算分类精度
# 1. 绘制LDA分类曲线
# plt.figure(figsize=(8, 8), dpi=100) # 添加一个窗口。
# plt.title('LDA') # 绘制title
p_x2 = np.asarray((data[0:200, 0])).flatten()
p_y2 = ((-1) * w_pre2[0] * p_x2) / w_pre2[1]
plt.plot(p_x2, p_y2, c='green', linewidth=2, linestyle="-", label="LDA") # 绘制LDA分类曲线
plt.scatter(data_train[0:100, 0], data_train[0:100, 1], label="class1") # plot在一个figure窗口中添加一个图,绘制曲线,默认颜色
plt.scatter(data_train[100:200, 0], data_train[100:200, 1], label="class2")
plt.legend(loc='upper right', frameon=False) # 标签位置
plt.show()
# 2.利用训练得到的w测试集进行预测
p_x_test = np.asarray((data_test[0:200, 0])).flatten()
p_y_test = ((-1) * w_pre2[0] * p_x_test) / w_pre2[1]
output = np.zeros((200, 1))
# 3. 计算分类精度acc
correct_num = 0
for i in range(np.size(p_y_test)):
output[i] = 1 if p_y_test[i] > 0 else -1
if output[i] == testdata_label[i]:
correct_num = correct_num + 1
acc = correct_num / np.size(p_y_test)
# 4. 输出分类精度acc
print(acc)
1.5 主函数main
if __name__ == '__main__':
data_train, data_label = get_train_data()
LinearRegression(data_train, data_label)
LDA(data_train, data_label)
实验2 (相同方差的高斯分布)
2.1 实验要求
从两个高斯分布中采样。一组采样为正类,一组采样为负类。两个高斯分布具有相同的方差。
在生成采用数据集时:
x1 = np.reshape(np.random.normal(1, 0.6, data_size), (data_size, 1))
上述代码中np.random.normal()函数的第一个、第二个参数分别代表正态分布的均值以及正态分布的标准差,保持第二个参数相同,生成两类训练数据集。
2.2 实验效果
2.3 效果分析
与不同方差的两类高斯分布数据相比,相同方差大小的高斯分布在线性回归时,得到的回归投影面与真实数据更加拟合。但在利用LDA判别分析进行分类时分类平面却不能很好的分割两个类别的数据,从图7可以看出,分类平面与边缘点的距离十分接近,还有误分类的离散数据点。