我正在使用中等大小的数据集(shape=(14013L, 46L)
)。
我想用knn来平滑每个样本。
我用以下方式训练我的模型:
NearestNeighbors(n_neighbors, algorithm='ball_tree',
metric=sklearn.metrics.pairwise.cosine_distances)
顺利如下:
def smooth(x,nbrs,data,alpha):
"""
input:
alpha: the smoothing factor
nbrs: trained NearestNeighbors from sklearn
data: the original data
(since NearestNeighbors returns only the index and not the samples)
x: what we want to smooth
output:
smoothed x with its nearest neighbours
"""
distances, indices = nbrs.kneighbors(x)
distances = map(lambda z:abs(-z+1),distances)[0]
norm = sum(distances)
if norm == 0:
"No neighbours were found."
return x
distances = map(lambda z: (1-alpha)*z/norm ,distances)
indices = map(lambda z: data[z],indices)[0]
other = np.array([indices[i] * distances[i] for i in range(len(distances))])
z = x * alpha
z = z.reshape((1,z.shape[0]))
smoothed = sum(np.concatenate((other,z),axis=0))
return smoothed
我的问题:
if
条件)答案 0 :(得分:1)
没有您的数据集和完整代码,很难肯定地说。这就是我的想法。
distances = map(lambda z:abs(-z+1),distances)[0]
norm = sum(distances)
因为您索引地图的结果,所以您应该只获得第一个邻居。 如果 x
实际上是您用来训练的点之一,那么第一个最近的邻居将是...... x
。因为您使用余弦距离,所以该距离恰好是:1。abs(1-1) == 0
。在我提出修正之前,让我们谈谈表现。
关于性能:你到处都在使用map
函数,这是一个内置的Python。 Scikit-learn建立在numpy
之上,旨在比原生Python代码更快地完成数学运算。这就是为什么培训比你的代码快得多的原因。您应该使用numpy算术而不是map
。一个例子:这一行
distances = map(lambda z: (1-alpha)*z/norm ,distances)
应该是这个
distances *= ((1-alpha)/norm)
如果norm
是一个数组,它应该有适当的维度来启动numpy广播规则并完成“正确的事情”,完全用C语言。
好的,因为我建议使用numpy数组(而不是map
和Python列表),我相信在if
语句之前两行的正确之处是删除索引。 (其余的代码也可能被索引破坏;在函数的第二行之后,distances
不是数组或列表,而是标量。)
distances = np.abs( distances-1 )
norm = np.sum(distances)
此外,您不应多次调用smooth()
函数,每个样本一次。您应该在N_samples
N_dimensions==46
个numpy数组中调用它,并相应地调整smooth()
代码。 (例如,NearestNeighbors将返回N_samples
个N_neighbors
数组比返回N_samples
长度为N_samples
的单个数组快得多。)
答案 1 :(得分:1)
首先,为什么要使用Ball树?也许您的指标确实对您有所帮助,但如果情况并非如此,您也可以使用kd树。
我将从理论的角度来处理你的问题。 radius
参数默认设置为1.0。这对于您的数据集来说可能太小了,因为如果我理解正确,这将指定要查询的查询的半径。因此,我建议您在增加此值时运行代码,直到获得一些结果。然后减少它,直到没有结果。再次增加一点,你就拥有了数据集的最佳参数。
一个重要参数是leaf_size
,它实际上影响了查询到达时要检查的点数。此参数的较小值可能会导致执行速度加快,精度较低。
您可能还想查看我的this答案,这解释了速度和准确性之间的权衡,这是在进行最近邻搜索时理解的关键。