如何使用Python(使用用户定义的距离指标)为图像创建KNN图?

时间:2019-05-16 05:59:16

标签: python scikit-learn knn nearest-neighbor

我想为MNIST数字数据集中的图像创建一个k最近邻图,并使用用户定义的距离度量标准-为简单起见,使用A-B的Frobenius范数。

sklearn.neighbors.kneighbors_graph提供了一个不错的界面,但不允许使用矩阵值的数据,例如当我尝试如下制作图形时:

from torchvision.datasets import MNIST
import sklearn

# Define distance metric for matrices
metric_func = lambda X, Y: norm(X - Y, ord='fro')

data = MNIST('sample_data', train=True, transform=None, target_transform=None, download=True)        

adj_matrix = sklearn.neighbors.kneighbors_graph(
        data.data, 
        n_neighbors=5, 
        mode='connectivity',
        metric=metric_func, 
        p=2, 
        metric_params=None, 
        include_self=False, 
        n_jobs=None
    )

我得到了错误:

ValueError: Found array with dim 3. Estimator expected <= 2.

我可以编写自己的'kneighbors_graph()`方法,但是它可能涉及两次for循环和很多低效率的工作。有没有一种有效的方法可以在Python中创建此图?

2 个答案:

答案 0 :(得分:0)

这很简单,它期望将2D(二维)数组作为X的输入:

https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.kneighbors_graph.html

您提供了吗?检查data.data.shape返回什么?

答案 1 :(得分:0)

展平图像

from sklearn import datasets
from sklearn.neighbors import kneighbors_graph

digits = datasets.load_digits()
images = digits.data.reshape(-1, 8, 8)

distances = kneighbors_graph(images.reshape(-1, 64), 5, mode='distance', include_self=True, metric='euclidean')
distances =  distances.todense()

# Test
i = 11
print ("Actual Image: {0}, Nearest 5 Images: {1}".format(
    digits.target[i], digits.target[distances[i].nonzero()[1]]))

输出: Actual Image: 1, Nearest 5 Images: [1 1 1 1]