TORANA TECH BLOG

株式会社トラーナのエンジニアチームの開発ブログ

ユニークなおもちゃ評価データを相関分析してみた

こんにちは、トラーナのしだのり(@sdx_)です。 今日はデータ分析に関して書いていこうと思います~ ワイワイ!

TL;DR

大量のデータを見て「確からしいデータ」を出していくための過程はものすごくチャレンジングで楽しいです。人間が頭で処理できるパターン数には限度があり、それがバイアスになって物事の判断を誤ったり、認知パターン数の違いが視座の違いになり答えの無い議論になってしまったりすることがあると思いますが、データ分析でそういった議論の共通土台を作っていきたいと思います。

Alteryxのライセンスを買うか、PythonExcelで職人ワザで頑張るのか悩んでます。

  • サクッと色んなロジックを試せるAlteryx
  • 将来技術資産になるPython
  • 技術資産にはならないが伝統の極旨ソースにはなるExcel

どれも一長一短です。。

おもちゃの評価データとは?

弊社では「このおもちゃで親子は遊べましたか?」というアンケートを取っています。

  • アンケート=評価データ=5段階評価で数字を頂いています。
  • 回答数は10万アイテム分くらいあります。
  • おもちゃは、一回の配送につき6点送っています。
  • おもちゃは、購入する・継続する・返却交換する の3つから選べます。
  • おもちゃは、月齢や様々な情報を加味して、弊社内のプランナーという職種のスタッフが選定します。

データの構造を簡単に記述します。

おもちゃ種別番号,おもちゃ名称,アンケート評価数値,おもちゃをお届けする際に使う配送管理番号
1111,おもちゃA,5,2233
2222,おもちゃA,5,2233
3333,おもちゃB,3,2244

このような表のようになってデータが保管されています。 ここでは、「配送管理番号」をキーにすると、「同一の配送の中で送った6点のおもちゃの評価情報」を取得することができます。 「配送管理番号」から「お送りしたお客様のお客様番号」のテーブルを結合し、「そのお客様にお届けした全てのおもちゃの評価情報」を取得することができます。

このような使い方をすることで、そのおもちゃ単品のマクロな評価だけでなく、もっとミクロな・クラスタ化した評価情報を取得することができます。 例えば、「お客様のお住まいの都道府県」で「その都道府県の何歳何ヶ月のお子様はどんな評価傾向にあるか」といったクラスタ化分析を行うことができるのです。

おもちゃの評価データのユニークさとは

こんなおもちゃの評価データ、実は他の会社にはありません。 ECサイトでは、「買ったあとに開梱して遊んだときの評価」は載っています。 ECサイトでは、「どんな購入者なのか」はわかります。

ところが、おもちゃにとって必要な「買ってしばらく経っても遊んでいるのか?買って使っているのは何歳何ヶ月のこどもなのか?」といった情報はサブスクリプション・レンタルのモデルでなければわからないと思っています。

そのため、トイサブ!で収集しているアンケート情報はとてもユニークな情報なのです。 「ユニークな情報」と言われるとぜひRやSPSSにかけたくなる、そんな方も非常に多いと思います。

なぜ分析するのか

おもちゃの単品評価を集めて、「このおもちゃは平均評価4.3だよ」そういったデータ利用はとても多いユースケースだと思います。 最初はそれで満足していました。ところが、こどもはとてもユニークなものなのだと途中から気づいたときにこの「平均して評価が高い」ことだけを見てしまってはいけないと思ったのです。

私達はついつい平均値を求めてしまいがちです。 データには、平均値・最頻値・中央値があります。それで「全体としてはこうである」を求めるために平均を使うケースは多いと思います。 私は平均値を使うのに慎重になるべきだなと思っています。

平均値は異常値を見逃してしまうからです。その対象が、本当に中央に偏差しているモデルならいいのですが、そうでないモデルも数多く存在すると思います。 また、「ユーザーが選ぶ」のと「サービス提供者が選ぶ」のは大きくモデルが異なると想定しており、「ユーザーが選ぶ」のは中央偏差になると予測され、「サービス提供者が選ぶ」モデルは中央偏差になるのかどうか懐疑的です。

ユーザーとは、そのサービスを使ってみたい、使って満足している方を指します。この方々は、ある一定のクラスタに収まるでしょう。 そのクラスタに分類されたユーザーが選ぶことにおいて中央偏差が生まれることは大いに考えられると思います。

サービス提供者が選ぶモデルも、採用者の質やマニュアルによっては中央偏差が発生すると思います。 しかしこどもという存在はそのユニークさから、「月齢」でもクラスタ分けは難しく、できることが同じ月齢でも大きく異なります。 クラスタ分けが難しいものに対して「満足されるであろうものを選ぶ」という行為に偏差が発生するのかは、まだ答えが出ないところです。

そのためのデータ分析が必要です。 「このおもちゃを、高く評価した」「それはなぜか、その傾向はどんなところにあるか」それを分析していくことで、偏差や平均ではない、詳細なクラスタ分けとクラスタの対応方法がわかるようになるだろうと予想しています。

なぜ相関分析なのか

まず単品の評価はすでにとれています。弊社では、お客様の情報を事細かには情報収集していません。地道ではありますが、弊社のプランナーはお客様からのメールやアンケートの文言からどんな人かを予測し、お客様に情報を記載いただかなくともペルソナを予測し対処を考えています。

このプランナーの「その先にいるお客様のペルソナを予測する」ことをどうやったら技術で助けられるのか?その一つの対処策が相関分析です。

