Python 在self.u compute内核(X)中,提升值错误(“X.shape[0]应等于X.shape[1]”)

Python 在self.u compute内核(X)中,提升值错误(“X.shape[0]应等于X.shape[1]”),python,machine-learning,scikit-learn,svm,Python,Machine Learning,Scikit Learn,Svm,在我的代码中,X和y是训练数据: from sklearn.svm import SVC clf = SVC(kernel=lambda x,y:gauss_kernel(x, y, 100) ) print(X.shape[0]) print(X.shape[1]) print(X.shape) clf.fit(X, y) 我得到以下错误: 211 2 (211, 2) /Users/mona/anaconda/lib/python3.6/site-packages/sklearn/uti

在我的代码中,X和y是训练数据:

from sklearn.svm import SVC
clf = SVC(kernel=lambda x,y:gauss_kernel(x, y, 100) )
print(X.shape[0])
print(X.shape[1])
print(X.shape)

clf.fit(X, y)
我得到以下错误:

211
2
(211, 2)
/Users/mona/anaconda/lib/python3.6/site-packages/sklearn/utils/validation.py:547: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().
  y = column_or_1d(y, warn=True)
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-23-1f163ab380a5> in <module>()
      8 print(X.shape)
      9 
---> 10 clf.fit(X, y)
     11 plot_data()
     12 plot_boundary(svm,-.5,.3,-.8,.6)

~/anaconda/lib/python3.6/site-packages/sklearn/svm/base.py in fit(self, X, y, sample_weight)
    185 
    186         seed = rnd.randint(np.iinfo('i').max)
--> 187         fit(X, y, sample_weight, solver_type, kernel, random_seed=seed)
    188         # see comment on the other call to np.iinfo in this file
    189 

~/anaconda/lib/python3.6/site-packages/sklearn/svm/base.py in _dense_fit(self, X, y, sample_weight, solver_type, kernel, random_seed)
    226             X = self._compute_kernel(X)
    227 
--> 228             if X.shape[0] != X.shape[1]:
    229                 raise ValueError("X.shape[0] should be equal to X.shape[1]")
    230 

我该如何解决这个问题?当我看sklearn中的SVM示例时,它们基本上做了相同的事情。我相信我忽略了一些小问题,但在匹配sklearn示例时无法确定问题所在

请确保自定义内核的输出为方形矩阵

当前,您的
gauss\u内核的实现将返回一个数字,而不是一个数组。因此,调用形状[0]或形状[1]会抛出“元组索引超出范围错误”

因此,请确定:

import math
def gauss_kernel(x1, x2):
    sigma = math.sqrt(100) 
    return np.array([np.exp(-np.sum((x1-x2)**2)/(2*sigma**2))])
然后使用你的代码


注意:这只是将单个数字包装到数组中的一种变通方法。您应该检查原始的
gauss\u内核有什么问题,它返回的是单个数字。

今天我做了课程作业ex6,我也有同样的问题。现在我来解决这个问题。
from sklearn import svm

def gauss_kernel(x1, x2, gamma):
    x1 = x1.flatten()
    x2 = x2.flatten()
    sigma = math.sqrt(gamma) 
    return np.exp(-np.sum((x1-x2)**2)/(2*sigma**2))



# from @lejlot http://stackoverflow.com/a/26962861/583834
def gaussianKernelGramMatrix(X1, X2, K_function=gauss_kernel, gamma=0.1):
    """(Pre)calculates Gram Matrix K"""

    gram_matrix = np.zeros((X1.shape[0], X2.shape[0]))
    for i, x1 in enumerate(X1):
        for j, x2 in enumerate(X2):
            gram_matrix[i, j] = K_function(x1, x2, gamma)
    return gram_matrix

gamma=0.1
y = y.flatten()

clf = svm.SVC(kernel="precomputed", verbose=2, C=2.0, probability=True)
clf.fit(gaussianKernelGramMatrix(X,X, gauss_kernel, gamma=gamma), y)
sklearn use custom kernel request kernel函数返回新的[m*m]矩阵,代码如下:

def _compute_kernel(self, X):
        """Return the data transformed by a callable kernel"""
        if callable(self.kernel):
            # in the case of precomputed kernel given as a function, we
            # have to compute explicitly the kernel matrix
            kernel = self.kernel(X, self.__Xfit)
            if sp.issparse(kernel):
                kernel = kernel.toarray()
            X = np.asarray(kernel, dtype=np.float64, order='C')
        return X
所以我定义了返回矩阵的核函数,它可以计算x1=[m,n]和x2=[h,n]欧氏距离,然后使用exp计算返回值

def gaussianKernel(x1: ndarray, x2: ndarray, sigma):
    # RBFKERNEL returns a radial basis function kernel between x1 and x2
    # sim = gaussianKernel(x1, x2) returns a gaussian kernel between x1 and x2
    # and returns the value in sim

    # Ensure that x1 and x2 are column vectors
    m = size(x1, 0)
    n = size(x2, 0)

    # You need to return the following variables correctly.
    sim = 0

    # ====================== YOUR CODE HERE ======================
    # Instructions: Fill in this function to return the similarity between x1
    #               and x2 computed using a Gaussian kernel with bandwidth
    #               sigma
    #
    # Note: use the matrix compute the distence
    M = x1@x2.T
    H1 = sum(square(mat(x1)), 1)  # [m,1]
    H2 = sum(square(mat(x2)), 1)  # [n,1]
    D = H1+H2.T-2*M

    sim = exp(-D/(2*sigma*sigma))
    # =============================================================
    return sim
现在在主函数中添加以下代码行:

def mykernel(x1, x2): return gaussianKernel(x1, x2, sigma)
model = svm.SVC(C, kernel=mykernel)  # type:SVC
model.fit(X, y.ravel())
visualizeBoundary(X, y, model)
最后的情节:

我修正了这个问题,但后来我陷入了绘制边界的困境。你能看一下吗?理想情况下,我希望使用my_svm.SVC.predict来绘制边界,但它会给我错误,如中所示
def mykernel(x1, x2): return gaussianKernel(x1, x2, sigma)
model = svm.SVC(C, kernel=mykernel)  # type:SVC
model.fit(X, y.ravel())
visualizeBoundary(X, y, model)