Python、SciKit、およびテキスト分類を利用して行動プロファイルを作成する

顧客がこれまで購入した商品に関する説明のテキスト属性に基づいて、顧客の行動プロファイル・モデルを作成する方法を学んでください。SciKit は、モデルの作成と評価をするための強力な Python ベースの機械学習パッケージです。この SciKit を利用して、モデルを作成し、シミュレートした顧客の商品購入履歴にそのモデルを適用する方法を学んでください。この記事のサンプル・シナリオでは、各顧客が購入する特定の商品とそれに対応するテキストの商品説明を基に、個々の顧客に音楽リスナーのプロファイルを割り当てるモデルを作成します。

Deep Dhillon, Technologist

Deep DhillonDeep Dhillon は、多数の高度なネットワーク・アプリケーションの概念化、設計、デプロイに関して幅広い経験を持つ熟練の技術役員です。Mayalogy に所属する彼は、商品開発において機械学習、NLP (Natural Language Processing: 自然言語処理)、データ科学に基づくテクノロジーを利用する新興企業を支援しています。



2014年 7月 17日

はじめに

私たちのほぼすべてが、買い物をします。食料品などの基本的な生活必需品から音楽アルバムなどの娯楽商品に至るまで、ありとあらゆるものを購入します。買い物をするときに、私たちは日々の生活で使うものを見つけているだけではありません。特定の社会集団への関心も表現しています。インターネット上のアクションや決定事項は、それぞれの個人の行動プロファイルを形づくります。

私たちが商品を購入する場合、その商品には自らを他の商品と似たものにしている性質や、他の商品とは違うものにしている性質がいくつもあります。商品を特徴づけるそのような性質の例には、商品の価格、サイズ、タイプなどが挙げられます。これらの性質を表す数値または列挙値による構造化された属性の他に、構造化されていないテキスト属性もあります。例えば、商品説明や顧客レビューのテキストにしても、商品を特徴づける属性となります。

テキスト分析やその他の NLP (Natural Language Processing: 自然言語処理) 手法は、非構造化テキスト属性から意味を抽出する上で大いに役立ちます。こうして抽出された意味は、行動プロファイルを作成するといったタスクで非常に価値があります。

この記事では、テキスト分類を使用して行動プロファイル・モデルを作成する方法の一例を紹介します。また、モデルの作成と評価をするための強力な Python ベースの機械学習パッケージである SciKit を利用して、シミュレートした顧客とその商品購入履歴にその行動プロファイル・モデルを適用する方法を説明します。記事で用いる具体的なシナリオでは、いくつかの音楽リスナー・プロファイル (レイブ、ゴス、ヘビメタなど) のうちの 1 つを顧客に割り当てるモデルを作成します。割り当ての基準とするのは、各顧客が購入する特定の商品とそれに対応するテキストの商品説明です。


音楽に関する行動プロファイルのシナリオ

まずはシナリオを説明します。このシナリオでは、多数の顧客プロファイルが含まれるデータ・セットがあります。それぞれの顧客プロファイルには、その顧客が購入した全商品に関する簡潔な自然言語ベースの説明が含まれています。以下に挙げるのは、ブーツに関する商品説明の例です。

説明: Rivet Head では、業界最新のゴス風ダークウェイブ・サブカルチャー・ファッションを提供しています。このメンズのバックル・ブーツもその 1 つです。合成 (人工) 皮革のアッパー、前面の靴ひもと互いにクロスしたバックルが足元まで細かくあしらわれたブーツ・シャフト、トレッド付きのアウト・ソール、コンバット風のトウ、そして脱ぎ履きしやすくするためのインサイド・ジップを特徴とします。アウト・ソールにはラバーを採用しています。シャフトは 13.5 インチ (約 34.3 センチメートル)、レッグ周りは約 16 インチ (約 40.6 センチメートル) です (サイズ 9.5 の場合)。スタイル: メンズのバックル・ブーツ。

このシナリオで目標とするのは、このような商品説明に基づいて、現在と将来のユーザーのそれぞれを行動プロファイルのいずれかに分類することです。

以下に示すように、キュレーターが商品サンプルを使って行動プロファイル、行動モデル、顧客プロファイル、そして最後に顧客の行動プロファイルを作成します。

図 1. 顧客の行動プロファイルを作成する手法の概要
サンプル・シナリオのワークフローを示す図

最初のステップでは、キュレーターの役割を担って、システムに各行動プロファイルを理解させます。そのための 1 つの方法は、各商品のサンプルを手作業でシードとしてシステムに提供することです。これらのサンプルが、行動プロファイルを定義できるようにします。このシナリオでは、ユーザーを以下のいずれかの音楽関連の行動プロファイルに分類します。

  • パンク
  • ゴス
  • ヒップホップ
  • メタル
  • レイブ

