在我的代码中,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
indexError:元组索引
这是我写的自定义的高斯内核:
import math
def gauss_kernel(x1, x2, gamma):
sigma = math.sqrt(gamma)
return np.exp(-np.sum((x1-x2)**2)/(2*sigma**2))
我应该如何解决此问题?当我查看Sklearn中的SVM示例时,他们基本上做同样的事情。我相信我正在忽略一些小东西,但是在与Sklearn示例匹配时无法解决问题。
请确保自定义内核的输出是方形矩阵。
当前您的gauss_kernel
实现将返回一个数字,而不是数组。因此,呼叫形状[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))])
然后使用您的代码。
NOTE :这只是将单个数字包裹到数组的解决方法。您应该检查原始gauss_kernel
返回单个数字的问题。
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)
今天我做coursera功课EX6,我也有同样的问题。现在我解决了这个问题。Sklearn使用自定义内核请求内核函数返回新的[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] euclidean距离,然后使用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)
最终情节:VisualizeBoundary
我也有同样的问题。这是我这样做的方式,现在具有正确的形状:
来自sklearn.metrics.pairwise导入euclidean_distances
def gauss_kernel(x1,x2,伽马):Sigma = Math.sqrt(伽马)返回np.exp(-euclidean_distances(x1,x2) 2/(2*Sigma 2))