5. ランク情報に基づく相関ルール分析

相関ルール分析は、データマイニングの分野で代表的な分析手法で、 特にルールを高速に列挙する技術は飛躍的な進展を遂げてきた。 しかしながら、パラメータの設定次第では時に大量のルールが出力され、 そこから興味深いルールを抽出するまでにユーザに多大な負担を強いることも少なくない。

この問題を解決する一つの方法として相互ランク情報に基づいたルールの抽出方法が提案されている 1 。 Takeモジュールでは、 mfriends 及び mpal メソッドとして実装されている。 この手法の特徴は、相関ルール列挙において2アイテムルール \(A=>B(|A|=1,|B|=1)\) のみを列挙し、 そこから \(A,B\) 相互に関連の強いルールを選択するというものである。 \(A=>B\) 及び \(B=>A\) の評価指標(supportやconfidence)が、それぞれの前件部を共通としてもつルール集合の中で ユーザが指定した k 位以内であるとき、アイテム集合 \(A\)\(B\) の関連が強いと考える。

5.1. 入力データと出力データ

表 5.18 に本課題で利用する入力データ onlineRetail2.csv のサンプルを示している。 このファイルは、 オンラインストア購買データ で作成したデータセットである。 スクリプトを保存するディレクトリに保存しておく。 本分析を進めるにあたって必要となる項目は、 顧客IDの InvoiceNoStockCode の2項目のみである。 InvoiceNo はトランザクション識別のためのIDとして用い、 StockCode はアイテムとして用い、 どの商品( StockCode )同士の関連が強いかを、 一回の購入( InvoiceNo )における共起情報によって計算しようということである。

表 5.18 online retailデータセット

InvoiceNo

StockCode

Description

Quantity

UnitPrice

CustomerID

Country

date

time

536365

85123A

WHITE HANGING HEART T-LIGHT HOLDER

6

2.55

17850

United Kingdom

20101201

082600

536365

71053

WHITE METAL LANTERN

6

3.39

17850

United Kingdom

20101201

082600

536365

84406B

CREAM CUPID HEARTS COAT HANGER

8

2.75

17850

United Kingdom

20101201

082600

:

:

:

:

:

:

:

:

:

tutorial_friends_output_image には出力データイメージを示している。 相互に関連の強い2つのアイテム item1item2 および、それら2アイテムのリフト値を出力する。

表 5.19 ランク情報に基づく相関ルールの出力イメージ

item1

item2

lift

15056BL

15056N

29.5141

15056BL

20679

35.015

15056N

20679

24.1441

:

:

:

5.2. スクリプト

リスト 5.6 は、OnlineStoreのデータから、ランク情報に基づく相関ルールを列挙するPythonコードである。 そして、グラフで視覚化した結果を 図 1 に示す。 赤い節点が一つのアイテムを示し、エッジが関連の強い結びつきを表している。 スクリプトの実行内容については、スクリプト内にコメントとして記述している。

リスト 5.6 ルールの相互ランク情報に基づいた2アイテム相関ルールの列挙とその可視化を実現するスクリプト
 1#!/usr/bin/env python
 2# -*- coding: utf-8 -*-/
 3import os
 4
 5# 視覚化のためのモジュール
 6import networkx as nx
 7import matplotlib
 8matplotlib.use('Agg') # 追加
 9import matplotlib.pyplot as plt
