knn算法中计算距离而不是欧几里得距离的替代有效方法
Posted
技术标签:
【中文标题】knn算法中计算距离而不是欧几里得距离的替代有效方法【英文标题】:alternate efficient way to compute distance instead of eucledian distance in knn algorithm 【发布时间】:2017-10-09 20:44:36 【问题描述】:我已经实现了 knn 算法,这是我计算欧几里得距离的函数。
def euc_dist(self, train, test):
return math.sqrt(((train[0] - test[0]) ** 2) + ((test[1] - train[1]) ** 2))
#
def euc_distance(self, test):
eu_dist = []
for i in range(len(test)):
distance = [self.euc_dist(self.X_train[j], test[i]) for j in range(len(self.X_train))]
eu_dist.insert(i, distance)
return eu_dist
有没有更有效的方法来计算距离??
【问题讨论】:
您有一些示例输入/输出数据吗? 是的,但是训练数据集有 1400 行,测试数据集有 600 行。 【参考方案1】:(1) Python 循环非常慢。学习使用数组计算,例如numpy:
import numpy as np
x = np.array(...)
y = np.array(...)
distances = np.sqrt(np.sum((x-y)**2))
批处理计算可以实现高效的矢量化甚至并行实现。
(2) 如果您不需要绝对距离值(例如,您只比较它们的大小或平均值或以某种方式对结果进行归一化),则省略平方根运算,它非常慢。省略是可能的,因为 sqrt 是一个单调函数(即省略它会保留总顺序)。
squared_distances = np.sum((x-y)**2)
(3) 除了欧几里得之外,可能还有对您的特定问题有意义的距离定义。您可以尝试找到更简单更快的定义,例如一个简单的减法或绝对误差。
error = x-y
absolute_error = np.abs(x-y)
(4) 在所有情况下,尝试和测量(配置文件)。在处理运行时性能优化时不要依赖直觉。
附:上面的代码 sn-ps 并没有准确地映射到您的代码(故意)。学习如何适应它们取决于您。提示:二维数组;)
【讨论】:
【参考方案2】:如果仅用于比较,您可以使用平方距离(只需删除 math.sqrt
- 操作缓慢)。
可能的优化 - 如果 Python 操作 ((train[0] - test[0]) ** 2
使用指数幂,则值得将其更改为简单的乘法
def squared_euc_dist(self, train, test):
x = train[0] - test[0]
y = train[1] - test[1]
return x * x + y * y
【讨论】:
是的,乘法平方的速度大约是使用**
的两倍。如果 OP 需要距离而不是平方距离,那么 math.hypot
值得一看。 OTOH,他们可能应该使用 Numpy。
在这种情况下,平方和 sqrt 都没有解释器中的循环和内存访问开销那么重要。
@Drop 当然可以!这就是我提到 Numpy 的原因。 ;)以上是关于knn算法中计算距离而不是欧几里得距离的替代有效方法的主要内容,如果未能解决你的问题,请参考以下文章