自定义指数卡方核适配sklearn SVM时遇维度不匹配错误求助
解决自定义指数卡方核函数在sklearn SVM中的形状不匹配问题
这个错误的核心原因是你的自定义核函数没有按照sklearn的要求返回正确形状的核矩阵。sklearn期望自定义核函数接收两个二维数组x(形状(n_samples_x, n_features))和y(形状(n_samples_y, n_features)),并返回一个(n_samples_x, n_samples_y)的矩阵,其中每个元素对应x中第i个样本与y中第j个样本的核函数值。而你的原函数返回的是(n_samples, n_features)的数组,自然会触发形状不匹配的错误。
修正后的代码
import numpy as np from sklearn import svm, datasets # 加载鸢尾花数据集,仅使用前两个特征 iris = datasets.load_iris() train_features = iris.data[:, :2] train_labels = iris.target def my_kernel(x, y): gamma = 1 # 扩展维度以支持广播计算所有样本对的特征差异 x_expanded = x[:, np.newaxis] # 形状变为(n_x, 1, n_features) # 计算每个特征维度的 (x_i - y_j)^2 / (x_i + y_j) diff_squared = (x_expanded - y) ** 2 sum_xy = x_expanded + y # 避免除以0(鸢尾花数据集特征均为正,这里只是防御性处理) sum_xy[sum_xy == 0] = 1e-10 terms = diff_squared / sum_xy # 对特征维度求和,得到样本对的核函数值 kernel_matrix = np.exp(-gamma * np.sum(terms, axis=2)) return kernel_matrix # 初始化并训练SVM分类器 classifier = svm.SVC(kernel=my_kernel) classifier.fit(train_features, train_labels) print(f"Train Accuracy : {classifier.score(train_features, train_labels)}")
关键修改说明
- 维度扩展:通过
x[:, np.newaxis]将输入的样本矩阵扩展为三维数组,让numpy可以广播计算x中每个样本与y中每个样本的特征差异,得到形状为(n_samples_x, n_samples_y, n_features)的中间结果。 - 特征维度求和:指数卡方核需要对所有特征维度的计算项求和,再代入指数公式。通过
np.sum(terms, axis=2)完成这一步,最终得到符合要求的(n_samples_x, n_samples_y)核矩阵。 - 除以0防护:添加了对
x + y为0的情况处理,避免运行时出现除以0的警告或错误(虽然鸢尾花数据不会出现,但这是通用的防御性编程技巧)。
运行修正后的代码,你会发现错误消失,并且能正常输出训练准确率。
内容的提问来源于stack exchange,提问作者Filus
相关产品推荐
相关产品推荐