パンクに識別される商品の例として、パンク・アルバムやパンク・バンドの説明などがある、セックス・ピストルズの「Never Mind the Bollocks」があります。パンクに識別されるその他の商品の例としては、モヒカン刈りなどのヘアスタイルに関連する商品や、ドク・マーテンズのブーツなどのフットウェアに関連する商品を挙げることもできます。


ライブラリー、ソフトウェア、データのセットアップ

この記事で使用するデータとソース・コードのすべては、JazzHub の bpro プロジェクトからダウンロードすることができます。tar ファイルをダウンロードして解凍した後、Python、SciKit Learn (機械学習およびテキスト分析パッケージ)、そしてすべての依存関係 (numpy、scipy、等々) が揃っていることを確認してください。Mac を使用している場合は、SciPy Superpack が確実な方法となるはずです。

tar ファイルを解凍すると、2 つの YAML ファイルにプロファイル・データが格納されていることに気づくはずです。これらの商品説明は、シード・コーパス (文書の本文) を取り込んで人工的に生成されたものです。この生成プロセスでは、商品説明で単語が出現する頻度が考慮されています。リスト 1 に、人工的に生成された商品説明を示します。

注: 以下の説明は、真の自然言語による説明ではありませんが、実際の状況では真の自然言語になります。

リスト 1. 人工的な商品説明
customer single clothes for his size them 1978 course group 
rhymes have master record-breaking group few starts heard 
blue ending company that the band the music packaged 
master kilmister not trousers got cult albums heart 
commentary cut 20.85 tour...

この分析には 2 つのデータ・ファイルが含まれています。

  • customers.yaml— 顧客のリストで構成されたファイルです。このファイルには、顧客別の商品説明のリストとターゲット・ラベル (つまり、正しい行動プロファイル) が格納されています。正しい行動プロファイルとは、正しいことがわかっている行動プロファイルのことです。例えば、現実のシナリオではゴス・ユーザーのプロファイル・データを調べて、これらのユーザーが購入している商品が、ユーザーがゴスに分類されることを示しているのを確認します。
  • behavioral_profiles.yaml— プロファイル (パンク、ゴス、等々) のリストと、そのプロファイルを定義する商品説明のサンプル・セットで構成されたファイルです。

コマンド python bpro.py -g を実行して、独自にシミュレートしたファイルを生成することもできます。

注: 最初に、対象のジャンルを定義するコンテンツをシード・ディレクトリーに取り込む必要があります。それには、カレント・ディレクトリーをシード・ディレクトリーに変更し、任意のファイルを開いて指示を参考にしてください。bpro.py ファイル内のパラメーターを操作することで、商品説明の長さ、ノイズの量、トレーニング・サンプルの数、その他のパラメーターを変更することができます。


行動プロファイル・モデルを作成する

まずは、SciKit の CountVectorizer を使用して、コーパスの単純な用語カウント・ベースの表現を作成するところから始めます。このコーパス・オブジェクトは、商品説明が含まれる文字列の単純なリストです。

リスト 2. 単純な用語カウントを作成するコード
    vectorizer = CountVectorizer(gmin_df=1)
    corpus=[]
    for bp in behavioral_profiles:
        for pd in bp.product_descriptions:
            corpus.append(pd.description)

SciKit には、もっと高度なベクタライザーが他にもあります。そのうちの 1 つとして挙げられる TFIDFVectorizer は、TF/IDF (Term Frequency/Inverse Document Frequency) 重み付けを適用して文書の用語を保管します。TF/IDF 表現は、Ozzy、raver、Bauhaus といった固有の用語に対する重み付けを、and、the、for などの頻繁に出現する用語より重くするのに役立ちます。

次に、商品説明を個々の単語にトークン化し、用語の辞書を作成します。適合プロセス中にアナライザーによって検出された用語のそれぞれに、固有の整数によるインデックスが割り当てられます。この整数は、生成された行列内の列に対応します。
fit_corpus = vectorizer.fit_transform(corpus)

注: さらに、このトークナイザー構成では、1 文字からなる単語が破棄されます。

いくつかの特徴を出力することで、何がトークン化されたのかを確認することができます。それには、print vectorizer.get_feature_names()[200:210] を使用してください。このコマンドは、以下の出力を表示します。

リスト 3. print コマンドの出力
[u'better', u'between', u'beyond', u'biafra', u'big', 
u'bigger', u'bill',   u'billboard', u'bites', u'biting']

