0

MySQLの協調フィルタリングを参照することによって?、私は次のものを作成しました:

CREATE TABLE `ub` (
  `user_id` int(11) NOT NULL,
  `book_id` varchar(10) NOT NULL,
  `rate` int(11) NOT NULL,
  PRIMARY KEY (`user_id`,`book_id`),
  UNIQUE KEY `book_id` (`book_id`,`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

insert into ub values (1, 'A', '8'), (1, 'B', '7'), (1, 'C', '10');
insert into ub values (2, 'A', '8'), (2, 'B', '7'), (2, 'C', '10'), (2,'D', '8'), (2,'X', '7');
insert into ub values (3, 'X', '10'), (3, 'Y', '8'), (3, 'C', '10'), (3,'Z', '10');
insert into ub values (4, 'W', '8'), (4, 'Q', '8'), (4, 'C', '10'), (4,'Z', '8');

そうすれば、次の表を取得して、それがどのように機能するかを理解できます。

create temporary table ub_rank as 
select similar.user_id,count(*) rank
from ub target 
join ub similar on target.book_id= similar.book_id and target.user_id != similar.user_id and target.rate= similar.rate
where target.user_id = 1
group by similar.user_id;

select * from ub_rank;

+---------+------+
| user_id | rank |
+---------+------+
|       2 |    3 |
|       3 |    1 |
|       4 |    1 |
+---------+------+

しかし、次のコードの後で混乱し始めます。

select similar.rate, similar.book_id, sum(ub_rank.rank) total_rank
from ub_rank
join ub similar on ub_rank.user_id = similar.user_id 
left join ub target on target.user_id = 1 and target.book_id = similar.book_id and target.Rate= similar.Rate 
where target.book_id is null
group by similar.book_id
order by total_rank desc, rate desc;

+---------+------------+
| book_id | total_rank |
+---------+------------+
| X       |          4 |
| D       |          3 |
| Z       |          2 |
| Y       |          1 |
| Q       |          1 |
| W       |          1 |
+---------+------------+



   (1, 'A', '8'), (1, 'B', '7'), (1, 'C', '10');

   (2, 'A', '8'), (2, 'B', '7'), (2, 'C', '10'), (2,'D', '8'), (2,'X', '7');

私がやりたいのは、ユーザー1と2の動作が似ていると仮定することです(前にA、B、Cを選択し、評価が一致している)。したがって、ユーザーAの方がレートが高いのでDをお勧めします。

上記のコードはそうしないようですか?として、最初にランク付けされたのはXです。上記の目標を達成するためにコードを変更するにはどうすればよいですか?

または、実際には、既存の方法の方が推奨の精度が高い/高いのでしょうか。

4

1 に答える 1

2

既存のクエリは、各本のランクの合計値に基づいて結果をランク付けし、同じ合計ランクを持つ本のタイブレークとしてレートを使用します。(また、similar.rateは、クエリ内のグループ化アイテムに集約、グループ化、または機能的に依存しないため、レートは基本的にランダムになります。)

そのため、Xはランク3の1人のユーザーとランク1の1人のユーザーによって選択され、合計ランクは4であるため、Dよりも上位にランク付けされますが、Dはランク3の1人のユーザーによってのみ選択されます。

クエリを変更して、ランキングで重み付けされた評価要素を含めることができます(例:

select similar.book_id, 
       sum(ub_rank.rank) total_rank, 
       sum(ub_rank.rank*similar.rate) wtd_rate
from ub_rank
join ub similar on ub_rank.user_id = similar.user_id 
left join ub target on target.user_id = 1 and target.book_id = similar.book_id and target.Rate= similar.Rate 
where target.book_id is null
group by similar.book_id
order by wtd_rate desc, total_rank desc

-この場合、ランク3のユーザーからの評価が7で、ランク1のユーザーからの評価が10であるため、これはXランクが高くなりますが、Dの合計ランクは31です。 24。

SQLFiddleはこちら

XをDよりも高くランク付けする場合は、XをDよりも高くランク付けするために使用する基準を決定する必要があります。

于 2013-03-26T12:50:29.680 に答える