Considere la clase siguiente:sugerencias sobre la manera de aumentar la velocidad de cálculo de la distancia
class SquareErrorDistance(object):
def __init__(self, dataSample):
variance = var(list(dataSample))
if variance == 0:
self._norm = 1.0
else:
self._norm = 1.0/(2 * variance)
def __call__(self, u, v): # u and v are floats
return (u - v) ** 2 * self._norm
lo uso para calcular la distancia entre dos elementos de un vector. Básicamente creo una instancia de esa clase para cada dimensión del vector que usa esta medida de distancia (hay dimensiones que usan otras medidas de distancia). La creación de perfiles revela que la función __call__
de esta clase representa el 90% del tiempo de ejecución de mi implementación knn (¿quién lo hubiera pensado?). No creo que exista una forma pura de Python para acelerar esto, pero ¿tal vez si lo implemento en C?
Si ejecuto un programa simple de C que simplemente calcula distancias para valores aleatorios usando la fórmula anterior, es órdenes de magnitud más rápido que Python. Así que traté de usar ctypes y llamar a una función C que hace el cálculo, pero aparentemente la conversión de los parámetros y los valores de retorno es muy cara, porque el código resultante es mucho más lento.
Podría, por supuesto, implementar todo el knn en C y simplemente llamarlo, pero el problema es que, como he descrito, utilizo diferentes funciones de distancia para algunas dimensiones de los vectores, y traducirlas a C sería demasiado trabajo.
¿Cuáles son mis alternativas? ¿Escribir la función C usando el Python C-API eliminará la sobrecarga? ¿Hay alguna otra forma de acelerar este cálculo?
Sugeriría Cython (Respuesta con la implementación de ejemplo podría aparecer en unos minutos). Supongo que sus algoritmos ya están tan ajustados como sea razonablemente posible. – delnan
@delnan: Ya uso el almacenamiento en caché siempre que sea posible y apropiado, por lo que no veo ninguna forma de guardar los cálculos de distancia. –
Bueno, entonces ... no relacionado, ¿qué es 'dataSample' y' var'? – delnan