できれば、「ユーザー属性」と「おもちゃ」で相関を分析したくなるのですが、弊社ではお客様の定量情報は最低限にしており、メールの文脈などから定性でお客様をイメージしています。 そこで「このおもちゃとこのおもちゃを組み合わせて送ると評価が上がる傾向にある」おもちゃがないか調べてみることにしました。

すなわち、AとBのおもちゃを同梱することに正の相関があるのか?負の相関があるのか?を見ていくことで、どういったおもちゃは同梱すべき・すべきでないがわかってくると、プランナーの考えるプロセスにデータ分析の力で貢献できるなと思いました。

なぜPythonを使ってみたか

ソリューションとしては

  • Alteryxのようなデータ分析・クレンジングツールを使う
  • Pythonのような言語でプログラムを作る
  • Excelで頑張る

この3つのソリューションがあります。

データ分析は8割クレンジング、1割ロジック、1割実装 というイメージを持っています。 この「1割のロジック」は誰の頭にもぱっと思いつくものです。 これがレベルが高い組織になると、3割クレンジング、5割ロジック、2割実装、というようにクレンジングの割合を小さくしていけると思います。 データ分析の結果を率先的にソフトウェアに組み込んでいる組織は、クレンジングの割合をいかに小さく、そして実装をいかに減らし、ロジックに価値が出るように取り組むことでしょう。

ところが実装に進むに際し膨大なクレンジングが必要になりました。 エンコードから始まり、数値、文字、Boolean、DATE、また地味に日本語⇔英語、Int32/64など、落とし穴が満載です。 また、そのデータを結合する・行列変える・などの加工も必要になります。

今回のデータはクレンジングがそこまで必要なかったこと、ライブラリが充実していることからPythonでやってみようと思いました。

求めるアウトプット

「AとBのおもちゃの同梱に、正負いずれの相関があるのか、相関係数はどの程度か」をイメージしました。 相関係数を二次元の表にし、ヒートマップのように強い相関があるところはわかりやすく表示したいと思います。

プロセス

データクレンジング

データはフォーマットが統一されていませんでした。数値のところに文字があったりします。まずデータのフォーマットを整えます。 次に、私達の持っているデータでは配送番号をキーにして左列に配送番号、右列におもちゃの種別番号、配列内に評価情報というデータに変えます。

配送番号,おもちゃ種別A,おもちゃ種別B,おもちゃ種別C,おもちゃ種別D
1111,5,4,4,3
2222,4,4,5,5
3333,3,3,5,5

このようなデータテーブルを準備します。 もともとのテーブルのデータを組み替える必要がありますね。

なおこの種別の種類は1500以上あります。配送番号は数万番まであります。 そのためデータテーブルのサイズは何百MBになるのでExcelだと厳しいです。

もともとのデータをクロスタブで切り替えれば一瞬で終わる作業です。 ここで自分は何を思ったか、「おれはExcelを信じる」と思ってExcelでクロスタブを作りました。 あとから見たら Pythonのpandasにはpandas.crosstab()関数が存在しました。。。 瞬殺だったはずなのに、Excelのグルグル回る○を10分以上ぼーっと眺めて、今年の夏は何しようかと考えていました。

データクレンジングにExcelを使う人がいたら、これからは「人は、弱くて……不完全で……だから託すんだ!託されて、歩き続けるんだ。どんなに辛い道であっても……!」と全力で止めます。

というわけでデータクレンジングはこれで無事出来ました。

なんと数行のコードでできる

実際に書いたのはこれだけです。メモ含めなので汚くてすみません。


from string import ascii_letters 
import pandas as pd 
import seaborn as sns 
import matplotlib.pyplot as plt 

sns.set(style="white")# seabornのヴィジュアライズ化のため 

data = pd.read_csv(r"C:\hoge\testdata.csv", index_col="DeliveryNumber")#インデックスは適当 
df = pd.DataFrame(data) #全部のとき 
df2 = df[["XXXX","XXXX"]] #おもちゃの番号でこれだけ抽出したいとき 
#print(df2) #とりあえず問題ないか 
#pd.DataFrame(data) #pandasのおまじない 
#df_corr = df_corr = df.corr() #corrメソッド pandasの。全部パターン。corrメソッドが、列間から相関行列を生成する  
df2_corr = df2_corr = df2.corr() 
df2_corr.to_csv(r"C:\hoge\sample.csv") 
#df.to_csv(r"C:\hoge\sample.csv") 
#sns.heatmap(df2_corr) {COMMENT OUT}seabornのヴィジュアライズ 
#plt.show() #テスト的な出力。マットプロットのライブラリ 

結果はこのようにビジュアライズ出来ます。

ヒートマップ
ヒートマップ

おわりに

おもちゃの相関をヒートマップで表すことは出来ました。 これが人間が見たときにどんな違和感があるか、その違和感を納得感に向かわせる、もしくは気づきを作り出すことがデータ分析の第一歩です。

このヒートマップを見ると、意外なおもちゃとの相関があるかも!と思ったのですが、「いや、普通これとこれは組み合わせない。イレギュラーケースですね」というものもありました。 これは分析結果の負の側面で、イレギュラーで回数が少ないケースを含んでしまい、それがたまたま評価が高・高の組み合わせであったため、おかしな違和感をもたせる結果が出ました。

そうでなく、「確かにこれとこれは同梱する傾向がある」というものが、正の相関が係数として強く出ており、その結果「やっぱりそうか」という納得感も出せています。

まだまだスポットで実施しているので、全体のプロセスには組み込めていませんが、こういった分析を通じて「このおもちゃとこのおもちゃは同梱すると正の相関が強い」という、今社内スタッフが手作業で・頭で考えていることを支援できるデータを作れるチームを作りたいなと思います。