Если вы можете использовать SciPy, вы можете использовать cosine
от spatial.distance
:
http://docs.scipy.org/doc/scipy/reference/spatial.distance.html
Если вы не можете использовать SciPy, вы можете попытаться получить небольшое ускорение, переписав свой Python (РЕДАКТИРОВАТЬ: но это не сработало так, как я думал, см. Ниже).
from itertools import izip
from math import sqrt
def cosine_distance(a, b):
if len(a) != len(b):
raise ValueError, "a and b must be same length"
numerator = sum(tup[0] * tup[1] for tup in izip(a,b))
denoma = sum(avalue ** 2 for avalue in a)
denomb = sum(bvalue ** 2 for bvalue in b)
result = 1 - numerator / (sqrt(denoma)*sqrt(denomb))
return result
Лучше вызывать исключение, когда длины a и b не совпадают.
Используя выражения генератора внутри вызовов к sum()
, вы можете вычислить свои значения, при этом большая часть работы выполняется кодом C внутри Python. Это должно быть быстрее, чем при использовании цикла for
.
Я не рассчитал это, поэтому не могу догадаться, насколько быстрее это может быть. Но код SciPy почти наверняка написан на C или C ++, и он должен быть настолько быстрым, насколько это возможно.
Если вы занимаетесь биоинформатикой в Python, вам все равно стоит использовать SciPy.
РЕДАКТИРОВАТЬ: Дариус Бэкон рассчитал мой код и нашел его медленнее. Итак, я рассчитал свой код и ... да, он медленнее. Урок для всех: когда вы пытаетесь ускорить процесс, не угадывайте, измеряйте.
Я озадачен тем, почему моя попытка больше работать над внутренними компонентами C в Python медленнее. Я попробовал это для списков длиной 1000, и это было все еще медленнее.
Я не могу больше тратить время на умные попытки взломать Python. Если вам нужна большая скорость, я предлагаю вам попробовать SciPy.
РЕДАКТИРОВАТЬ: Я только что проверил вручную, без времени. Я считаю, что для краткости a и b старый код работает быстрее; для длинных a и b новый код работает быстрее; в обоих случаях разница не велика. (Теперь мне интересно, могу ли я доверять timeit на моем компьютере с Windows; я хочу попробовать этот тест снова в Linux.) Я бы не стал менять рабочий код, чтобы попытаться ускорить его. И еще раз призываю вас попробовать SciPy. : -)