Muszę obliczyć podobieństwo cosinusowe między dwiema listami , powiedzmy na przykład lista 1, która jest dataSetI
i lista 2, która jest dataSetII
. Nie mogę używać niczego takiego jak numpy lub moduł statystyk. Muszę używać wspólnych modułów (matematyka itp.) (I możliwie najmniejszej liczby modułów, aby skrócić czas spędzony).
Powiedzmy, że dataSetI
jest [3, 45, 7, 2]
i dataSetII
jest [2, 54, 13, 15]
. Długości list są zawsze równe.
Oczywiście podobieństwo cosinusowe mieści się w przedziale od 0 do 1 i ze względu na to zostanie zaokrąglone do trzeciego lub czwartego miejsca po przecinku za pomocą format(round(cosine, 3))
.
Z góry dziękuję za pomoc.
python
python-3.x
cosine-similarity
Rob Alsod
źródło
źródło
Odpowiedzi:
Powinieneś spróbować SciPy . Zawiera wiele przydatnych naukowych procedur, na przykład „procedury numerycznego obliczania całek, rozwiązywania równań różniczkowych, optymalizacji i rzadkich macierzy”. Używa superszybkiego zoptymalizowanego NumPy do chrupania liczb. Zobacz tutaj, aby zainstalować.
Zauważ, że spatial.distance.cosine oblicza odległość , a nie podobieństwo. Musisz więc odjąć wartość od 1, aby uzyskać podobieństwo .
źródło
inna wersja oparta
numpy
tylkoźródło
np.inner(a, b) / (norm(a) * norm(b))
lepiej jest to zrozumieć.dot
może uzyskać taki sam wynik jakinner
dla wektorów.scipy.spatial.distance.cosine
.cos_sim = (a @ b.T) / (norm(a)*norm(b))
Możesz użyć dokumentów
cosine_similarity
funkcji formularzysklearn.metrics.pairwise
źródło
cosine_similarity([[1, 0, -1]], [[-1,-1, 0]])
Nie sądzę, żeby wydajność miała tu duże znaczenie, ale nie mogę się oprzeć. Funkcja zip () całkowicie ponownie kopiuje oba wektory (właściwie to raczej transpozycja macierzy) tylko po to, aby uzyskać dane w „Pythonowej” kolejności. Byłoby ciekawie zaplanować wdrożenie nakrętek i śrub:
Przechodzi przez szum podobny do C podczas wyodrębniania elementów pojedynczo, ale nie powoduje masowego kopiowania tablicy i wykonuje wszystko, co ważne w pojedynczej pętli for, i wykorzystuje pojedynczy pierwiastek kwadratowy.
ETA: Zaktualizowano wywołanie drukowania, aby było funkcją. (Oryginał to Python 2.7, a nie 3.3. Bieżący działa pod Pythonem 2.7 z rozszerzeniem
from __future__ import print_function
instrukcją.) Dane wyjściowe są takie same, tak czy inaczej.CPYthon 2.7.3 na 3,0 GHz Core 2 Duo:
Tak więc w tym przypadku sposób niepytoniczny jest około 3,6 razy szybszy.
źródło
cosine_measure
w tym przypadku?cosine_measure
icosine_similarity
są po prostu różnymi implementacjami tego samego obliczenia. Równoważne ze skalowaniem obu tablic wejściowych do „wektorów jednostkowych” i obliczeniem iloczynu skalarnego.cosine_measure
to kod wysłany wcześniej przez pkacprzaka. Ten kod był alternatywą dla „innego” całkowicie standardowego rozwiązania Pythona.bez użycia importu
można zastąpić
bez używania numpy.dot () musisz stworzyć własną funkcję kropkową używając funkcji list:
a wtedy jest to tylko prosta kwestia zastosowania wzoru na podobieństwo cosinusowe:
źródło
Zrobiłem test porównawczy na podstawie kilku odpowiedzi w pytaniu i uważa się, że następujący fragment jest najlepszym wyborem:
Wynik zaskakuje mnie, że wdrożenie oparte o
scipy
nie należy do najszybszych. Sprofilowałem i stwierdziłem, że cosinus w scipy zajmuje dużo czasu, aby rzutować wektor z listy Pythona na tablicę numpy.źródło
Możesz go zaokrąglić po obliczeniu:
Jeśli chcesz, żeby była naprawdę krótka, możesz użyć tej jednej linijki:
źródło
[2,3,2,5]
i byciem v2[3,2,2,0]
. Wraca z1.0
, jakby były dokładnie takie same. Masz jakiś pomysł, co jest nie tak?Możesz to zrobić w Pythonie za pomocą prostej funkcji:
źródło
Używając numpy porównaj jedną listę liczb z wieloma listami (macierz):
źródło
Możesz użyć tej prostej funkcji, aby obliczyć podobieństwo cosinusowe:
źródło
Jeśli używasz już PyTorch , powinieneś skorzystać z ich implementacji CosineSimilarity .
Przypuśćmy, że masz
n
dwuwymiarowenumpy.ndarray
s,v1
av2
więc ich kształty są oba(n,)
. Oto jak uzyskać ich podobieństwo cosinusowe:Albo załóżmy, że masz dwa
numpy.ndarray
sw1
iw2
, które mają oba kształty(m, n)
. Poniżej znajduje się lista podobieństw cosinusowych, z których każde jest podobieństwem cosinusowym między wierszem ww1
a odpowiadającym mu wierszem ww2
:źródło
Wszystkie odpowiedzi są świetne w sytuacjach, w których nie możesz używać NumPy. Jeśli możesz, oto inne podejście:
Pamiętaj też o
EPSILON = 1e-07
zabezpieczeniu podziału.źródło