Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python KNeighborsClassifier是否比较不同大小的列表?_Python_Machine Learning_Time Series_Scikit Learn_Knn - Fatal编程技术网

Python KNeighborsClassifier是否比较不同大小的列表?

Python KNeighborsClassifier是否比较不同大小的列表?,python,machine-learning,time-series,scikit-learn,knn,Python,Machine Learning,Time Series,Scikit Learn,Knn,我必须使用Scikit Lean的KNeighborsClassifier,使用Python中的用户定义函数来比较时间序列 knn = KNeighborsClassifier(n_neighbors=1,weights='distance',metric='pyfunc',func=dtw_dist) 问题是Kneighbors分类器似乎不支持我的训练数据。它们是时间序列,所以它们是大小不同的列表。当我尝试使用fit方法(knn.fit(X,Y))时,KNeighborsClassifier

我必须使用Scikit Lean的KNeighborsClassifier,使用Python中的用户定义函数来比较时间序列

knn = KNeighborsClassifier(n_neighbors=1,weights='distance',metric='pyfunc',func=dtw_dist)
问题是Kneighbors分类器似乎不支持我的训练数据。它们是时间序列,所以它们是大小不同的列表。当我尝试使用
fit
方法(
knn.fit(X,Y)
)时,KNeighborsClassifier会给我此错误消息:

似乎KNeighborsClassifier只支持相同大小的训练集(只接受具有相同长度的时间序列,但这不是我的情况),但我的老师告诉我使用KNeighborsClassifier。所以我不知道该怎么办

有什么想法吗?

