如何可视化CUML版本SVC的决策边界或超平面?
嘿,我明白你遇到的问题了——用sklearn的SVC可视化决策边界很顺手,但换到CUML的版本连coef_都拿不到,官方文档也没例子,确实头疼。我来给你拆解一下怎么解决:
首先得明确:CUML的SVC虽然和sklearn的API尽量对齐,但在不同核函数下的处理逻辑是不一样的,能不能拿到coef_、怎么可视化决策边界,得看你用的是线性核还是非线性核:
1. 使用线性核(kernel='linear')的情况
这时候CUML的SVC其实是支持coef_和intercept_属性的,和sklearn完全一致。如果你拿不到,可能是用了旧版本的CUML(建议升级到22.06及以后的版本),或者没注意到CUML返回的是cudf对象,需要转成numpy数组才能用。
直接上可运行的例子:
import cuml import cudf import matplotlib.pyplot as plt import numpy as np # 生成线性可分的示例数据 X = cudf.DataFrame({'x1': np.random.randn(100), 'x2': np.random.randn(100)}) y = cudf.Series(np.where(X['x1'] + X['x2'] > 0, 1, 0)) # 初始化并拟合线性SVC svc = cuml.svm.SVC(kernel='linear') svc.fit(X, y) # 获取系数和截距,转成numpy数组方便后续计算 coef = svc.coef_.to_array() intercept = svc.intercept_.to_array()[0] # 生成网格点用于绘制边界 x_min, x_max = X['x1'].min() - 1, X['x1'].max() + 1 y_min, y_max = X['x2'].min() - 1, X['x2'].max() + 1 xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02), np.arange(y_min, y_max, 0.02)) # 把网格点转成cudf DataFrame,传给模型计算决策函数 grid = cudf.DataFrame({'x1': xx.ravel(), 'x2': yy.ravel()}) Z = svc.decision_function(grid).to_array() Z = Z.reshape(xx.shape) # 可视化 plt.contourf(xx, yy, Z, alpha=0.8, cmap=plt.cm.Paired) plt.scatter(X['x1'].to_array(), X['x2'].to_array(), c=y.to_array(), edgecolors='k', cmap=plt.cm.Paired) plt.title('CUML Linear SVC 决策边界') plt.show()
2. 使用非线性核(比如kernel='rbf'、poly)的情况
不管是sklearn还是CUML,非线性核的SVC都没有coef_属性——因为非线性核是把数据映射到高维空间构建超平面,这个高维空间的系数没法直接暴露出来。这时候可视化的思路是:生成网格点,用训练好的模型对每个网格点做预测或计算决策函数,再根据结果画出边界。
CUML的SVC支持predict和decision_function方法,步骤和sklearn几乎一样,只是要注意把numpy格式的网格数据转成cudf对象再传入模型:
import cuml import cudf import matplotlib.pyplot as plt import numpy as np # 生成非线性可分的示例数据 X = cudf.DataFrame({'x1': np.random.randn(200), 'x2': np.random.randn(200)}) y = cudf.Series(np.where(X['x1']**2 + X['x2']**2 > 1, 1, 0)) # 拟合RBF核SVC svc = cuml.svm.SVC(kernel='rbf', C=1.0, gamma='scale') svc.fit(X, y) # 生成网格点 x_min, x_max = X['x1'].min() - 1, X['x1'].max() + 1 y_min, y_max = X['x2'].min() - 1, X['x2'].max() + 1 xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02), np.arange(y_min, y_max, 0.02)) # 转换为cudf并预测 grid = cudf.DataFrame({'x1': xx.ravel(), 'x2': yy.ravel()}) Z = svc.predict(grid).to_array() Z = Z.reshape(xx.shape) # 可视化 plt.contourf(xx, yy, Z, alpha=0.8, cmap=plt.cm.Paired) plt.scatter(X['x1'].to_array(), X['x2'].to_array(), c=y.to_array(), edgecolors='k', cmap=plt.cm.Paired) plt.title('CUML RBF SVC 决策边界') plt.show()
最后再补充一下:如果你用线性核还是拿不到coef_,先检查CUML的版本,旧版本可能存在API不一致的问题;另外,CUML的属性返回的是cudf的Series或DataFrame,必须用.to_array()转换成numpy数组才能和matplotlib配合使用哦。
备注:内容来源于stack exchange,提问作者user2718067

