带有非数字数据的KNeighborClassifier失败
我试图用非数字数据训练KNeighborClassifier
,但我提供的自定义度量允许计算样本之间的相似度分数。带有非数字数据的KNeighborClassifier失败
from sklearn.neighbors import KNeighborsClassifier
#Compute the "ASCII" distance:
def my_metric(a,b):
return ord(a)-ord(b)
#Samples and labels
X = [["a"],["b"], ["c"],["m"], ["z"]]
#S=Start of the alphabet, M=Middle, E=end
y = ["S", "S", "S", "M", "E"]
model = KNeighborsClassifier(metric=my_metric)
model.fit(X,y)
X_test = [["e"],["f"],["w"]]
y_test = [["S"],["M"],["E"]]
model.score(X_test, y_test)
我得到以下错误:
Traceback (most recent call last):
File "/home/marcofavorito/virtualenvs/nlp/lib/python3.5/site-packages/IPython/core/interactiveshell.py", line 2862, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-20-e339c96eea22>", line 1, in <module>
model.score(X_test, y_test)
File "/home/marcofavorito/virtualenvs/nlp/lib/python3.5/site-packages/sklearn/base.py", line 350, in score
return accuracy_score(y, self.predict(X), sample_weight=sample_weight)
File "/home/marcofavorito/virtualenvs/nlp/lib/python3.5/site-packages/sklearn/neighbors/classification.py", line 145, in predict
neigh_dist, neigh_ind = self.kneighbors(X)
File "/home/marcofavorito/virtualenvs/nlp/lib/python3.5/site-packages/sklearn/neighbors/base.py", line 361, in kneighbors
**self.effective_metric_params_)
File "/home/marcofavorito/virtualenvs/nlp/lib/python3.5/site-packages/sklearn/metrics/pairwise.py", line 1247, in pairwise_distances
return _parallel_pairwise(X, Y, func, n_jobs, **kwds)
File "/home/marcofavorito/virtualenvs/nlp/lib/python3.5/site-packages/sklearn/metrics/pairwise.py", line 1090, in _parallel_pairwise
return func(X, Y, **kwds)
File "/home/marcofavorito/virtualenvs/nlp/lib/python3.5/site-packages/sklearn/metrics/pairwise.py", line 1104, in _pairwise_callable
X, Y = check_pairwise_arrays(X, Y)
File "/home/marcofavorito/virtualenvs/nlp/lib/python3.5/site-packages/sklearn/metrics/pairwise.py", line 110, in check_pairwise_arrays
warn_on_dtype=warn_on_dtype, estimator=estimator)
File "/home/marcofavorito/virtualenvs/nlp/lib/python3.5/site-packages/sklearn/utils/validation.py", line 402, in check_array
array = np.array(array, dtype=dtype, order=order, copy=copy)
ValueError: could not convert string to float: 'e'
我想我可以很轻松地实现算法,但没有sklearn
分类的所有功能。我错过了一些选择?或者,如果在我不将样本翻译成浮标之前,我无法训练模型?
N.B.我知道这个问题可以通过把数字而不是字符来解决。但是我需要解决另一个处理非数字数据的问题,并且我无法找到一个简单的浮点映射,如前所述。
您的代码中存在一些错误。首先,你必须以某种方式将分类数据转换为数字数据。 Sklearn中的KNN分类器尚不支持分类数据。其次,您需要使用sklearn中的make_Scorer()函数才能使用您的自定义指标。 KNN中的默认score
函数将返回平均精度而不是您指定的度量。你可以阅读更多关于它here。您需要更改数据集才能使用KNN分类器的sklearn实现。
除了*已经提到的东西:你的方法在数学上有缺陷和sklearn可能不会保证会发生什么。
KNN分类器对于核心数据结构如KD-trees和Ball-trees只是一个很好的包装。 Here you can see what kind of assumptions those need。
Here func is a function which takes two one-dimensional numpy arrays, and returns a distance. Note that in order to be used within the BallTree, the distance must be a true metric: i.e. it must satisfy the following properties
Non-negativity: d(x, y) >= 0
Identity: d(x, y) = 0 if and only if x == y
Symmetry: d(x, y) = d(y, x)
Triangle Inequality: d(x, y) + d(y, z) >= d(x, z)
公平。 That's just what a metric is。
这样表示,您的公制不是真正的公制! (即使最明显的规则:没有给出非负性
现在在上面的文字中,只给出了关于球树(而不是KD树)的警告,并且KNN选择了底层树结构所以这里可能会出现一个不好的情况,你应该避免这种情况,
虽然我不确定,如果这些假设对于KD树也是需要的,我会期待yes和just指向kd-trees docs哪个还在使用这个词指标和可用kd_tree.valid_metrics
(虽然这个名单只是其附带sklearn的通用指标的一个子集)。
我知道我要离开一个重要的一点是!感谢这个信息。在度量属性上。 :) –