現行のベクタライザーには、語幹抽出された単語がないことに注意してください。語幹抽出とは、単語の活用形または派生語から共通の語基または原形を取得するプロセスのことです。例えば、上記リストの「bigger」という単語の共通の語幹は「big」です。SciKit は、語幹抽出、見出し語化、そして複合語の分割といった、複雑なトークン化を扱いませんが、NLTK (Natural Language Toolkit) ライブラリーに含まれているようなカスタム・トークナイザーを使用すれば、そのようなトークン化に対処することができます。優れたカスタム・トークナイザーの例については、scikit-learn.org を参照してください。

単語のさまざまな形式ごとに統計的表現をする必要はないことから、必要なトレーニング・サンプルの数を減らすには、語幹抽出などのトークン化プロセスが役立ちます。トレーニングの必要性を下げるには、タイプに関する辞書を使用するといった、他の手法を利用することができます。例えば、すべてのゴス・バンドのバンド名リストがある場合、goth_band などといった共通語のトークンを作成し、それを説明に追加してから特徴を生成します。こうすると、あるバンドが説明の中で初めて出現したとしても、モデルはそのバンドを、モデルがパターンを認識している他のバンドと同じように扱います。この記事のシミュレートしたデータの場合には、トレーニングの必要性を下げることについては懸念事項ではないため、次のステップに移って構いません。

機械学習では、このシナリオのような管理された分類の問題は、最初に一連の特徴とそれに対応するターゲット・ラベル (つまり正しいラベル) を一連の観測に対して定義することで提示されます。その後、選択されたアルゴリズムは、データに最もよく適合すると同時に既知のデータ・セットに対する誤りを最小限に抑えるモデルを見つけ出そうとします。従って、次のステップでは、特徴とターゲット・ラベルのベクトルを作成します (リスト 4 を参照)。検証手法が対象を無作為に選ばない場合に備えて、観測を無作為に行うのは常に賢明な考えです。

リスト 4. 特徴とターゲット・ラベルのベクトルの作成
   data_target_tuples=[ ]
    for bp in behavioral_profiles:
        for pd in bp.product_descriptions:
            data_target_tuples.append((bp.type, pd.description))

    shuffle(data_target_tuples)

次に、リスト 5 に示すようにベクトルをアセンブルします。

リスト 5. ベクトルのアセンブル
    X_data=[ ]
    y_target=[ ]
    for t in data_target_tuples:
        v = vectorizer.transform([t[1]]).toarray()[0]
        X_data.append(v)
        y_target.append(t[0])

    X_data=np.asarray(X_data)
    y_target=np.asarray(y_target)

これで、分類子を選択して行動プロファイル・モデルをトレーニングする準備が整いました。その作業に移る前に、念のため、モデルを評価することをお勧めします。こうすることにより、モデルが機能することを確認してから顧客に対してモデルを試すことができます。


行動プロファイル・モデルを評価する

最初に、線形 SVM (Support Vector Machine: サポート・ベクター・マシン) を使用します。線形 SVM は、このシナリオでのような疎なベクトル問題に適した高い認識性能を持つモデルです。コード linear_svm_classifier = SVC(kernel="linear", C=0.025) を使用してください。

注: このモデルの初期化コードを変更するだけで、別のモデル・タイプに切り替えることができます。この分類子のマップは多数の共通オプションの初期化を設定しているため、このマップを使用して、他のモデル・タイプを試すことができます。

リスト 6. 分類子のマップを使用するコード
classifier_map = dict()
classifier_map["Nearest Neighbors"]=KNeighborsClassifier(3)
classifier_map["Linear SVM"]=SVC(kernel="linear", C=0.025)
classifier_map["RBF SVM"]= SVC(gamma=2, C=1)
classifier_map["Decision Tree"]=DecisionTreeClassifier(max
    _depth=5)
classifier_map["Random Forest"]=RandomForestClassifier
    (max_depth=5, n_estimators=10, max_features=1)
classifier_map["AdaBoost"]=AdaBoostClassifier()
classifier_map["Naive Bayes"]=GaussianNB()
classifier_map["LDA"]=LDA()
classifier_map["QDA"]=QDA()

これは、複数クラスの分類問題であるため (つまり、2 つ以上の可能なカテゴリーから選択する必要がある問題)、これに対応する戦略も指定する必要があります。そのためによく使われる手法は、one vs. all の分類を行うことです。つまり、例えば goth クラスに属する商品の商品説明を使用して 1 つのクラスを定義し、goth クラス以外のすべてのクラス (metalrave、等々) に属する商品の商品説明サンプルで構成される、別のクラスを定義します。最終的には検証の一環として、現在テスト対象になっているデータに対してモデルがトレーニングされていないことを確認しなければなりませんが、それには多重交差検証という手法が一般的に使用されます。この例では、5 つの群を使用します。つまり、データを 5 つの部分に分割し、それに対して 5 つのパスが作成されます。各パスでは、データの 5 分の 4 を使用してトレーニングを行います。残りの 5 分の 1 は、テストに使用します。

