Preciso calcular a semelhança do cosseno entre duas listas , digamos, por exemplo, a lista 1 que é dataSetI
e a lista 2 que é dataSetII
. Não posso usar nada como o numpy ou um módulo de estatísticas. Devo usar módulos comuns (matemática, etc) (e o mínimo de módulos possível, para reduzir o tempo gasto).
Digamos que dataSetI
é [3, 45, 7, 2]
e dataSetII
é [2, 54, 13, 15]
. O comprimento das listas é sempre igual.
Claro, a semelhança do cosseno está entre 0 e 1 e , por causa disso, será arredondada para a terceira ou quarta casa decimal com format(round(cosine, 3))
.
Muito obrigado desde já por ajudar.
python
python-3.x
cosine-similarity
Rob Alsod
fonte
fonte
Respostas:
Você deve tentar SciPy . Ele tem um monte de rotinas científicas úteis, por exemplo, "rotinas para calcular integrais numericamente, resolver equações diferenciais, otimização e matrizes esparsas". Ele usa o NumPy super rápido otimizado para processamento de números. Veja aqui para instalar.
Observe que spatial.distance.cosine calcula a distância e não a similaridade. Portanto, você deve subtrair o valor de 1 para obter a similaridade .
fonte
outra versão baseada
numpy
apenas emfonte
np.inner(a, b) / (norm(a) * norm(b))
seja melhor entender.dot
pode obter o mesmo resultado queinner
para vetores.scipy.spatial.distance.cosine
.cos_sim = (a @ b.T) / (norm(a)*norm(b))
Você pode usar documentos de
cosine_similarity
formulário de funçãosklearn.metrics.pairwise
fonte
cosine_similarity([[1, 0, -1]], [[-1,-1, 0]])
Acho que o desempenho não importa muito aqui, mas não consigo resistir. A função zip () copia completamente os dois vetores (mais como uma transposição de matriz, na verdade) apenas para obter os dados na ordem "Pythônica". Seria interessante cronometrar a implementação de porcas e parafusos:
Isso passa pelo ruído semelhante ao C de extrair elementos um por vez, mas não faz nenhuma cópia de array em massa e faz tudo que é importante em um único loop for e usa uma única raiz quadrada.
ETA: chamada de impressão atualizada para ser uma função. (O original era Python 2.7, não 3.3. O atual é executado no Python 2.7 com uma
from __future__ import print_function
instrução.) A saída é a mesma, de qualquer maneira.CPYthon 2.7.3 em 3.0 GHz Core 2 Duo:
Portanto, a forma impotônica é cerca de 3,6 vezes mais rápida neste caso.
fonte
cosine_measure
neste caso?cosine_measure
ecosine_similarity
são simplesmente implementações diferentes do mesmo cálculo. Equivalente a dimensionar ambas as matrizes de entrada para "vetores unitários" e obter o produto escalar.cosine_measure
é o código postado anteriormente por pkacprzak. Esse código era uma alternativa à "outra" solução Python padrão.sem usar quaisquer importações
pode ser substituído por
sem usar numpy.dot (), você deve criar sua própria função de ponto usando compreensão de lista:
e então é apenas uma simples questão de aplicar a fórmula de similaridade de cosseno:
fonte
Fiz um benchmark com base em várias respostas à pergunta e o seguinte snippet é considerado a melhor escolha:
O resultado me surpreende que a implementação baseada em
scipy
não seja a mais rápida. Fiz o perfil e descobri que o cosseno em scipy leva muito tempo para lançar um vetor da lista python para a matriz numpy.fonte
Você pode arredondá-lo após o cálculo:
Se você quiser realmente curto, você pode usar este one-liner:
fonte
[2,3,2,5]
e v2 sendo[3,2,2,0]
. Ele retorna com1.0
, como se fossem exatamente iguais. Alguma idéia do que está errado?Você pode fazer isso em Python usando uma função simples:
fonte
Usando numpy compare uma lista de números com várias listas (matriz):
fonte
Você pode usar esta função simples para calcular a semelhança do cosseno:
fonte
Se acontecer de você já estar usando o PyTorch , você deve ir com a implementação do CosineSimilarity .
Suponha que você tenha s
n
bidimensionais e , ou seja, suas formas são ambas . Veja como você consegue sua similaridade de cosseno:numpy.ndarray
v1
v2
(n,)
Ou suponha que você tenha dois
numpy.ndarray
sw1
ew2
, cujas formas são ambos(m, n)
. O seguinte fornece uma lista de semelhanças de cosseno, cada uma sendo a semelhança de cosseno entre uma linha emw1
e a linha correspondente emw2
:fonte
Todas as respostas são ótimas para situações em que você não pode usar o NumPy. Se você puder, aqui está outra abordagem:
Lembre-
EPSILON = 1e-07
se também de garantir a divisão.fonte