4

重要な要素と組み合わせた3Dポイントが多数あります。

各ユーザーには6つのポイントがあります。例:Person Charlieには6つのポイントがあります:(22,44,55)は重要度係数3の最初のポイントです(10,0,0)は重要度係数2.8の2番目のベクトルです6番目のポイントは(100,300,200)で、重要度は0.4です。

私がやりたいのは、他のすべての人を繰り返すことなく、チャーリーに最も似ている人を見つけることです。基本的に、すべてのユーザーに対してこの機能を最小限に抑えます(つまり、そのユーザーからチャーリーに適切な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)は非常に反対であるため、ここではベクトルと余弦定理を使用できません。

何か案は?

4

1 に答える 1

2

まだ回答がないので、少なくとも少しは貢献したいと思いました。私はPythonkdツリーモジュールを使用して、最近傍点をすばやく検索しました。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>

結果から、最も頻繁に一致する「人」を確認するか、重みを検討することができます。または、結果の重要な要素を合計して、最も評価の高い要素を取得することもできます。そうすれば、メアリーが1回だけ一致したが、10の要素があり、フィルが3つ一致したが、合計が5であった場合、メアリーの方が関連性が高い可能性があります。

インデックスを作成するためのより堅牢な関数があることは知っていますが、コレクション内のすべてのポイントを通過する必要があります。

于 2012-05-11T23:39:33.710 に答える