機械学習を使用したQuery Serviceでのボットフィルタリング

ボットの動作は、分析指標に影響を与え、データの整合性を損なう可能性があります。 Adobe Experience Platform Query Serviceは、ボットフィルタリングのプロセスを通じてデータ品質を維持するために使用できます。

ボットフィルタリングを使用すると、web サイトとの人間ではない相互作用から生じるデータ汚染を広く削除することで、データ品質を維持できます。 このプロセスは、SQL クエリとマシンラーニングを組み合わせることで実現します。

ボットアクティビティは、さまざまな方法で識別できます。 このドキュメントで取られたアプローチは、アクティビティスパイク、この場合は特定の期間内にユーザーが実行したアクションの数に焦点を当てています。 最初に、SQL クエリは、ボットアクティビティとして認定されるまでの期間に実行されたアクションの数のしきい値を任意に設定します。 このしきい値は、マシンラーニングモデルを使用して動的に調整され、これらの比率の精度が向上します。

このドキュメントでは、SQL ボットフィルタリングクエリの概要と詳細な例、および環境でプロセスを設定するために必要なマシンラーニングモデルについて説明します。

はじめに

このプロセスの一環として、マシンラーニングモデルをトレーニングする必要があります。このドキュメントでは、1つ以上のマシンラーニング環境に関する実用的な知識を前提としています。

この例では、Jupyter Notebookを開発環境として使用しています。 利用可能なオプションは多数ありますが、Jupyter Notebookは計算要件が低いオープンソースのweb アプリケーションであるため、お勧めします。 公式サイトから​ ダウンロードできます

Query Serviceを使用して、ボット活動のしきい値を定義します

ボット検出用のデータ抽出に使用される2つの属性は次のとおりです。

  • Experience Cloud訪問者ID (ECID、MCIDとも呼ばれます):これは、すべてのAdobe ソリューションの訪問者を識別する、ユニバーサルで永続的なIDを提供します。
  • タイムスタンプ:Web サイトでアクティビティが発生した日時をUTC形式で指定します。
NOTE
mcidの使用は、次の例に示すように、Experience Cloud訪問者IDへの名前空間参照で引き続き見つかります。

次のSQL ステートメントは、ボットアクティビティを識別するための最初の例を示しています。 このステートメントは、訪問者が1分以内に50回クリックした場合、そのユーザーはボットであると仮定しています。

SELECT *
FROM   <YOUR_TABLE_NAME>
WHERE  enduserids._experience.mcid NOT IN (SELECT enduserids._experience.mcid
                                           FROM   <YOUR_TABLE_NAME>
                                           GROUP  BY Unix_timestamp(timestamp) /
                                                     60,
                                                     enduserids._experience.mcid
                                           HAVING Count(*) > 50);

この式は、しきい値を満たすが、他の間隔からのトラフィックの急増に対処しないすべての訪問者のECID (mcid)をフィルタリングします。

マシンラーニングによるボット検出の強化

初期のSQL文を絞り込んで、マシンラーニング用の特徴抽出クエリにすることができます。 改善されたクエリは、マシンラーニングモデルを高精度でトレーニングするための様々な間隔で、より多くの機能を生成する必要があります。

サンプル文は、最大60回のクリックで1分から拡張され、クリック数がそれぞれ300と1800の5分と30分の期間が含まれます。

このステートメントの例では、さまざまな期間における各ECID (mcid)の最大クリック数を収集します。 最初のステートメントは、1分(60秒)、5分(300秒)、1時間(1800秒)の期間を含むように拡張されました。

SELECT table_count_1_min.mcid AS id,
       count_1_min,
       count_5_mins,
       count_30_mins
