【问题标题】:'KD tree' with custom distance metric具有自定义距离度量的“KD树”
【发布时间】:2018-06-11 01:31:29
【问题描述】:

我想使用带有自定义距离度量的“KDtree”(这是最佳选择。其他“KNN”算法对我的项目来说不是最佳选择)。我在这里检查了一些类似问题的答案,这应该可以工作......但没有。

distance_matrix 按照定义是对称的:

array([[ 1.,  0.,  5.,  5.,  0.,  3.,  2.],
   [ 0.,  1.,  0.,  0.,  0.,  0.,  0.],
   [ 5.,  0.,  1.,  5.,  0.,  2.,  3.],
   [ 5.,  0.,  5.,  1.,  0.,  4.,  4.],
   [ 0.,  0.,  0.,  0.,  1.,  0.,  0.],
   [ 3.,  0.,  2.,  4.,  0.,  1.,  0.],
   [ 2.,  0.,  3.,  4.,  0.,  0.,  1.]])

我知道我的指标不是“正式指标”,但在documentation 中它说我的函数必须是“正式指标”,只有当我使用“球树”时(在User-defined distance: 下)。 这是我的代码:

from sklearn.neighbors import DistanceMetric
def dist(x, y):
    dist = 0
    for elt_x, elt_y in zip(x, y):
        dist += distance_matrix[elt_x, elt_y]
    return dist
X = np.array([[1,0], [1,2], [1,3]])
tree = KDtree(X, metric=dist)

我收到此错误:

NameError
Traceback (most recent call last)   
<ipython-input-27-b5fac7810091> in <module>()
  7     return dist
  8 X = np.array([[1,0], [1,2], [1,3]])
----> 9 tree = KDtree(X, metric=dist)
NameError: name 'KDtree' is not defined

我也试过了:

from sklearn.neighbors import KDTree
def dist(x, y):
    dist = 0
    for elt_x, elt_y in zip(x, y):
        dist += distance_matrix[elt_x, elt_y]
    return dist
X = np.array([[1,0], [1,2], [1,3]])
tree = KDTree(X, metric=lambda a,b: dist(a,b))

我收到此错误:

ValueError
Traceback (most recent call last)   
<ipython-input-27-b5fac7810091> in <module>()
  7     return dist
  8 X = np.array([[1,0], [1,2], [1,3]])
----> 9 tree = KDtree(X, metric=dist)
ValueError: metric PyFuncDistance is not valid for KDTree

我也试过了:

from sklearn.neighbors import NearestNeighbors
nbrs = NearestNeighbors(n_neighbors=1, algorithm='kd_tree',    metric=dist_metric)

我收到以下错误:

ValueError                                Traceback (most recent call last)
<ipython-input-32-c78d02cacb5a> in <module>()
      1 from sklearn.neighbors import NearestNeighbors
----> 2 nbrs = NearestNeighbors(n_neighbors=1, algorithm='kd_tree',     metric=dist_metric)

/usr/local/lib/python3.5/dist-packages/sklearn/neighbors/unsupervised.py    in __init__(self, n_neighbors, radius, algorithm, leaf_size, metric, p, metric_params, n_jobs, **kwargs)
    121                           algorithm=algorithm,
    122                           leaf_size=leaf_size, metric=metric, p=p,
--> 123                           metric_params=metric_params,     n_jobs=n_jobs, **kwargs)

/usr/local/lib/python3.5/dist-packages/sklearn/neighbors/base.py in     _init_params(self, n_neighbors, radius, algorithm, leaf_size, metric, p, metric_params, n_jobs)
    138                 raise ValueError(
    139                     "kd_tree algorithm does not support callable     metric '%s'"
--> 140                     % metric)
     141         elif metric not in VALID_METRICS[alg_check]:
    142             raise ValueError("Metric '%s' not valid for algorithm     '%s'"

ValueError: kd_tree algorithm does not support callable metric '<function     dist_metric at 0x7f58c2b3fd08>'

我尝试了所有其他算法(自动、蛮力、...),但都出现同样的错误。

我必须对向量的元素使用距离矩阵,因为元素是特征代码,5 可以比 3 更接近 1。我需要的是获得前 3 个邻居(从最近到最远排序)。

【问题讨论】:

    标签: python-3.x machine-learning scikit-learn


    【解决方案1】:

    Scikit-learn 的 KDTree 不支持自定义距离指标。 BallTree 确实支持自定义距离度量,但要小心:用户可以确定提供的度量是 actually a valid metric:如果不是,算法会很高兴地返回查询结果,但结果会不正确。

    此外,您应该知道,使用自定义 Python 函数作为指标通常太慢而无法使用,因为在树的遍历中 Python 回调的开销。

    【讨论】:

    • '.. 如果不是,算法将愉快地返回查询结果,但结果将不正确。'这是什么意思?如果指标无效,结果是根据哪个指标计算的?
    • 如果您提供的函数返回的结果不符合有效度量标准:例如,有效度量必须满足三角不等式。 BallTree 无法检查所有可能的输入,但它需要这样做以保证结果正确。有关指标有效性的更多信息,请访问scikit-learn.org/stable/modules/generated/…
    猜你喜欢
    • 1970-01-01
    • 2012-07-09
    • 1970-01-01
    • 2017-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 2012-07-09
    相关资源
    最近更新 更多