リスト 7. 多重交差検証
scores = cross_validation.cross_val_score(OneVsRestClassifier
    (linear_svm_classifier), X_data, y_target, cv=2)
print("Accuracy using %s: %0.2f (+/- %0.2f) and %d folds" 
    % ("Linear SVM", scores.mean(), scores.std() * 2, 5))

完璧な精度を達成できるとは言え、これは、シミュレートされたデータが完璧すぎるという証拠でもあります。当然ながら、実際のシナリオではノイズが入ってくることになります。それは、グループ間を完全に分け隔てる境界が必ずしも存在するとは限らないためです。その一例として、ゴス・パンクという問題のあるジャンルがあり、Crimson Scarlet などのバンドは、gothpunk の両方のトレーニング・サンプルに振り分けられる可能性があります。ダウンロードした bpro パッケージに含まれるシード・データをさまざまに試してみることで、このようなタイプのノイズについての理解を深めることができます。

行動プロファイル・モデルを理解した後は、持っているデータのすべてで、順にモデルをトレーニングすることができます。

リスト 8. 行動プロファイル・モデルのトレーニング
    behavioral_profiler = SVC(kernel="linear", C=0.025)
    behavioral_profiler.fit(X_data, y_target)

行動プロファイル・モデルを試す

この時点で、モデルがどのように機能するのかを調べるために、架空の商品説明を入力してモデルをいろいろと試してみて構いません。

リスト 9. モデルの試用
print behavioral_profiler.predict(vectorizer.transform(['Some black 
Bauhaus shoes to go with your Joy Division hand bag']).toarray()[0])

このモデルが実際に、['goth'] を返すことに注目してください。Bauhaus という単語を削除してもう一度実行すると、今後は ['punk'] を返すはずです。


行動モデルを顧客に適用する

いよいよ、トレーニングしたモデルを、顧客とその顧客が購入した商品の説明に適用します。

リスト 10. トレーニング後のモデルを、顧客とその顧客が購入した商品の説明に適用する
predicted_profiles=[ ]
ground_truth=[ ]
for c in customers:
    customer_prod_descs = ' '.join(p.description for p in 
c.product_descriptions)
    predicted =   behavioral_profiler.predict(vectorizer
.transform([customer_product_descriptions]).toarray()[0])
    predicted_profiles.append(predicted[0])
    ground_truth.append(c.type)
    print "Customer %d, known to be %s, was predicted to 
be %s" % (c.id,c.type,predicted[0])

最後に、精度を計算して、買い物客のプロファイルの作成に成功した頻度を確認します。

リスト 11. 精度の計算
    a=[x1==y1 for x1, y1 in zip(predicted_profiles,ground_truth)]
    accuracy=float(sum(a))/len(a)
    print "Percent Profiled Correctly %.2f" % accuracy

提供されているデフォルトのプロファイル・データでの結果は、95 パーセントになるはずです。これが実際のデータだとすれば、これはかなり高い精度だということになります。


モデルを拡張する

モデルを作成してテストが完了した今、何百万件もの顧客プロファイルにこのモデルを適用することが可能です。MapReduce フレームワークを使用すれば、トレーニングされた行動プロファイルをワーカー・ノードに送信することができます。その場合、各ワーカー・ノードが、購入履歴を含む顧客プロファイルのバッチを受け取り、モデルを適用します。その結果を保存した時点で、モデルの適用が完了し、顧客が行動プロファイルに割り当てられます。このようなプロファイルの割り当ては、さまざまな方法で利用できます。例えば、カスタマイズされたプロモーションを持つ顧客を対象にすることにしたり、これらのプロファイルを商品推奨システムへの入力として使用したりする場合などが考えられます。

参考文献

学ぶために

製品や技術を入手するために

  • bpro パッケージをダウンロードしてください。
  • scikit-learn.org にアクセスして、カスタム・トークナイザーの見事な例を調べてください。
  • SciPy Superpak: OS X 向けの基本的な Python 科学計算パッケージの最新ビルド。
  • Apache.org から Hadoop 0.20.1 を入手してください
  • Hadoop MapReduce を入手してください。
  • 皆さんの次のオープンソース開発プロジェクトを IBM ソフトウェアの試用版を使用して革新してください。ダウンロード、あるいは DVD で入手することができます。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Open source
ArticleID=977541
ArticleTitle=Python、SciKit、およびテキスト分類を利用して行動プロファイルを作成する
publish-date=07172014