Python Sklearn自定义内核提供了错误的决策函数
我已经成功地实现了我自己的定制线性内核,它使用clf.predict运行得非常好。但是,当我想使用Python Sklearn自定义内核提供了错误的决策函数,python,machine-learning,scikit-learn,svm,kernel-methods,Python,Machine Learning,Scikit Learn,Svm,Kernel Methods,我已经成功地实现了我自己的定制线性内核,它使用clf.predict运行得非常好。但是,当我想使用clf.decision\u函数时,它会为所有点提供常量值 这是自定义内核的代码: ``` def linear_basis(x, y): return np.dot(x.T, y) def linear_kernel(X, Y, K=linear_basis): gram_matrix = np.zeros((X.shape[0], Y.shape[0])) for i,
clf.decision\u函数时,它会为所有点提供常量值
这是自定义内核的代码:
```
def linear_basis(x, y):
return np.dot(x.T, y)
def linear_kernel(X, Y, K=linear_basis):
gram_matrix = np.zeros((X.shape[0], Y.shape[0]))
for i, x in enumerate(X):
for j, y in enumerate(Y):
gram_matrix[i,j] = K(x,y)
return gram_matrix
```
现在,将此内核用于一个小型线性训练集
```
#creating random 2D points
sample_size = 100
dat = {
'x': [random.uniform(-2,2) for i in range(sample_size)],
'y': [random.uniform(-2,2) for i in range(sample_size)]
}
data = pd.DataFrame(dat)
# giving the random points a linear structure
f_lin = np.vectorize(lambda x, y: 1 if x > y else 0)
data['z_lin'] = f_lin(data['x'].values, data['y'].values)
data_pos = data[data.z_lin == 1.]
data_neg = data[data.z_lin == 0.]
X_train = data[['x', 'y']]
y_train = data[['z_lin']]
clf_costum_lin = svm.SVC(kernel=linear_kernel) # using my costum kernel here
clf_costum_lin.fit(X_train.values,y_train.values)
# creating a 100x100 grid to manually predict each point in 2D
gridpoints = np.array([[i,j] for i in np.linspace(-2,2,100) for j in np.linspace(-2,2,100)])
gridresults = np.array([clf.predict([gridpoints[k]]) for k in range(len(gridpoints))])
# now plotting each point and the training samples
plt.scatter(gridpoints[:,0], gridpoints[:,1], c=gridresults, cmap='RdYlGn')
plt.scatter(data_pos['x'], data_pos['y'], color='green', marker='o', edgecolors='black')
plt.scatter(data_neg['x'], data_neg['y'], color='red', marker='o', edgecolors='black')
plt.show()
```
这将产生以下结果:
现在,我想使用clf.decision\u函数
复制绘图:
(!注意我不小心在这里切换了颜色!)
这给出了以下曲线图:
这是使用集成线性核(kernel=“linear”)绘制相同数据的示例:
由于自定义内核的预测函数刚刚工作,它应该给出与决策函数相同的工作图,对吗?
我不知道为什么它适用于积分线性函数,但不适用于自定义线性函数,自定义线性函数也适用于预测点,而不适用于决策函数。希望有人能在这里提供帮助。实际的问题真的很愚蠢,但由于需要花费相当长的时间来追踪,我将与大家分享我的调试概要
首先,不是打印,而是打印决策函数的实际值:您会发现第一个值是唯一的,但之后所有值都是常量。在数据集的不同切片上运行相同的操作,此模式将保持不变。所以我想可能有一些值被覆盖了,于是我深入研究了一下SVC
代码。这会产生一些有用的内部函数/属性,比如包含训练数据的\BaseLibSVM\uuuuuxfit
,\uDecision\uFunction
和\uDecision\uFunction
,以及\uCompute\uKernel
。但是没有一个代码表明有问题,运行它们只会显示同样的问题。运行\u compute\u kernel
得到的结果在第一行之后都是零,然后返回到代码,运行linear\u kernel
已经这样做了。因此,最后,它返回到您的线性_内核
函数
返回外部for循环内部,因此只使用X
的第一行,而不计算矩阵的其余部分。(这带来了一个惊喜:为什么预测看起来很好?这似乎是一个侥幸。更改f_lin
的定义,更改类,模型仍然学习斜率-1行。)好吧,这真是太愚蠢了。。。非常感谢,我也已经开始查看sklearn的源代码,没有意识到我的自定义内核一开始就错了。有没有关于如何改进运行时的想法?现在返回的位置正确了,代码看起来效率很低。内核函数可以写成矩阵积,这样可以节省一些时间。为了提高效率,我不确定libsvm在引擎盖下还做了什么。
```
h = .02
xx, yy = np.meshgrid(np.arange(-2 - .5, 2 + .5, h),
np.arange(-2 - .5, 2 + .5, h))
# using the .decision_function here
Z = clf_costum_lin.decision_function(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.RdBu, alpha=.8)
plt.scatter(data_pos['x'], data_pos['y'], color='blue', marker='o', edgecolors='black')
plt.scatter(data_neg['x'], data_neg['y'], color='red', marker='o', edgecolors='black')
plt.show()
```