2011-02-06 4 views
3

私は、ユーザーベースのアイテム推奨のためにPHP経由でSlope Oneアルゴリズムを実装しようとしています。これを行うには、OpenSlopeOneライブラリを使用しています。私が抱えている問題は、生成された推奨事項がユーザーにとってまったく関連していないということです。Slope 1つの実装では、貧弱な推奨事項が提供されています

現在、私はuser_ratingsとslope_oneの2つのテーブルを持っています。 user_ratingsテーブルはかなり簡単です。その特定のユーザー(user_id、item_idおよびuser_item_rating)によって指定されたアイテムごとの評価が含まれます。 slope_oneテーブルは、OpenSlopeOneのデフォルトスキーマ(item_id1、item_id2、timesおよびrating)に従います。

slope_oneテーブルには、次のSQLプロシージャ使用して移入さ:

CREATE PROCEDURE `slope_one`() 
begin      
    DECLARE tmp_item_id int; 
    DECLARE done int default 0;      
    DECLARE mycursor CURSOR FOR select distinct item_id from user_ratings; 
    DECLARE CONTINUE HANDLER FOR NOT FOUND set done=1; 
    open mycursor; 
    while (!done) do 
     fetch mycursor into tmp_item_id; 
     if (!done) then 
      insert into slope_one (select a.item_id as item_id1,b.item_id as item_id2,count(*) as times, sum(a.rating-b.rating) as rating from user_ratings a, user_ratings b where a.item_id = tmp_item_id and b.item_id != a.item_id and a.user_id=b.user_id group by a.item_id,b.item_id); 
     end if; 
    END while; 
    close mycursor; 
end 

を与えられたユーザーに最も関連する勧告をフェッチするために、私は次のクエリを実行します。

SELECT 
    item.* 
FROM 
    slope_one s, 
    user_ratings u, 
    item 
WHERE 
    u.user_id = '{USER_ID}' AND 
    s.item_id1 = u.item_id AND 
    s.item_id2 != u.item_id AND 
    item.id = s.item_id2 
GROUP BY 
    s.item_id2 
ORDER BY 
    SUM(u.rating * s.times - s.rating)/SUM(s.times) DESC 
LIMIT 20 

先に述べたようにこれは動作していないようです。私はかなり大きなデータセット(10,000 +推奨)で作業していますが、私はどんな形式の相関も見ていません。実際、多くのリコメンデーションは、全く異なる項目レーティングであっても、ユーザーにとっては同じであるようです。

答えて

5

(はい、私は意図的に別の答えを与えている。)

を参照してください他の答えは、すべてのこれらのアルゴリズムは、長所と短所を持っているし、いくつかの日ではなく、他人にうまくやっていることです。しかし、以前は坂道についても同様の観察をしていましたが、実装を最初に提案したDaniel Lemireからのコメントもありました。

データが100%密集するにつれて、各ユーザーがすべてのアイテムを評価します。アイテムAとアイテムB間の格付け差は、格付け差異の平均(r_uB - r_uA)のすべての共同評価ユーザuに対する平均です。しかし、すべてのユーザーが評価しているので、これはBの平均格付け(全ユーザー以上)に、A:平均(r_uB) - 平均(r_uA)の平均格付けを引いた値に簡単に近づきます。その平均(B)と平均(A)を容易に呼んでください。

全体的に平均レーティングが最も高いアイテムPを想像してください。 AとPとの間の差は、Aと他のいずれかのBとの差よりも大きくなる。 (平均(P) - 平均(A))、(平均(B) - 平均(A))である。 Pの差分は、他のどのB(平均(P) - 平均(B))よりも常に高くなります。

しかし、これらの差分をユーザーのレーティングに追加して平均化することで、アルゴリズムが優先度を推定するため、Pはすべてのユーザーにとって常に最高の推奨値になります。ユーザーの格付けがどのようなものであっても、どのような差異があっても、P(したがって平均)の合計は最大です。等々。

データが高密度になる傾向があります。その効果のエコーが既に表示されていると思います。それは「間違っている」わけではない(すべてのPが高い評価を受けた後である)が、勧告が非個人化されると直感的に最適ではないと感じる。

Daniel Lemireは、データモデルを「正」と「負」のレーティングに分割し、両者から独立したモデルを構築することを推奨しています。これはいくつかの問題を回避し、より良いパフォーマンスを提供します。

Apache Mahoutで実装されている別の変種は、推定嗜好計算でより良い重み付けを使用することです。それは、標準偏差の高いdiffと、標準偏差の低いdiffに対して重み付けするオプションがあります。これは、多くのユーザーに対して計算された差分を優先します。それは原動力ですが、助けになります。

1

Apache Mahoutで試してみることができます。 Mahout in Actionのexcerptがあります。これは第2のデータポイントとして有用であり、アルゴリズムと実装の問題を区別するのに役立ちます。

Mahout 0.9以降、remmendersは廃止されました。 https://mahout.apache.org/

関連する問題