문제

나는 많은 객체 모음을 가지고 있으며 그들 사이의 유사점을 알아 내야합니다.

정확히 말하면 : 두 가지 객체를 주어 주면 나는 그들의 비 유사성을 숫자로 계산할 수 있습니다. 메트릭 - 값이 높을수록 유사성이 적고 0은 객체가 동일한 내용을 가지고 있음을 의미합니다. 이 숫자를 계산하는 비용은 작은 물체의 크기에 비례합니다 (각 객체는 주어진 크기가 있습니다).

나는 물체와 비슷한 객체 세트를 신속하게 찾을 수있는 능력이 필요합니다.

정확히 말하면 : 객체 O를 객체 세트에 맵핑하는 데이터 구조를 생성해야합니다. O 객체의 객체를 나열하는 경우 일부는 비 유사성 값 D에 대해 O와 더 이상 O와 더 이상 D와 다르지 않습니다. 배열 또는 링크 된 목록에있었습니다 (아마도 실제로는). 일반적으로 세트는 총 객체 수보다 훨씬 작 으므로이 계산을 수행하는 것이 실제로 가치가 있습니다. 데이터 구조가 고정 된 D를 가정하면 충분하지만 임의의 D에서 작동하는 경우 더 좋습니다.

이 문제를 전에 본 적이 있습니까, 아니면 그와 비슷한 것이 있습니까? 좋은 솔루션은 무엇입니까?

정확히 말해서 : 간단한 솔루션에는 모든 쌍의 물체 사이의 비 유사성을 계산하는 것이 포함되지만 이것은 느린다 - O (n2) 여기서 n은 물체의 수입니다. 복잡성이 낮은 일반적인 솔루션이 있습니까?

도움이 되었습니까?

해결책

메트릭에 대한 자세한 내용을 알지 못하면 말하기는 어렵습니다. 나는 O (n^2) 측면을 제거하기위한 아이디어가 없지만 관련된 상수를 줄이는 방법이있을 수 있습니다. 예를 들어, 유클리드 메트릭 D (P, Q) = SQRT ((P_1-Q_1)^2 + .. + (P_N-Q_N)^2)가있는 경우 거리 D를 제곱하고 부분과 비교할 수 있습니다. (p_i-q_i)^2의 합계와 d^2를 초과하면 중지됩니다.

이것이 실제로 시간을 절약할지 여부는 비교가 요약을 계산하는 데 비교의 비용과이를 수행함으로써 피할 수있는 수집 및 계산 수에 달려 있습니다 (분명히 D가 작을수록 좋습니다).

다른 팁

일부 객체 O를 객체 세트에 맵핑하는 데이터 구조를 생성해야합니다.

하위 운동이 더 커질 때 유사성 계산을 포기하는 것이 가장 빠를 수 있습니다. d. 예를 들어, 유사성이 코사인 또는 Hausdorff 거리를 기반으로하는 경우 쉽게 수행 할 수 있습니다.

 

추신: 이 작업을 수행 할 수없는 경우 문제는 K-Nearest Neighbors 문제와 관련이있을 수 있습니다 (또는 임계 값 이웃에서 가장 가까운 이웃 문제). 모든 거리를 계산하지 않고 가까운 멤버를 찾는 알고리즘 (삼각형 불평등을 사용하는 것)을 찾아야합니다. Wikipedia는 적절한 알고리즘을 탐색하는 데 도움이됩니다.

유사성 측정 값이 전이적 인 경우 객체 A, B, C :에 대해 모든 쌍의 객체에 대한 유사성을 계산할 필요가 없습니다.

similarity(a,c) = similarity(a,b) op similarity(b,c)

어디 op 이진 연산자 (예 : 곱셈 또는 추가)입니다.

솔루션은 문제의 본질에 대한 자세한 내용에 달려 있다고 생각합니다.

  1. 동일한 개체에 대해 유사한 개체를 여러 번 또는 한 번만 찾아야합니까? 여러 번이면 각 쌍의 차이를 한 번 계산 한 다음 객체를 유사한 객체에 연결하여 다시 계산하지 않고 목록을 빠르게 검색 할 수있는 데이터 구조를 작성하는 것이 매우 유용한 성능 향상 일 수 있습니다.

  2. 계산의 특성은 무엇입니까? 한 가지 극단적 인 경우, 차이의 특성이 예를 들어 두 사람의 높이 차이라면 높이별로 목록을 유지하면 비슷한 물체를 매우 빠르게 찾을 수 있습니다. 실제 문제가 그보다 더 복잡하다고 가정하지만, 해당 논리를 따르면 차이가 여러 선형 수량의 합인 경우 다중 차일 배열을 만들 수있는 다음 비슷한 개체의 세트를 개념적으로 상상할 수 있습니다. N- 차원 구체 내에서 (예 : 원, 구체, 하이퍼 스피어 등)는 기준 객체를 중심으로하고 다시 직접 찾습니다. 실제로 반경 계산이 너무 복잡하거나 너무 많은 런타임을 취하면 참조 개체 주위에 n 차원 큐브 (즉, 정사각형, 큐브, Tesseract 등)를 만드는 것이 좋습니다. 그 큐브 안에 "후보자"로 놓인 객체는 후보자에 대한 실제 계산을 수행합니다.

