Python Sklearn自定义内核提供了错误的决策函数

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.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, 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()
```