2018 年 12 月
Volume 33 Number 12
Artificially Intelligent - マーケット バスケット分析
きっとあなたもこの人工知能 (AI) のことをご存知のことでしょう。特に今はクリスマス ショッピングの季節なので、よく見かけるかもしれません。何だかおわかりですか? それは、購入の推奨です。ほとんどすべてのオンライン小売業者は、「よく一緒に購入する」または「X を購入した顧客は Y も購入した」という見出しの下に、おすすめ商品の表示を加えます。 2013 年に McKinsey 社が行ったある調査 (bit.ly/2yK3Bu8) によると、Amazon で消費者が購入したもののうち、35% が商品推奨アルゴリズムによるものでした。さらに、この戦略は小売業者だけでなく、Netflix や YouTube などのオンライン ストリーミング サービスでも採用されています。そうしたサービスでは、洗練された推奨アルゴリズムを使用して視聴者をより長く引きつけます。
明らかに、推奨システムは私たちの日常生活に影響を与えています。これは、消費者がよく見かける有名な AI かもしれません。このコラムでは、マーケット バスケット分析と呼ばれる基本的な形の推奨システムについて考えます。
マーケット バスケット分析
アフィニティ分析とも呼ばれるマーケット バスケット分析は、消費者が特定のグループのアイテムを購入した場合、別のグループのアイテムを購入する可能性が高いという理論に基づくモデリング手法です。たとえば、ピーナッツ バターとパンを購入している人はジャムも購入する確率がかなり高くなります。ただし、すべての関係が一目でわかるわけではありません。消費者行動を予測できると売上が伸び、小売業者は競合他社よりもかなり優位に立つことができます。厳密に言えば、マーケット バスケット分析は関連分析手法の応用の一つにすぎません。しかし、多くのオンライン記事やチュートリアルではその 2 つが混同されていることがあります。これまでに書いた他の機械学習手法の観点からすると、マーケット バスケット分析は教師なしの学習ツールと言えます。特徴エンジニアリングの方法はほとんど必要なく、データのクリーニングと準備も少しですみます。実際には、マーケット バスケット分析から得られた分析情報を、他の AI やデータ サイエンス ツールを使ってさらに詳しく調べることができます。
マーケット バスケット分析では、隠されたパターンを発見することができます。そうした高度な機能があるにもかかわらず、比較的説明が簡単で、高度な統計や計算についての知識は必要ありません。ただし、確認しておくべきいくつかの用語と従来の表記があります。第一に、原因と結果の概念は前件、後件と呼ばれます。前に述べた例では、ピーナッツ バターとパンが前件で、ジャムがその後件です。この関係の正式な表記法は {ビーナッツ バター、パン} - > {ジャム} となり、これらの項目の間に関連性があることを示します。前件と後件はどちらも、複数の項目から構成されることもあります。
マーケットバスケット分析には、3 つの重要な数学的メジャーが必要です。サポート、リフト、信頼度という指標です。サポートは、データ内に前件が一緒に表示される回数を表します。たとえば、{ピーナッツ バター} -> {ぶどうジャム} という関係があるとします。100 人の顧客 (顧客ごとに 1 つのトランザクション) が存在すると仮定し、次のシナリオを考えてみましょう。
- 15 人がピーナッツ バターを購入した
- 13 人がぶどうジャムを購入した
- 11 人がピーナッツ バターとぶどうジャムを購入した
サポートは、一緒にトランザクションに現れる項目の回数を表します。この例の場合は、11/100 または 0.11 です。統計用語で言うと、特定のトランザクションにピーナッツ バターとぶどうジャムの両方が含まれる可能性が 11% あります。信頼度は、サポートの値 (.11) を取り、それをぶどうジャムのみを持つトランザクションの確率で除算したものです。この例の場合は、0.846 という値になります。これは、ぶどうジャムが購入されたときに、約 85% の確率でピーナッツ バターと一緒に購入されたことを意味します。最後は、リフトです。これは信頼度 (0.846) を取り、それをピーナッツ バターの確率で除算します。これは 5.64 となります (小数点以下第 2 位を四捨五入)。
図 1 に示すように、これらすべてをシンプルな図表で示すとよりわかりやすいかもしれません。
図 1 サポート、信頼度、リフトの各値
メジャー | 式 | 値 |
サポート | P (ピーナッツ バター & ぶどうジャム) | .011 |
信頼度 | サポート/P (ぶどうジャム) | 0.846 |
リフト | 信頼度/P (ピーナッツ バター) | 5.64 (四捨五入) |
実際のマーケット バスケット分析
前項のメトリックを基に、実際のデータセットでマーケット バスケット分析を試してみましょう。まず、分析する小売店のデータを取得します。幸い、カリフォルニア大学アーバイン校は、英国を拠点とする Web サイトのトランザクションを含むデータセットを提供しています。利用可能なデータセットの詳細については、bit.ly/2DgATFl をご覧ください。お好みのプラットフォームで Python 3 ノートブックを作成してください (前のコラムでは msdn.com/magazine/mt829269 で Jupyter ノートブックを取り上げました)。空のセルを作成し、次のコードを入力してサンプルデータをダウンロードし、セルを実行します。
! curl http://archive.ics.uci.edu/ml/machine-learning-databases/00352/Online%20Retail.xlsx -o retail.xlsx
これが完了したら、次のコードを新しいセルに入力して Excel スプレッドシートを Pandas DataFrame に読み込み、データセットの列を出力します。
import pandas as pd
df = pd.read_excel('retail.xlsx')
print( df.columns)
The output will look something like this:
Index(['InvoiceNo', 'StockCode', 'Description', 'Quantity', 'InvoiceDate',
'UnitPrice', 'CustomerID', 'Country'],
dtype='object')
マーケット バスケット分析では厳密にデータを破棄する必要はありませんが、請求書番号が Null のレコードや注文がキャンセルされたレコードなど、無関係なレコードを削除することは重要です。商品説明の余分なスペースを削除したり、すべての請求書番号を文字列に変換したりすることも大切です。この処理は、次のコードを実行することによって行えます。
df['Description'] = df['Description'].str.strip()
df.dropna(axis = 0, subset=['InvoiceNo'], inplace = True)
df['InvoiceNo'] = df['InvoiceNo'].astype('str')
df = df[~df['InvoiceNo'].str.contains('C')]
では、次のコードを入力して、データを集約し、国レベルで表示してみましょう。
df.groupby('Country').count().reset_index().sort_values(
'InvoiceNo', ascending = False).head()
次に、データを再構成します。各商品をワンホット エンコードし、1 行に 1 つのトランザクションとなるようにします。ワンホット エンコーディングとは、カテゴリ値を列に変換するデータ変換技法の一種です。カテゴリ値が存在する場合は、値 1 を入力します。また、個々の市場における消費者行動を比較するために、データセットの範囲を 1 つの国 (ここでは、フランス) だけに限定します。これを行うには、次のコードを入力して実行します (セル出力の basket_uk データ フレームの形式にご注目ください。ワンホット エンコーディングは列を 8 から 4175 に拡張します)。
basket_fr = (df[df['Country']=="France"]
.groupby(['InvoiceNo', 'Description'])['Quantity']
.sum().unstack().reset_index().fillna(0)
.set_index('InvoiceNo'))
basket_fr.head(10)
結果を見て、私のワンホット エンコーディングの問題が一目でわかりました。2 列目の 6 個下の項目の値が 24.0 になっています。私の意図は、データに数量を入力することではなく、1 か 0 を入れることでした。ですから、0 以外の値を見つけて 1 に変換する必要があります。これを修正するには、次のコードを実行します。24.0 が 1 に変換されていることに注意してください。
def sum_to_boolean(x):
if x<=0:
return 0
else:
return 1
basket_fr_final = basket_fr.applymap(sum_to_boolean)
basket_fr_final.head(10)
MLXTEND (rasbt.github.io/mlxtend) を使用して、データをより細かく分析します。MLXTEND は、マーケット バスケット分析を含む一般的なデータ サイエンス タスクで役立つツールの Python ライブラリです。ノートブック内からこのライブラリをインストールするには、次のコードを実行します。
! pip install mlxtend
MLXTEND パッケージをインストールした後、次のように、MLXTEND から関連ライブラリをインポートします。
from mlxtend.frequent_patterns import association_rules
from mlxtend.frequent_patterns import apriori
新しいセルで次のコードを入力して、少なくとも 6% のサポートが含まれているアイテムのセットを表示します。
frequent_itemsets_fr = apriori(basket_fr_final, min_support = 0.06,
use_colnames = True)
frequent_itemsets_fr.sort_values('support', ascending = False).head()
鍵となる項目のセットを特定できたので、関連ルール ライブラリを適用して顧客の購買行動を発見できます。以下のコードを入力して実行します。
a_rules = association_rules(frequent_itemsets_fr, metric = "lift",
min_threshold = 1)
a_rules.sort_values('lift',ascending = False)
結果をリフトでソートすると、図 2 のようになります。このサイトにおけるフランス人客の購買パターンがわかります。CHILDRENS CUTLERY SPACEBOY を購入する顧客は CHILDRENS CUTLERY DOLLY GIRL も購入し、ある色の目覚まし時計を購入する顧客は別の色の目覚まし時計も購入していることがこの結果から一目でわかります。アクションにつながる分析情報としては、性別ごとのカトラリーでのバンドル販売と、複数の色の目覚まし時計のバンドル販売をサイト所有者にお勧めします。
図 2 フランス人客の関連付けルール
ただし、このリストは出現順ではなくリフトでソートされていることにご注意ください。新しいバンドルや商品オファリングの人気が低ければ、それを紹介しても意味がないかもしれません。これらのカトラリー アイテムの人気度を知るには、次の Python コードを入力します。
print( basket_fr_final['CHILDRENS CUTLERY SPACEBOY'].sum())
print( basket_fr_final['CHILDRENS CUTLERY DOLLY GIRL'].sum())
あまり期待できそうにありません。結果は、SPACEBOY は 27、DOLLY GIRL は 28 しかありませんでした。少し調べてみて、もう少し期待のもてる関連ルールが見つかりました。関連ルール インデックス 50 (SET/20 RED RETROSPOT PAPER NAPKINS) は、赤い紙コップと赤い紙皿の前件です。次のコードを入力すると、販売数がわかります。
basket_fr_final['SET/20 RED RETROSPOT PAPER NAPKINS'].sum()
数値は低いですが、使い捨ての紙コップを購入する顧客は、紙皿とナプキンも合わせて購入しています。これはうなずける結果です。賢い小売業者は、顧客に購入を促すために、これらを簡単にバンドル オファーにパッケージできるかもしれません。
鋭い読者は、結果のデータフレームに他にも 2 つのメトリックがあることに気付くことでしょう。それは、レバレッジと確信です。これらは、マーケット バスケット分析を実行するときに考慮する必要がある付加的な値です。この詳細については、「alternative measures of interestingness (関心度の代替的メジャー)」をご覧ください。 Wikipedia から始めるとよいでしょう (bit.ly/2AECRNh)。
国レベルでデータを集約したとき、イギリスからの請求書は他のどの国よりもはるかに多くありました。さらに多くの生データを利用できるようにして顧客行動を調べることで、より多くのことが学べます。新しいセルに次のコードを入力して実行し、調べてみましょう。
basket_uk = (df[df['Country']=="United Kingdom"]
.groupby(['InvoiceNo', 'Description'])['Quantity']
.sum().unstack().reset_index().fillna(0)
.set_index('InvoiceNo'))
basket_final_uk = basket_uk.applymap(sum_to_boolean)
frequent_itemsets_uk = apriori(basket_final_de, min_support = 0.06,
use_colnames = True)
a_rules_uk = association_rules(frequent_itemsets_uk, metric = "lift",
min_threshold = 1)
a_rules_uk.sort_values('lift',ascending = False).head()
英国の場合はデータ セットが大きいため、実行時間はかなり長くなります。結果もまったく違います。データが大きいために分析が変わったのでしょうか? それとも、単にマーケットが異なり、顧客の好みも異なるからなのでしょうか?あるいは、小売業者がさまざまなマーケットでさまざまな商品を販売しているということでしょうか?これは、分析を行っていく中で自分でつきとめなければならないものです。状況によって異なるからです。この場合、イギリスを拠点とするオンライン小売業者であること以外、ほとんど情報がありません。しかし、実際のプロジェクトでは、ビジネスのその分野での専門家との連携が、データ分析プロジェクトを成功させるため重要な要素となります。
まとめ
この記事では、消費者行動パターンを明らかにするためのマーケット バスケット分析の使用方法について検討しました。マーケット バスケット分析は、アフィニティ分析のより広い分野に属しています。大手企業はこれを利用して、顧客が商品により多くのお金を投じ、ストリーミング プラットフォームにより多くの時間を費やすようにします。
マーケット バスケット分析は、データ サイエンスにこれから目を向けようとしている人や組織にとって非常に優れたエントリ ポイントです。数学的なスキルという意味では、それほどハードルは高くありません。実際、必要な計算といえば、シンプルな除算や基本的な確率論程度です。初心者でも調べやすい問題空間であり、企業に AI の導入を開始するのにもうってつけです。とはいえ、これはデータ サイエンスを実施したり、企業のリーダーに価値を示したりするための強力な手段ではないということにご留意ください。収益に大きな影響を及ぼす可能性があるものです。
Frank La Vigne 氏は、Microsoft で AI テクノロジ ソリューションの専門家として働き、企業が分析と AI によってデータからより多くの価値を引き出してより多くの事柄を実現するのを支援しています。また、DataDriven ポッドキャストの共同ホストも努めています。FranksWorld.com (英語) に定期的にブログ記事を投稿し、Frank’s World TV (FranksWorld.TV (英語)) という YouTube チャンネルを主催しています。
この記事のレビューに協力してくれた技術スタッフのAndy Leonard 氏 (Enterprise Data & Analytics)