こんにちは、ECナビ システム本部 システムソリューショングループの大竹(@tokosa)です。
ECナビではDWHのNetezzaを使用し、データマートを構築しております。
Netezzaに関しては、日本ネティーザのサイトをご覧下さい。
実際Netezzaの性能がどの位なのか?何が出来るのかをご紹介します。
Netezzaを使用して2つの集合の類似度を計る
2つの集合の類似度を計る方法としてTanimoto係数(Jaccard係数の拡張)があります。
式は下記の通り。
================================================================== Tb = Nc/ (Na + Nb - Nc) ================================================================== Tb:Tanimoto係数 (二値データ) Na:Aのアイテム数 Nb:Bのアイテム数 Nc:共通集合
Tbは0~1の間で0に近ければ類似度が低く1に近づく程類似度が高くなります。
では、実際にDBで集計を行います。
テーブル構成
NETEZZA => d PUR_TEST
Attribute | Type | Modifier | Default Value -----------------+------------------------+----------+--------------- USER_ID | INTEGER | | ITEM_ID | INTEGER | | DATE | DATE | | distribute key (USER_ID) レコード数:50万 集計対象数(アイテム数):1000
テンポラリーテーブルは作成せず、自己結合でSQLを実行させます。
1.Nc=アイテム共通集合をもとめるSQL
select m.ITEM_ID as MY_ITEM,o.ITEM_ID as OTHER_ITEM ,COUNT(distinct(o.USER_ID)) as match
from PUR_TEST m INNER JOIN PUR_TEST o on m.ITEM_ID != o.ITEM_ID
and m.USER_ID =o.USER_ID
group by m.ITEM_ID,o.ITEM_ID
2.Naのアイテム数
select item_id,count(distinct(user_id)) NA from pur_test group by item_id
3.Nbのアイテム数
select item_id,count(distinct(user_id)) NB from pur_test group by item_id
4.1~3の結果をTanimoto係数の公式へ。
select MY_ITEM,NA,OTHER_ITEM,NB,NC,trunc(cast(NC as dec)/(NA+NB-NC),2) as T from (
select m.ITEM_ID as MY_ITEM,o.ITEM_ID as OTHER_ITEM ,COUNT(distinct(o.USER_ID)) as NC
from PUR_TEST m INNER JOIN PUR_TEST o on m.ITEM_ID != o.ITEM_ID
and m.USER_ID =o.USER_ID
group by m.ITEM_ID,o.ITEM_ID
) ma,
(select ITEM_ID,count(distinct(user_id)) NA from pur_test group by item_id) na,
(select ITEM_ID,count(distinct(user_id)) NB from pur_test group by item_id) nb
WHERE
ma.MY_ITEM =na.ITEM_ID AND
ma.OTHER_ITEM =nb.ITEM_ID
単純に計算量はO(n^2)です。
アイテム数が1000位なら一瞬です。
実行時間================ real 0m6.680s user 0m0.156s sys 0m0.031s
アイテム数が10000超えると。。
実行時間================ real 29m53.769s user 1m10.785s sys 0m3.777s
まとめ
実際にはテンポラリテーブルを作成するべきです、アイテム毎のアイテム数(Na ,Nb) は先に集計しておくと良いでしょう。
Netzzaは自己結合も弱いのでこちらは別にするべきです。
今回はNetezzaの性能計る為、こんなSQLを書いています。
Netezzaにもstddev(標準偏差)、stddev_pop(母標準偏差)、variance(式の分散)、var_pop(母分散)などなど
解析関数が用意されています。協調フィルタリングの相関係数法もできますね。