예를 들어, "차이"가 세 가지 속성의 차이의 절대 값, 즉 a1, a2 및 a3의 차이의 합의 합이라고 가정합니다. 3 차원 배열을 생성하고 배열의 각 노드 값을 해당 값으로 객체로 설정할 수 있습니다. 그런 다음 Object O에서 D보다 차이가있는 모든 객체를 찾으려면 다음을 작성할 수 있습니다.

for (x1=o.a1-d;x1<o.a1+d;++x1)
{
  for (x2=o.a2-d;x1<o.a2+d;++x2)
  {
    for (x3=o.a3-d;x1<o.a3+d;++x3)
    {
      if (array[x1][x2][x3]!=null
        && (abs(x1-o.a1)+abs(x2-o.a2)+abs(x3-o.a3)<=d)
        {
          ... found a match ...
        }
    }
  }
}

차이 규칙이 그보다 더 복잡하다고 생각하지만, 규칙의 복잡성과 일치하기 위해 Alrorithm에 정교함을 추가합니다. 요점은 배열을 사용하여 검사해야 할 객체 세트를 제한하는 것입니다.

  1. 계산의 특성에 대해 다시 한 번 : 차이를 구성하는 요소 중 하나 또는 일부 작은 서브 세트가 다른 것보다 더 중요한 경향이 있다면 범위 내에서 빠르게 비교할 수있는 데이터 구조를 만들 수 있습니다. 범위에있는 경우 전체 비교를 수행하십시오. 그렇지 않다면, 당신은 그것을 보지 않습니다.

a를 사용할 수 없습니까? 케이D- 트리?

치수를 정상화하는 데 필요한 경우 (가능하다면) 필요할 수 있습니다. 그 후, 당신은 나무를 채우고 "가장 가까운 n 이웃"검색을 사용하고 어떤 범위 내에서 어떤 객체를 찾으려고 노력하면됩니다.

객체의 예 : 이미지, 문서. 물론 이러한 물체의 원시 표현으로 작업하는 것은 대부분 유용하지 않습니다. 일반적으로 원시 형태를 사전 처리하고 일부 정규화 된 형태로 바꿉니다 (문서의 경우 각 항목이 특정 단어가 나타난 숫자/ %를 나타내는 벡터를 말하면 이미지가 발견 된 시각적 특징을 나타내는 것이 될 수 있습니다. 이미지에서).

d가 고정되어 있고^2 사전 계산이 가능하면 각 객체에 대해 링크 된 목록을 사용하여 그래프 표현을 사용할 수 있습니다. 가장 가까운 이웃 알고리즘을 사용하여 정확도를 희생하면서보다 효율적인 솔루션을 가질 수 있습니다.

우리는 유사성이 전이적이라고 가정 할 수 있습니까? diff(a,c) == diff(a,b) + diff(b,c)? 그렇다면 다음을 시도 할 수 있습니다.

  1. 객체 모음을 정렬하십시오. 객체 유사성 메트릭에 적절한 절대 값이 없으면 하나의 객체를 "0"으로 임의로 선택하고 다른 모든 객체를 해당 객체와 유사하게 정렬 할 수 있습니다.
  2. 유사한 객체를 찾습니다 s 에게 o, 찾기 o 정렬 된 목록에서 Diff가 더 커질 때까지 왼쪽과 오른쪽으로 검색합니다. s.

이것의 장점은 정렬을 한 번 수행 할 수 있고 후속 세트 건물은 세트에있을 멤버 수에 비례한다는 것입니다.

BK-Tree처럼 들립니다. 다음은 작은 예입니다. 당신은 기본적으로 트리를 만들고 유사한 객체 검색에 어떤 분기를 사용해야하는지 확인하고 그렇지 않은지 확인합니다. O(n2)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top