2개의 번호 리스트 간의 코사인 유사성
예를 들어 목록 1은 다음과 같습니다. 예를 들어, 두 목록 사이의 코사인 유사도를 계산합니다.dataSetI
리스트 2는 다음과 같습니다.dataSetII
.
예를 들어dataSetI
이[3, 45, 7, 2]
그리고.dataSetII
이[2, 54, 13, 15]
목록의 길이는 항상 동일합니다.코사인 유사도를 0과 1 사이의 수치로 보고하고 싶습니다.
dataSetI = [3, 45, 7, 2]
dataSetII = [2, 54, 13, 15]
def cosine_similarity(list1, list2):
# How to?
pass
print(cosine_similarity(dataSetI, dataSetII))
당신은 SciPy를 먹어봐야 해요.예를 들어, "숫자로 적분을 계산하고 미분 방정식, 최적화 및 희박한 행렬을 푸는 방법"과 같은 유용한 과학적 루틴이 많이 있습니다.숫자 계산에는 초고속 최적화 NumPy를 사용합니다.인스톨에 대해서는, 여기를 참조해 주세요.
spatial.distance.cosine은 유사도가 아닌 거리를 계산합니다.그래서 1부터 빼야 유사성을 알 수 있어요.
from scipy import spatial
dataSetI = [3, 45, 7, 2]
dataSetII = [2, 54, 13, 15]
result = 1 - spatial.distance.cosine(dataSetI, dataSetII)
기반으로 한 다른 버전numpy
오직.
from numpy import dot
from numpy.linalg import norm
cos_sim = dot(a, b)/(norm(a)*norm(b))
사용할 수 있습니다.cosine_similarity
함수형sklearn.metrics.pairwise
문서
In [23]: from sklearn.metrics.pairwise import cosine_similarity
In [24]: cosine_similarity([[1, 0, -1]], [[-1,-1, 0]])
Out[24]: array([[-0.5]])
여기서 성능은 별로 중요하지 않다고 생각하지만, 거절할 수 없어요.zip() 함수는 데이터를 "Pythonic" 순서로 가져오기 위해 두 벡터를 완전히 다시 복사합니다(실제로 매트릭스 전치).너트와 볼트의 실장 시간을 재는 것은 흥미로울 것입니다.
import math
def cosine_similarity(v1,v2):
"compute cosine similarity of v1 to v2: (v1 dot v2)/{||v1||*||v2||)"
sumxx, sumxy, sumyy = 0, 0, 0
for i in range(len(v1)):
x = v1[i]; y = v2[i]
sumxx += x*x
sumyy += y*y
sumxy += x*y
return sumxy/math.sqrt(sumxx*sumyy)
v1,v2 = [3, 45, 7, 2], [2, 54, 13, 15]
print(v1, v2, cosine_similarity(v1,v2))
Output: [3, 45, 7, 2] [2, 54, 13, 15] 0.972284251712
이 경우 요소를 한 번에 추출할 때 C와 같은 노이즈가 발생하지만 벌크 배열 복사는 이루어지지 않고 중요한 모든 작업을 단일 루프에서 수행하며 단일 제곱근을 사용합니다.
ETA: 함수가 되도록 인쇄 호출이 업데이트되었습니다.(원래는 3.3이 아니라 Python 2.7이었습니다.전류는 Python 2.7에서 실행되며,from __future__ import print_function
를 참조해 주세요.어느 쪽이든 출력은 동일합니다.
3.0에서는 CPYthon 2.7.3GHz Core 2 Duo:
>>> timeit.timeit("cosine_similarity(v1,v2)",setup="from __main__ import cosine_similarity, v1, v2")
2.4261788514654654
>>> timeit.timeit("cosine_measure(v1,v2)",setup="from __main__ import cosine_measure, v1, v2")
8.794677709375264
이 경우 비조음 방식이 약 3.6배 더 빠릅니다.
수입품을 사용하지 않고
math.sqrt(x)
로 대체할 수 있다
x**.5
numpy.dot()을 사용하지 않고 목록 이해를 사용하여 자체 닷 함수를 만들어야 합니다.
def dot(A,B):
return (sum(a*b for a,b in zip(A,B)))
코사인 유사성 공식을 적용하는 간단한 문제입니다.
def cosine_similarity(a,b):
return dot(a,b) / ( (dot(a,a) **.5) * (dot(b,b) ** .5) )
질문의 몇 가지 답변을 바탕으로 벤치마크를 실시했습니다.다음 스니펫이 최선의 선택이라고 생각됩니다.
def dot_product2(v1, v2):
return sum(map(operator.mul, v1, v2))
def vector_cos5(v1, v2):
prod = dot_product2(v1, v2)
len1 = math.sqrt(dot_product2(v1, v1))
len2 = math.sqrt(dot_product2(v2, v2))
return prod / (len1 * len2)
그 결과, 다음과 같은 기반 구현이 이루어졌다는 사실에 놀랐습니다.scipy
가장 빠른 것은 아닙니다.프로파일링을 해보니 코사인 scipy는 python 목록에서 numpy 배열로 벡터를 캐스팅하는 데 시간이 많이 걸린다는 것을 알 수 있습니다.
import math
from itertools import izip
def dot_product(v1, v2):
return sum(map(lambda x: x[0] * x[1], izip(v1, v2)))
def cosine_measure(v1, v2):
prod = dot_product(v1, v2)
len1 = math.sqrt(dot_product(v1, v1))
len2 = math.sqrt(dot_product(v2, v2))
return prod / (len1 * len2)
계산 후 반올림할 수 있습니다.
cosine = format(round(cosine_measure(v1, v2), 3))
매우 짧은 길이의 원라이너를 사용할 수 있습니다.
from math import sqrt
from itertools import izip
def cosine_measure(v1, v2):
return (lambda (x, y, z): x / sqrt(y * z))(reduce(lambda x, y: (x[0] + y[0] * y[1], x[1] + y[0]**2, x[2] + y[1]**2), izip(v1, v2), (0, 0, 0)))
계산할 Python 코드:
- 코사인 거리
- 코사인 유사성
- 각도 거리
- 각도 유사성
import math
from scipy import spatial
def calculate_cosine_distance(a, b):
cosine_distance = float(spatial.distance.cosine(a, b))
return cosine_distance
def calculate_cosine_similarity(a, b):
cosine_similarity = 1 - calculate_cosine_distance(a, b)
return cosine_similarity
def calculate_angular_distance(a, b):
cosine_similarity = calculate_cosine_similarity(a, b)
angular_distance = math.acos(cosine_similarity) / math.pi
return angular_distance
def calculate_angular_similarity(a, b):
angular_similarity = 1 - calculate_angular_distance(a, b)
return angular_similarity
- https://en.wikipedia.org/wiki/Cosine_similarity
- https://gist.github.com/amir-saniyan/e102de09b01c4ed1632e3d1a1a1cbf64
이 간단한 함수를 사용하여 코사인 유사도를 계산할 수 있습니다.
def cosine_similarity(a, b):
return sum([i*j for i,j in zip(a, b)])/(math.sqrt(sum([i*i for i in a]))* math.sqrt(sum([i*i for i in b])))
Python에서는 간단한 함수를 사용하여 이 작업을 수행할 수 있습니다.
def get_cosine(text1, text2):
vec1 = text1
vec2 = text2
intersection = set(vec1.keys()) & set(vec2.keys())
numerator = sum([vec1[x] * vec2[x] for x in intersection])
sum1 = sum([vec1[x]**2 for x in vec1.keys()])
sum2 = sum([vec2[x]**2 for x in vec2.keys()])
denominator = math.sqrt(sum1) * math.sqrt(sum2)
if not denominator:
return 0.0
else:
return round(float(numerator) / denominator, 3)
dataSet1 = [3, 45, 7, 2]
dataSet2 = [2, 54, 13, 15]
get_cosine(dataSet1, dataSet2)
numpy를 사용하여 하나의 숫자 목록을 여러 목록(행렬)과 비교합니다.
def cosine_similarity(vector,matrix):
return ( np.sum(vector*matrix,axis=1) / ( np.sqrt(np.sum(matrix**2,axis=1)) * np.sqrt(np.sum(vector**2)) ) )[::-1]
이미 PyTorch를 사용하고 있다면 CosineSimilarity를 구현해야 합니다.
를 들어, 두 개의 어리다이가 가정해봅시다.n
원numpy.ndarray
s,v1
★★★★★★★★★★★★★★★★★」v2
ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ.(n,)
코사인 유사도를 구하는 방법은 다음과 같습니다.
import torch
import torch.nn as nn
cos = nn.CosineSimilarity()
cos(torch.tensor([v1]), torch.tensor([v2])).item()
두 개 .numpy.ndarray
s w1
★★★★★★★★★★★★★★★★★」w2
다 (m, n)
입니다. 코사인 유사도는 에 있는 행각 코사인 유사도는, 의 행간의 코사인 유사도입니다.w1
의 이 표시됩니다.w2
:
cos(torch.tensor(w1), torch.tensor(w2)).tolist()
또 다른 버전에서는 벡터 리스트와 쿼리 벡터 리스트가 있고 쿼리 벡터와 리스트 내의 모든 벡터의 코사인 유사도를 계산하려면 다음 방법으로 한번에 실행할 수 있습니다.
>>> import numpy as np
>>> A # list of vectors, shape -> m x n
array([[ 3, 45, 7, 2],
[ 1, 23, 3, 4]])
>>> B # query vector, shape -> 1 x n
array([ 2, 54, 13, 15])
>>> similarity_scores = A.dot(B)/ (np.linalg.norm(A, axis=1) * np.linalg.norm(B))
>>> similarity_scores
array([0.97228425, 0.99026919])
여기에서는 매트릭스에도 사용할 수 있는 구현이 있습니다.동작은 sklearn cosine 유사성과 동일합니다.
def cosine_similarity(a, b):
return np.divide(
np.dot(a, b.T),
np.linalg.norm(
a,
axis=1,
keepdims=True
)
@
np.linalg.norm(
b,
axis=1,
keepdims=True
).T
)
우리는 간단한 수학 방정식으로 코사인 유사도를 쉽게 계산할 수 있다.Cosine_silarity = 1-(벡터의 점곱/(벡터의 노름곱)).도트 곱과 노름의 계산을 위해 각각 두 가지 함수를 정의할 수 있습니다.
def dprod(a,b):
sum=0
for i in range(len(a)):
sum+=a[i]*b[i]
return sum
def norm(a):
norm=0
for i in range(len(a)):
norm+=a[i]**2
return norm**0.5
cosine_a_b = 1-(dprod(a,b)/(norm(a)*norm(b)))
SciPy를 사용할 수 있습니다(가장 쉬운 방법).
from scipy import spatial
dataSetI = [3, 45, 7, 2]
dataSetII = [2, 54, 13, 15]
print(1 - spatial.distance.cosine(dataSetI, dataSetII))
:spatial.distance.cosine()
. gives 、 1 、 1 、 gives 。
이 솔루션을 찾는 또 다른 방법은 길이가 다른 목록의 가능성까지 고려하는 함수를 직접 작성하는 것입니다.
def cosineSimilarity(v1, v2):
scalarProduct = moduloV1 = moduloV2 = 0
if len(v1) > len(v2):
v2.extend(0 for _ in range(len(v1) - len(v2)))
else:
v2.extend(0 for _ in range(len(v2) - len(v1)))
for i in range(len(v1)):
scalarProduct += v1[i] * v2[i]
moduloV1 += v1[i] * v1[i]
moduloV2 += v2[i] * v2[i]
return round(scalarProduct/(math.sqrt(moduloV1) * math.sqrt(moduloV2)), 3)
dataSetI = [3, 45, 7, 2]
dataSetII = [2, 54, 13, 15]
print(cosineSimilarity(dataSetI, dataSetII))
모든 답변은 NumPy를 사용할 수 없는 상황에 적합합니다.가능한 경우는, 다른 어프로치를 다음에 나타냅니다.
def cosine(x, y):
dot_products = np.dot(x, y.T)
norm_products = np.linalg.norm(x) * np.linalg.norm(y)
return dot_products / (norm_products + EPSILON)
,, 의해주의 도 염두에 두세요.EPSILON = 1e-07
사단을 안전하게 하기 위해서요
언급URL : https://stackoverflow.com/questions/18424228/cosine-similarity-between-2-number-lists
'source' 카테고리의 다른 글
SELECT INTO 및 "미등록 변수" 오류 (0) | 2022.11.13 |
---|---|
JavaScript 콘솔에 jQuery 포함 (0) | 2022.11.13 |
문자의 ASCII 값을 가져오는 방법 (0) | 2022.11.13 |
잘못된 종류의 값을 보유한 키에 대한 WORLTYPE 작업 php (0) | 2022.11.13 |
숫자를 어떻게 반올림합니까? (0) | 2022.11.13 |