gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 09:56:46 25 4
gpt4 key购买 nike

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

knn = KNeighborsClassifier(n_neighbors=1,weights='distance',metric='pyfunc',func=dtw_dist)

问题是 KNeighborsClassifier 似乎不支持我的训练数据。它们是时间序列,因此它们是不同大小的列表。当我尝试使用 fit 方法 (knn.fit(X,Y)) 时,KNeighborsClassifier 给出此错误消息:

ValueError: data type not understood

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

有什么想法吗?

最佳答案

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

  1. 预先计算距离(KNeighborsClassifier 似乎不直接支持,但其他聚类算法可以,例如 Spectral Clustering)。
  2. 使用 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 时间序列):

  1. 将距离预先计算为 (N, N)距离矩阵D
  2. 创建 (N, 1)矩阵只是 [0, N) 之间的范围(即距离矩阵中序列的索引)
  3. 创建距离函数 wrapper
  4. 使用这个wrapper作为距离函数。

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]

好吧,我希望它是清楚的。

完整示例

#!/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]

关于python - KNeighborsClassifier 是否比较不同大小的列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24592641/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com