代码:
# 导入必要的库
import numpy as np
import matplotlib.pyplot as plt# 定义类1的数据点,每个数据点是二维的坐标
class1_points = np.array([[1.9, 1.2],[1.5, 2.1],[1.9, 0.5],[1.5, 0.9],[0.9, 1.2],[1.1, 1.7],[1.4, 1.1]])# 定义类2的数据点,每个数据点是二维的坐标
class2_points = np.array([[3.2, 3.2],[3.7, 2.9],[3.2, 2.6],[1.7, 3.3],[3.4, 2.6],[4.1, 2.3],[3.0, 2.9]])# 将两个类的数据点合并为一个大的数据集 x,标签合并为 y
x = np.concatenate((class1_points, class2_points), axis=0) # x 是一个 (14, 2) 形状的数组,包含所有的点
y = np.concatenate((np.zeros(len(class1_points)), np.ones(len(class2_points))), axis=0) # y 是一个包含标签的数组,0 表示 class1,1 表示 class2# 计算先验概率,即每个类在数据集中的概率
prior_prob = [np.sum(y == 0) / len(y), np.sum(y == 1) / len(y)]# 计算每个类的均值向量(每个类的特征的均值)
class_u = [np.mean(x[y==0], axis=0), np.mean(x[y==1], axis=0)]# 计算每个类的协方差矩阵
class_cov = [np.cov(x[y==0], rowvar=False), np.cov(x[y==1], rowvar=False)]# 定义概率密度函数 (PDF),用于计算高斯分布的概率
def pdf(x, mean, cov):n = len(mean) # mean 是特征的维度,这里是2,因为每个数据点有两个特征# 计算常数系数部分,注意是协方差矩阵的行列式coff = 1 / (2 * np.pi) ** (n / 2) * np.sqrt(np.linalg.det(cov))# 计算指数部分,(x - mean) 转置和协方差矩阵的逆相乘,再与 (x - mean) 相乘exponent = np.exp(-(1 / 2) * np.dot(np.dot((x - mean).T, np.linalg.inv(cov)), (x - mean)))# 返回高斯分布的概率密度return coff * exponent# 创建网格点,用于在平面上绘制决策边界
xx, yy = np.meshgrid(np.arange(0, 5, 0.05), np.arange(0, 4, 0.05))# 将网格点转换为 (N, 2) 的矩阵,方便后续计算
grid_points = np.c_[xx.ravel(), yy.ravel()]# 用于存储每个网格点的预测标签
grid_label = []# 遍历网格中的每一个点,计算其后验概率,决定属于哪个类
for point in grid_points:poster_prob = [] # 存储每个类的后验概率for i in range(2): # 遍历两个类# 计算每个类在该点的似然度(即高斯分布的概率)likelihood = pdf(point, class_u[i], class_cov[i])# 计算该类的后验概率,即 先验概率 * 似然度poster_prob.append(prior_prob[i] * likelihood)# 选择后验概率最大的类作为预测的标签pre_class = np.argmax(poster_prob)grid_label.append(pre_class)# 绘制类1的样本点,蓝色标记
plt.scatter(class1_points[:, 0], class1_points[:, 1], c='blue', label='class 1')
# 绘制类2的样本点,红色标记
plt.scatter(class2_points[:, 0], class2_points[:, 1], c='red', label='class 2')
# 添加图例
plt.legend()# 将 grid_label 转换为一个数组,并重塑为与网格形状一致的矩阵,便于绘制等高线图
grid_label = np.array(grid_label)
pre_grid_label = grid_label.reshape(xx.shape)# 绘制决策边界,等高线图,绿色线表示决策边界(即类0与类1的分界线)
contour = plt.contour(xx, yy, pre_grid_label, levels=[0.5], colors='green')# 显示绘图结果
plt.show()
结果: