2012-05-11 1 views
4

중요한 요소와 많은 수의 3d 점이 있습니다.3D 포인트 및 중요도 팩터를 기반으로 빠른 사용자 조회를위한 적절한 데이터 구조 또는 색인이 필요합니다.

각 사용자의 점수는 6 점입니다. 예를 들어 Person Charlie는 6 점을 가지고 있습니다. (22,44,55)는 중요도가 3 인 첫 번째 점이고 (10,0,0)은 중요도가 2.8 인 그의 두 번째 벡터입니다 중요도 계수 0.4 인 (100,300,200)의 여섯 번째 포인트.

내가 뭘하고 싶은지는 다른 모든 사람을 반복하지 않고 Charlie와 가장 유사한 사람을 찾는 것입니다. 기본적으로 모든 사용자에 대해이 기능을 최소화 (즉, 찰리 해당 사용자의 권리 6 점까지 일치) : 온통 가장 낮은로 하나를 선택하여 찰리 가장 유사한 사용자를 찾는

pythagoras(point, point2) * max(importance_factor, importance_factor2) * (abs(importance_factor - importance_factor2) + 1) 

그리고 다음을 비용. 지금 코드를 멍청한 방법으로 작성했습니다 (많은 루프를 수행하여)하지만 여러 포인트와 중요도 요소가 있다는 사실을 적절히 처리 할 수있는 방법을 찾고 있습니다.

공간적 색인을 조사하기 시작했는데 여러 점이 있기 때문에 작동하지 않을 것이라고 생각하지만 점을 더 높은 차원의 점으로 풀 수 있습니까? 그래서 3 차원에서 6 점 대신에 18 차원에서 1 점을 가질 수 있습니까? 여전히 중요성 요인을 처리 할 수는 없지만 아무것도없이 중요합니다.

불행히도 (1,1,1) 및 (400,400,400)은 이므로 매우 불리하게도 벡터와 코사인을 사용할 수 없습니다. 반대 항목.

아이디어가 있으십니까?

+1

저는 알고리즘의 전문가는 아니지만 데이터 세트의 범위를 좁히기 위해 거리 나 무게에 우선 순위를 두어야 할 필요가 있다는 뜻입니까? 말하듯이 먼저 N을 가장 가까운 것으로 생각하고 무게를 분류합니까? 내게는 그 기능을 고려하기 위해 모든 조합을 테스트해야 할 것 같습니다. – jdi

+0

이 지점에서 다른 지점까지의 유클리드 거리를 계산할 수 있습니다. "중요도 요인"은 별도의 차원입니까, 아니면 기존 벡터의 무게입니까? –

+0

기존 포인트에 단지 무게. – zachaysan

답변

1

아직 답을 얻지 못했기 때문에 나는 적어도 생각에 조금이라도 기여할 것이라고 생각했습니다. 가장 가까운 이웃 점을 빠르게 검색하기 위해 파이썬 k-d 트리 모듈을 사용했습니다 :
http://code.google.com/p/python-kdtree/downloads/detail?name=kdtree.py
동일한 크기 인 한 임의의 포인트 길이를 사용합니다.

"중요도"의 가중치 적용 방법을 잘 모르겠지만 kdtree 모듈을 사용하여 각 지점에 가장 가까운 "사람"을 얻는 방법에 대한 브레인 스톰입니다. 주어진 사람의 세트 :

import numpy 
from kdtree import KDTree 
from itertools import chain 

class PersonPoint(object): 

    def __init__(self, person, point, factor): 
     self.person = person 
     self.point = point 
     self.factor = factor 

    def __repr__(self): 
     return '<%s: %s, %0.2f>' % (self.person, 
      ['%0.2f' % p for p in self.point], self.factor) 

    def __iter__(self): 
     return self.point 

    def __len__(self): 
     return len(self.point) 

    def __getitem__(self, i): 
     return self.point[i] 


people = {} 
for name in ('bill', 'john', 'mary', 'jenny', 'phil', 'george'): 
    factors = numpy.random.rand(6) 
    points = numpy.random.rand(6, 3).tolist() 
    people[name] = [PersonPoint(name, p, f) for p,f in zip(points, factors)] 

bill_points = people['bill'] 
others = list(chain(*[people[name] for name in people if name != 'bill'])) 

tree = KDTree.construct_from_data(others) 

for point in bill_points: 
    # t=1 means only return the 1 closest. 
    # You could set it higher to return more. 
    print point, "=>", tree.query(point, t=1)[0] 

결과 :

<bill: ['0.22', '0.64', '0.14'], 0.07> => 
    <phil: ['0.23', '0.54', '0.11'], 0.90> 

<bill: ['0.31', '0.87', '0.16'], 0.88> => 
    <phil: ['0.36', '0.80', '0.14'], 0.40> 

<bill: ['0.34', '0.64', '0.25'], 0.65> => 
    <jenny: ['0.29', '0.77', '0.28'], 0.40> 

<bill: ['0.24', '0.90', '0.23'], 0.53> => 
    <jenny: ['0.29', '0.77', '0.28'], 0.40> 

<bill: ['0.50', '0.69', '0.06'], 0.68> => 
    <phil: ['0.36', '0.80', '0.14'], 0.40> 

<bill: ['0.13', '0.67', '0.93'], 0.54> => 
    <jenny: ['0.05', '0.62', '0.94'], 0.84> 

나는 결과로 생각, 당신은 가장 많이 일치하는 "사람"보거나 다음 가중치를 고려할 수 있습니다. 또는 결과에서 중요한 요소를 합산 한 다음 가장 높은 평가를받을 수도 있습니다. 그렇게하면 메리가 한 번만 일치했지만 10 점이 맞으면 필은 3 점이 일치했지만 5 점 만 합산하면 메리가 더 관련성이있을 수 있습니다.

인덱스를 만드는 데 더 강력한 기능이 있지만 컬렉션의 모든 지점을 통과해야한다는 것을 알고 있습니다.