10
11import nysol.mcmd as nm
12import nysol.take as nt
13
14iFile="onlineRetail2.csv"
15oPath="./friends"
16os.system("mkdir -p %s"%oPath)
17
18# 注文番号(InvoiceNo)をトランザクションに、StockCodeをアイテムとして利用し、
19# アイテムの類似度グラフを作成する。
20# iFile
21# InvoiceNo,StockCode,Description,Quantity,InvoiceDate,UnitPrice,CustomerID,Country
22# 536365,85123A,WHITE HANGING HEART T-LIGHT HOLDER,6,2010/12/1 8:26,2.55,17850,United Kingdom
23# 536365,71053,WHITE METAL LANTERN,6,2010/12/1 8:26,3.39,17850,United Kingdom
24f=None
25f <<= nm.mcut(f="InvoiceNo,StockCode",i=iFile)
26f <<= nm.muniq(k="InvoiceNo,StockCode",o="%s/tra.csv"%oPath)
27f.run(msg="on")
28
29# アイテムサイズの上限と下限を共に2とすることで、2アイテム相関ルールが列挙される。
30# 最小サポートは100とし、少なくとも100のトランザクションに共起する2アイテム集合を列挙する。
31nt.mitemset(S=100,tid="InvoiceNo",item="StockCode",l=2,u=2,i="%s/tra.csv"%oPath,O=oPath).run()
32# 途中経過: oPath/pattern.csvの中身
33# 一行目は、アイテム22386と85099Bは833のトランザクションに共起していて、そのsupportは0.032でliftが8.209ということ。
34# pid,size,count,total,support%0nr,lift,pattern
35# 81,2,833,25900,0.03216216216,8.209,22386 85099B
36# 478,2,784,25900,0.03027027027,17.1523,22697 22699
37# 122,2,733,25900,0.0283011583,7.4039,21931 85099B
38#                    :
39
40# pattern項目上の2つのアイテムを2つの項目として分割し、
41# エッジファイルを作成し、これが類似度グラフとなる。
42# ここでは類似度の定義にはliftを利用する。
43f=None
44f <<= nm.msplit(f="pattern",a="item1,item2",i="%s/patterns.csv"%oPath)
45f <<= nm.mcut(f="item1,item2,lift",o="%s/rules.csv"%oPath)
46f.run(msg="on")
47# rules.csvの内容
48# item1,item2,lift
49# 22386,85099B,8.209
50# 22697,22699,17.1523
51# 21931,85099B,7.4039
52#        :
53
54# これが相互類似度を利用したルール列挙プログラムfriends。
55# 任意の2つのアイテムペア(上で求めたitem1,item2項目)について、liftが相互に5位以内であるようなアイテムペアを選択する。
56nt.mfriends(ef="item1,item2",ei="%s/rules.csv"%oPath,sim="lift", rank=5, udout=True, eo="%s/friends.csv"%oPath).run()
57# friends.vsvの内容
58# item1%0,item2%1,lift
59# 15056BL,15056N,29.5141
60# 15056BL,20679,35.015
61# 15056N,20679,24.1441
62#           :
63
64# 以下、friends.csvの視覚化
65# 得られたアイテムペアをエッジとしたグラフを描画する。
66# networkxモジュールのエッジフォーマット(アイテムペアのスペース区切り)としてedge.csvに書き出す。
67f=None
68f <<= nm.mcal(c="cat(\" \",$s{item1},$s{item2})", a="edges", i="%s/friends.csv"%oPath)
69f <<= nm.mcut(f="edges",nfno=True,o="%s/edges.csv"%oPath)
70f.run(msg="on")
71# edges.csvの内容
72# 15056BL 15056N
73# 15056BL 20679
74# 15056N 20679
75
76# エッジファイルを読み込んで、バネモデルでレイアウトを決め、グラフを描画し、画像ファイルfriends.pngに出力する。
77G = nx.read_edgelist("%s/edges.csv"%oPath)
78pos=nx.spring_layout(G)
79plt.figure(figsize=(10, 10))
80nx.draw(G, pos=pos,node_size=40,iterations=20)
81plt.savefig("%s/friends.png"%oPath)
82

Footnotes

1

岩﨑幸子,中元政一,中原孝信,宇野毅明,羽室行信,グラフ構造による相関ルールの視覚化ツール:KIZUNA,2017年度人工知能学会(第31回),ウインクあいち,2017/5/24.