2012-01-12 2 views
1

죄송합니다. 이것이 멍청한 질문 이었지만 목록에서 비슷한 값을 찾으려고했습니다. 사실 좀 더 구체적으로 말하면, 내가 점수를 매길 수있는 방법이 있는지 알고 싶었습니다.유사도에 대한 숫자 목록을 비교하는 알고리즘?

저는 파이썬에서 하나의리스트를 취해서 '=='를 사용하여 똑같은지 확인할 수 있지만, 똑같지는 않지만 대신에 비슷한 값 (또는 아님)을가집니다.

#Batch one 
[1, 10, 20] 
[5, 15, 10] 
[70, 19, 15] 
[50, 40, 20] 


#Batch two 
[46, 19, 8] 
[6, 14, 8] 
[2, 11, 44] 

내가/점수가 서로 얼마나 비슷한에 의해 두 개의 배치를 평가하고자하는 말 :

다음은 예입니다. 모든 숫자를 더하고 총 값으로 비교할 수 있다고 생각했지만, [5,6,1000] [600, 200, 211]이 비슷하게 보이기 때문에 효과가 있다고 생각하지 않습니다. 이 예에서 [5, 15, 10] 및 [6, 14, 8]은 가장 높은 점수를 얻어야합니다.

나는 각 값을 나눠서 생각하고 백분율 차이를 살펴 보았지만 목록이 여러 변수로 커지면 비용이 많이 든다. (결국 각각 800 개 이상의 변수가있는 수천 개의 목록이있을 수있다. 더 나은 접근법.

제안 사항?

+0

많은 수의 큰 목록이있는 경우 numpy 사용을 고려해야합니다. – kennytm

+1

([1, 2, 3], [1, 2, 4]) 또는 ([1, 2, 3], [3, 2, 1]) 어느 쪽이 더 유사한가? 일반적으로 유사성의 척도는 적용에 관한 어떤 것을 반영해야합니다. 초록에서 "더 나은 접근법"을 정의하는 것은 불가능합니다. –

+0

@KennyTM 나는 numpy를 사용할 계획입니다. 바로 지금, 나는 이것을하기 위해 알 고를 알아 내려고 노력하고 있습니다. 나는 theres를 나누는 것보다 더 좋은 방법이라고 생각하지만, 그렇지 않다면 나눠서하는 것이 좋습니다. – Lostsoul

답변

3

Euclidean distance을 사용하면 어떨까요? 지능형리스트에서

:

def distance(lista, listb): 
    return sum((b - a) ** 2 for a,b in zip(lista, listb)) ** .5 

이상의 기입은 :

def distance(lista, listb): 
    runsum = 0.0 
    for a, b in zip(lista, listb): 
     # square the distance of each 
     # then add them back into the sum 
     runsum += (b - a) ** 2 

    # square root it 
    return runsum **.5 
1
a = [1, 10, 20] 
b = [5, 15, 10] 
c = [70, 19, 15] 
d = [50, 40, 20] 

def sim(seqA, seqB): 
    return sum([abs(a - b) for (a, b) in zip(seqA, seqB)]) 


print sim(a, a) # => 0 
print sim(a, b) # => 19 
print sim(a, c) # => 83 
print sim(a, d) # => 79 

낮은 숫자가 더 유사한 의미한다. 0은 동일한 것을 의미합니다.

0

비슷한 값은 (이론상) 비슷한 편차가 있기 때문에 표준 편차를 사용하려고하는 방법에 대해 어떻게 생각하고 있었는지 모르겠습니까? 이 경우

[5, 15, 10] 5 및 표준 편차 얻는다 [6, 14, 18] 내가 제대로 이해 해요 경우 6.1101

1

, 당신은 기본적으로보고 싶어하고 도착 네가 가지고있는 클러스터가 얼마나 단단한가?

데이터를 3D로 포인트 세트로 생각하면 각 클러스터의 확산을 찾으려고합니다.

(즉 당신은 내부적으로 유사한 두 배치는 어떻게 비교할?)

이 경우

가 (최대 속도 일에 사용 NumPy와) 다음과 같은 사항을 고려하십시오

import numpy as np 

def spread(group): 
    return group.var(axis=0).sum() 

group1 = np.array([[1, 10, 20], 
        [5, 15, 10], 
        [70, 19, 15], 
        [50, 40, 20]], dtype=np.float) 
group2 = np.array([[46, 19, 8], 
        [6, 14, 8], 
        [2, 11, 44]], dtype=np.float) 

print spread(group1), spread(group2) 

그래서이 경우 그룹 2는 가장 이며 내부적으로는과 비슷합니다.대신, 당신은 두 그룹은 각각 다른에 얼마나 "가까운"찾는 데 관심이 있다면

, 당신은

legs = group1.mean(axis=0) - group2.mean(axis=0) 
distance = np.sqrt(np.sum(legs**2)) 

가 아니면 발견하고자하는 그 중심 사이의 거리를 비교할 수 가장 가까운 각 그룹 내의 두 "지점"? (어떤 경우에는 거리 매트릭스 (또는 더 많은 포인트를위한보다 효율적인 알고리즘 ...)을 사용합니다).

1

확실한 해결책은 이미 여기에 있습니다. 기본적으로 각 집합에 대해 | x-mean (x) |^p를 계산합니다 (p = 2 인 경우 분산을 계산하는 것과 같습니다).

[1,2,3]과 [101,103,105]의 비율에 대해 언급 했으므로 어느 답변을 선호 하시겠습니까? 대답이 '첫 번째'라면, 결코 신경 쓰지 마라. 두 번째 경우 평균을 사용하여 분산을 정규화해야합니다.

솔루션은 다음과 같습니다. SquareMean = (a^2 + b^2 + c^2)/3, Mean = (a + b + c)/3.

관련 문제