我怎样才能将自定义距离指标用于 KNeighboursRegressor



在使用knn回归模型时,我正在尝试应用自己的自定义距离度量函数。我的数据集是名义、有序、数字和二进制类型的字段的混合体

法典:

def cus_distance(array1, array2, **kwargs):
    # calculate the distance, return a float
    pass
knn = neighbors.KNeighborsRegressor(weights='distance', metric=cus_distance)
# train_data is a pandas dataframe obj
knn.fit(train_data.ix[:, fields_list], train_data['time_costs'])

最后一行将导致异常:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-284-04520b227b8a> in <module>()
----> 1 knn.fit(train_data.ix[:, fields_list], train_data['time_costs'])
/usr/local/lib/python2.7/dist-packages/sklearn/neighbors/base.pyc in fit(self, X, y)
    587             X, y = check_arrays(X, y, sparse_format="csr")
    588         self._y = y
--> 589         return self._fit(X)
    590 
    591 
/usr/local/lib/python2.7/dist-packages/sklearn/neighbors/base.pyc in _fit(self, X)
    214             self._tree = BallTree(X, self.leaf_size,
    215                                   metric=self.effective_metric_,
--> 216                                   **self.effective_metric_kwds_)
    217         elif self._fit_method == 'kd_tree':
    218             self._tree = KDTree(X, self.leaf_size,
/usr/local/lib/python2.7/dist-packages/sklearn/neighbors/ball_tree.so in sklearn.neighbors.ball_tree.BinaryTree.__init__ (sklearn/neighbors/ball_tree.c:7983)()
/usr/local/lib/python2.7/dist-packages/numpy/core/numeric.pyc in asarray(a, dtype, order)
    318 
    319     """
--> 320     return array(a, dtype, copy=False, order=order)
    321 
    322 def asanyarray(a, dtype=None, order=None):
ValueError: could not convert string to float: Unknown

我知道这个错误是由我的数据集中的字符串值("未知"是其中之一)引起的。
这让我感到困惑,在我的理解中,函数cus_distance应该处理这些str值,而KNeighborsRegressor只是使用我的函数的返回值。

问:
* 这是在 KNN 回归中使用自定义距离度量的正确方法吗?
* 如果是,为什么我遇到这个例外?
* 如果没有,正确的方法是什么?

球树和 KD 树需要浮点数据,无论使用何种指标。 如果您的数据无法转换为浮点数,那么您将收到此类错误。

>>> import numpy as np
>>> data = [1, "Unknown", 2]
>>> np.asarray(data, dtype=float)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
----> 1 np.asarray(data, dtype=float)
ValueError: could not convert string to float: Unknown

谢谢@jakevdp。
scikit-learn 支持蛮力、球树和 KD 树,根据@jakevdp的回答,我唯一能用的就是蛮力算法,所以我的代码改为:

knn = neighbors.KNeighborsRegressor(weights='distance', metric=cus_distance, algorithm='brute')
knn.fit(train_data.ix[:, fields_list], train_data['time_costs'])

这次不会再引发错误了,谢谢 jakevdp!

但是当我尝试使用这个knn对象时,新的问题来了:

knn.predict(check_data.ix[:, fields_list])

这将在我的问题中导致相同的错误。所以我查看了scikit-learn的源代码,发现这一行导致此错误:

elif callable(metric):
    # Check matrices first (this is usually done by the metric).
    X, Y = check_pairwise_arrays(X, Y)
    n_x, n_y = X.shape[0], Y.shape[0]

函数check_pairwise_arrays将尝试将所有值转换为浮点数,"未知"再次导致错误。

我认为这是一个错误,因为scikit的内置指标不支持数据集的混合类型,我写了一个客户指标函数,但这行仍然强制数据集为纯浮点类型。
正如这一行上面的评论所说,检查工作应该由客户指标完成,所以我只是评论了这一行,重新加载这个模块,我的knn对象现在可以完美地工作:)

ps:我正在努力将此更改推送到 scikit-learn 官方 github 存储库。

相关内容

  • 没有找到相关文章

最新更新