据我所知,有两个(或一个…)选项:

  • 预计算距离(KNeighborsClassifier似乎不直接支持,其他聚类算法也支持,例如)
  • 使用
    NaN
    s将数据转换为正方形,并在自定义距离函数中相应地处理这些数据
  • 使用
    NaN
    s“平方”数据 因此,选择2是正确的。 假设我们有以下数据,其中每一行代表一个时间序列:

    import numpy as np
    
    series = [
        [1,2,3,4],
        [1,2,3],
        [1],
        [1,2,3,4,5,6,7,8]
    ]
    
    我们只需通过添加NAN使数据成为方形:

    def make_square(jagged):
        # Careful: this mutates the series list of list
        max_cols = max(map(len, jagged))
        for row in jagged:
            row.extend([None] * (max_cols - len(row)))
        return np.array(jagged, dtype=np.float)
    
    
    make_square(series)
    array([[  1.,   2.,   3.,   4.,  nan,  nan,  nan,  nan],
           [  1.,   2.,   3.,  nan,  nan,  nan,  nan,  nan],
           [  1.,  nan,  nan,  nan,  nan,  nan,  nan,  nan],
           [  1.,   2.,   3.,   4.,   5.,   6.,   7.,   8.]])
    
    现在数据“适合”算法。您只需调整距离函数以考虑
    NaN
    s

    预计算并使用缓存函数 哦,我们可能也可以做选项1(假设您有
    N
    时间序列):

  • 将距离预计算到a
    (N,N)
    距离矩阵
    D
  • 创建一个介于
    [0,N)
    之间的
    (N,1)
    矩阵(即距离矩阵中序列的索引)
  • 创建距离函数
    wrapper
  • 使用此
    包装器
    作为距离函数
  • 包装器
    函数:

    def wrapper(row1, row2):
        # might have to fiddle a bit here, but i think this retrieves the indices.
        i1, i2 = row1[0], row2[0]
        return D[i1, i2]
    
    好的,我希望它清楚

    完整示例
    你能用失败的随机数据写一个例子吗?哪一个可以复制和粘贴?否则你的问题就不够清楚了。你说的“相同大小的训练集”是什么意思?每个样本都是不同长度的时间序列?这很容易出错,但由于我不知道knn的内部结构,因此有可能使用自定义距离函数来恢复这种情况。@Eikenberg一个例子可能是当用户41047告诉我使用NaNs时,他使用的时间序列。是的,我的时间序列与ea的长度不同ch other.问题是我已经在使用一个自定义距离函数(dtw_dist)。该函数支持不同长度的列表,但KNN甚至不能使用它。我想的更多的是一个示例,它是复制+粘贴的,包含虚假数据,如@user41047的答案,以及一个虚假的距离函数(或您真正的
    dtw_dist
    ),它将无法给出与您收到的相同的错误消息。@eickenberg,无论我使用的是标准函数还是我的dtw_dist。如果我使用@user41047示例或任何其他列表长度不同的示例,我都会收到此错误消息。如果我使用类似于
    series=[[1,2,3,4],[1,2,3,4],[1,2,3,4],[1,2,3,4]的东西,一切都会正常工作
    系列=[[1,2,3],[2,3,4],[3,4,5],[4,5,6]]
    。我希望这一次我能说清楚。我理解你的问题。如果你提供了一个独立的代码块,它会中断,那么平均来说,可能会有更多的人倾向于尝试一下,也许会想出一些有趣的方法来解决你的问题。现在看来,这似乎是答案下面的注释看起来像一条路径。填充NaN是一个非常糟糕的主意,因为大多数scikit学习估计器都会被NaN阻塞。(也就是说,填充一个神奇的值是正确的方法。-1可能是一个选项。)@user41047当你告诉我预计算并使用缓存函数时,你是想说我应该更改“权重”或“度量”吗paramether?当我说我将“metrics”设置为“pyfunc”并将“function”设置为“dtw_dist”时,我已经使用了一个自定义函数。dtw_dist支持不同长度的列表,但KNeighborsClassifier给出了同样的错误…@larsmans我将尝试使用-1作为一个神奇的值。让我们看看它是否有效。您应该使用
    dtw_dist
    来创建
    (N,N)
    距离矩阵
    D
    。然后创建另一个矩阵
    (N,1)
    只包含索引值。这个新矩阵现在是fit方法的
    X
    。传递给
    KNN
    的距离函数应该是提供的
    包装器,而不是
    dtw\u dist
    。使用
    -1
    作为魔术值可能更容易。
    def wrapper(row1, row2):
        # might have to fiddle a bit here, but i think this retrieves the indices.
        i1, i2 = row1[0], row2[0]
        return D[i1, i2]
    
    #!/usr/bin/env python2.7
    # encoding: utf-8
    '''
    '''
    from mlpy import dtw_std # I dont know if you are using this one: it doesnt matter.
    from sklearn.neighbors import KNeighborsClassifier
    import numpy as np
    
    # Example data
    series = [
        [1, 2, 3, 4],
        [1, 2, 3, 4],
        [1, 2, 3, 4],
        [1, 2, 3],
    
        [1],
    
        [1, 2, 3, 4, 5, 6, 7, 8],
        [1, 2, 5, 6, 7, 8],
        [1, 2, 4, 5, 6, 7, 8],
    ]
    
    # I dont know.. these seemed to make sense to me!
    y = np.array([
        0,
        0,
        0,
        0,
    
        1,
    
        2,
        2,
        2
    ])
    
    # Compute the distance matrix
    N = len(series)
    D = np.zeros((N, N))
    
    for i in range(N):
        for j in range(i+1, N):
            D[i, j] = dtw_std(series[i], series[j])
            D[j, i] = D[i, j]
    
    print D
    
    # Create the fake data matrix: just the indices of the timeseries
    X = np.arange(N).reshape((N, 1))
    
    
    # Create the wrapper function that returns the correct distance
    def wrapper(row1, row2):
        # cast to int to prevent warnings: sklearn converts our integer indices to floats.
        i1, i2 = int(row1[0]), int(row2[0])
        return D[i1, i2]
    
    # Only the ball_tree algorith seems to accept a custom function
    knn = KNeighborsClassifier(weights='distance', algorithm='ball_tree', metric='pyfunc', func=wrapper)
    knn.fit(X, y)
    print knn.kneighbors(X[0])
    # (array([[ 0.,  0.,  0.,  1.,  6.]]), array([[1, 2, 0, 3, 4]]))
    print knn.kneighbors(X[0])
    # (array([[ 0.,  0.,  0.,  1.,  6.]]), array([[1, 2, 0, 3, 4]]))
    
    print knn.predict(X)
    # [0 0 0 0 1 2 2 2]