【问题标题】:KNeighborClassifier with non-numeric data fails具有非数字数据的 KNeighborClassifier 失败
【发布时间】:2017-09-22 20:27:20
【问题描述】:

我正在尝试使用非数字数据训练 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 分类器的所有功能。我错过了一些选择?或者,如果在我不将样本转换为浮点数之前,我就无法训练模型?

注意我知道这个问题可以通过输入数字而不是字符来轻松解决。但是我需要解决另一个处理非数字数据的问题,并且我无法找到一个简单的浮点映射,如前所述。

【问题讨论】:

    标签: python machine-learning scikit-learn knn nearest-neighbor


    【解决方案1】:

    除了 Mohammed 已经提到的内容:您的方法在数学上存在缺陷,sklearn 可能无法保证会发生什么。

    KNN-classifier 只是像 KD-treesBall-trees 这样的核心数据结构的一个很好的包装器。 Here you can see what kind of assumptions those need.

    这里的 func 是一个函数,它接受两个一维 numpy 数组,并返回一个距离。请注意,为了在 BallTree 中使用,距离必须是一个真实的度量:即它必须满足以下属性

    非负性:d(x, y) >= 0

    身份:d(x, y) = 0 当且仅当 x == y

    对称性:d(x, y) = d(y, x)

    三角不等式:d(x, y) + d(y, z) >= d(x, z)

    公平地说。 That's just what a metric is.

    这样说,您的 metric 不是真正的指标! (即使是最明显的规则:没有给出非否定性。

    现在在上面的文本中,只给出了关于 Ball-tree(不是 KD-tree)的警告,并且 KNN 会自动选择底层的树结构。所以这里可能有一个不好的情况,你应该避免。

    我不确定,KD-tree 是否也需要这些假设!我本以为是,只是指向kd-trees docs,它们仍在使用metric这个词和可用的kd_tree.valid_metrics(尽管这个列表只是sklearn附带的常见指标的一个子集) .

    【讨论】:

      【解决方案2】:

      您的代码中有一些错误。首先是您必须以某种方式将分类数据转换为数字数据。 Sklearn 中的 KNN 分类器尚不支持分类数据。其次,您需要在 sklearn 中使用 make_Scorer() 函数才能使用您的自定义指标。 KNN 中的默认 score 函数返回平均准确度,而不是您指定的指标。你可以阅读更多关于它的信息here。您需要更改数据集才能使用 KNN 分类器的 sklearn 实现。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-07
        • 2012-09-14
        • 1970-01-01
        • 1970-01-01
        • 2020-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多