FROM   ( ( (SELECT mcid,
                 Max(count_1_min) AS count_1_min
          FROM   (SELECT enduserids._experience.mcid.id AS mcid,
                         Count(*)                       AS count_1_min
                  FROM
       <YOUR_TABLE_NAME>
                  GROUP  BY Unix_timestamp(timestamp) / 60,
                            enduserids._experience.mcid.id)
          GROUP BY mcid) AS table_count_1_min
           LEFT JOIN (SELECT mcid,
                             Max(count_5_mins) AS count_5_mins
                      FROM   (SELECT enduserids._experience.mcid.id AS mcid,
                                     Count(*)                       AS
                                     count_5_mins
                              FROM
           <YOUR_TABLE_NAME>
                              GROUP  BY Unix_timestamp(timestamp) / 300,
                                        enduserids._experience.mcid.id)
                      GROUP  BY mcid) AS table_count_5_mins
                  ON table_count_1_min.mcid = table_count_5_mins.mcid )
         LEFT JOIN (SELECT mcid,
                           Max(count_30_mins) AS count_30_mins
                    FROM   (SELECT enduserids._experience.mcid.id AS mcid,
                                   Count(*)                       AS
                                   count_30_mins
                            FROM
         <YOUR_TABLE_NAME>
                            GROUP  BY Unix_timestamp(timestamp) / 1800,
                                      enduserids._experience.mcid.id)
                    GROUP  BY mcid) AS table_count_30_mins
                ON table_count_1_min.mcid = table_count_30_mins.mcid )

この式の結果は、次の表のようになります。

id
count_1_min
count_5_min
count_30_min
4833075303848917832
1
1
1
1469109497068938520
1
1
1
5045682519445554093
1
1
1
7148203816406620066
3
3
3
1013065429311352386
1
1
1
3077475871984695013
7
7
7
4151486040344674930
2
2
2
6563366098591762751
6
6
6
2403566105776993627
4
4
4
5710530640819698543
1
1
1
3675089655839425960
1
1
1
9091930660723241307
1
1
1

マシンラーニングを使用して新しいスパイクしきい値を特定する

次に、結果のクエリデータセットをCSV形式で書き出し、Jupyter Notebookに読み込みます。 その環境から、現在のマシンラーニングライブラリを使用してマシンラーニングモデルをトレーニングできます。 CSV形式で Query Service からデータをエクスポートする方法について詳しくは、トラブルシューティングガイドを参照してください

最初に設定されたアドホックスパイクのしきい値はデータ主導ではないため、精度が不足しています。 マシンラーニングモデルは、パラメーターのしきい値をトレーニングするために使用できます。 その結果、不要な機能を削除してGROUP BY キーワードの数を減らすことで、クエリの効率を高めることができます。

この例では、デフォルトでJupyter NotebookとともにインストールされるScikit-Learn機械学習ライブラリを使用します。 「pandas」のpython ライブラリもここで使用するために読み込まれます。 次のコマンドがJupyter Notebookに入力されます。

import pandas as ps

df = pd_read.csv('data/bot.csv')
df = df[df['count_1-min'] > 1]
df['is_bot'] = 0
df.loc[df['count_1_min'] > 50,'is_bot'] = 1
df

次に、データセットで決定木の分類子を訓練し、モデルから得られるロジックを観察する必要があります。

以下の例では、「Matplotlib」ライブラリを使用して、決定木の分類子を視覚化しています。

from sklearn.tree import DecisionTreeClassifier
from sklearn import tree
from matplotlib import pyplot as plt

X = df.iloc[:,:[1,3]]
y = df.iloc[:,-1]

clf = DecisionTreeClassifier(max_leaf_nodes=2, random_state=0)
clf.fit(X,y)

print("Model Accuracy: {:.5f}".format(clf.scre(X,y)))

tree.plot_tree(clf,feature_names=X.columns)
plt.show()

この例のJupyter Notebookから返される値は次のとおりです。

Model Accuracy: 0.99935

機械学習モデル Jupyter Notebookからの統計的な出力。

上の例に示されているモデルの結果は、99%以上の精度です。

決定木の分類子は、スケジュールされたクエリを使用して定期的にQuery Serviceのデータを使用してトレーニングできるため、ボットのアクティビティを高い精度でフィルタリングすることで、データの整合性を確保できます。 マシンラーニングモデルから派生したパラメーターを使用することで、モデルによって作成された高精度なパラメーターで元のクエリを更新できます。

このモデルの例では、5分間に130回を超えるインタラクションがある訪問者はボットであると高い精度で判断されています。 この情報を使用して、ボットフィルターSQL クエリを絞り込むことができます。

次の手順

このドキュメントでは、Query Serviceと機械学習を使用してボットのアクティビティを決定およびフィルタリングする方法について詳しく説明します。

組織の戦略的ビジネスインサイトにQuery Serviceのメリットを示すその他の文書には、放棄された参照ユースケース ​があります。

recommendation-more-help
experience-platform-help-query-service