np.random.seed(42) # 设置随机种子确保可重复性
feature_matrix_2d = np.random.randn(100, 2) # 生成100个二维标准正态样本
class_labels_2d = np.array([-1] * 50 + [1] * 50) # 前50个标记为-1类,后50个为+1类
feature_matrix_2d[class_labels_2d == 1] += 1 # 将+1类的样本中心平移至(1,1)
def visualize_svm_boundary(features, labels, model, title, ax):
"""绘制SVM决策边界、间隔边界和支持向量的可视化函数"""
x_min, x_max = features[:, 0].min() - 1, features[:, 0].max() + 1 # 计算X轴绘图范围
y_min, y_max = features[:, 1].min() - 1, features[:, 1].max() + 1 # 计算Y轴绘图范围
xx_grid, yy_grid = np.meshgrid(np.linspace(x_min, x_max, 200), np.linspace(y_min, y_max, 200)) # 创建密集网格
grid_decision_values = model.decision_function(np.c_[xx_grid.ravel(), yy_grid.ravel()]) # 在网格点上计算决策函数值
grid_decision_values = grid_decision_values.reshape(xx_grid.shape) # 重塑为二维矩阵
ax.contourf(xx_grid, yy_grid, grid_decision_values, levels=[-100, 0, 100], colors=['#ffcfdf', '#a8d8ea'], alpha=0.4) # 用颜色填充决策区域
ax.contour(xx_grid, yy_grid, grid_decision_values, levels=[-1, 0, 1], colors=['gray', 'black', 'gray'], linestyles=['--', '-', '--'], linewidths=[1, 2, 1]) # 绘制间隔边界和决策边界
ax.scatter(features[labels == -1, 0], features[labels == -1, 1], c='darkorange', marker='s', s=40) # 绘制-1类散点
ax.scatter(features[labels == 1, 0], features[labels == 1, 1], c='steelblue', marker='o', s=40) # 绘制+1类散点
sv_points = model.support_vectors_ # 获取支持向量坐标
ax.scatter(sv_points[:, 0], sv_points[:, 1], s=150, facecolors='none', edgecolors='red', linewidths=1.5) # 用红色空心圆标记支持向量
ax.set_title(f'{title} (支持向量数: {len(sv_points)})', fontsize=12) # 显示标题和支持向量数量
fig, axes = plt.subplots(1, 2, figsize=(12, 5)) # 创建1行2列的子图
linear_svc_strict = SVC(kernel='linear', C=10) # 创建C=10的线性SVC(较严格)
linear_svc_strict.fit(feature_matrix_2d, class_labels_2d) # 拟合模型
visualize_svm_boundary(feature_matrix_2d, class_labels_2d, linear_svc_strict, 'C=10', axes[0]) # 可视化C=10的结果
linear_svc_relaxed = SVC(kernel='linear', C=0.1) # 创建C=0.1的线性SVC(较宽松)
linear_svc_relaxed.fit(feature_matrix_2d, class_labels_2d) # 拟合模型
visualize_svm_boundary(feature_matrix_2d, class_labels_2d, linear_svc_relaxed, 'C=0.1', axes[1]) # 可视化C=0.1的结果
plt.tight_layout() # 自动调整子图间距
plt.show() # 显示图形