Oracle® Fusion Middleware Oracle Real-Time Decisionsプラットフォーム開発者ガイド 11g リリース1 (11.1.1) B72429-01 |
|
前 |
次 |
この章では、Oracle RTDが提案する選択肢の有効性に関するフィードバック情報を提供するために選択肢グループ・イベントと選択肢イベント・モデルを構成する方法について説明し、このチュートリアル・セクションを終了します。また、フィードバック情報が様々なデシジョン・センター・レポートでどのように表示されるかも説明します。
前の章では、コール・センター・エージェントが顧客にオファーを提示できるように、オファーをCRMアプリケーションに返すアドバイザを追加しました。顧客へのオファー提示後、顧客がそのオファーを受け入れたかどうかを追跡してから、オファーの提示と受入れのプロセスに関するループをクローズする必要があります。フィードバックのループは、様々な方法によって様々なタイミングでクローズされる場合があります。デシジョンやオファーが実行されてから数日から数週間後にようやく結果が判明することもあります。また、それだけの時間が経過しても、肯定的な結果のみが判明し、否定的な結果は不明な場合が多くあります。フィードバックは、顧客から直接取得される場合もあれば、電話に対応したエージェントから取得される場合、サービス、契約および請求を処理する業務システム、さらにはバッチ・プロセスから取得される場合もあります。
インライン・サービスに対するフィードバック・ループは、インフォーマントの使用を介してReal-Time Decision Serverに通知することでクローズされます。
この章には次のトピックが含まれます:
ほとんどの場合、オファーの存続期間中には、成功を追跡する観点から見て有意義なイベントが複数あります。たとえば、Credit Cardオファーの存続期間では、次のようなイベントが存在する場合があります。
オファーの提示
顧客による興味関心
カード発行の申込み
カードの受領
カードの使用
顧客がクレジット・カードを使用したときが本当の成功と考えることができます。最終的な目標は、顧客がカードに興味を持ち、カードの発行を申込み、カードを受領するだけではなく、より多くの顧客がカードを使用することにあります。カードの使用によって企業に収益がもたらされるからです。
一般的に、オファーの提示直後のイベントは追跡が容易です。たとえば、コール・センターにおいてエージェントがオファーを提示した時点で、顧客が示す興味関心の程度を測定できます。オファーがWebサイトに提示されている場合は、クリック・イベントが興味関心のインジケータになります。
オファーの存続期間の後半にあるイベントほど、オファーを追跡して妥当性を評価することが難しくなる場合があります。そのため、プロジェクトを開始して即座に結果の出るフィードバック・ループのみをクローズし、システムが熟成するにつれて下流のイベントを追加するのが一般的です。Oracle RTDでは、開始直後のフィードバックのみでも、マーケティングの意思決定に大きく貢献できます。
この項には次のトピックが含まれます:
イベントは、選択肢グループのレベルで定義します。イベントはグループ階層の任意のレベルで定義できますが、ルートに近い最上位レベルで定義するのが一般的です。
ここではイベントを2つ作成します。1つはオファーが顧客に提示された事実を示すイベントで、もう1つはオファーが受け入れられた事実を示すイベントです。このチュートリアルでは、アドバイザの結果として選択されたすべてのオファーが提示され、オファーの受入れがただちに判明することを前提にしています。
選択肢グループにイベントを定義する手順は、次のとおりです。
「インライン・サービス・エクスプローラ」の「選択肢」で、「Cross Selling Offer」選択肢グループをダブルクリックします。
「選択肢イベント」タブを選択します。「追加」をクリックして、イベントを2つ追加します。最初のイベント名は「presented」
(提示)、2番目のイベント名は「accepted」
(受入れ)にします。これらのイベント名は単なるラベルで、オファーの内部状態には対応しないことに注意してください。これらのイベントは選択肢イベント・モデル(次の項で説明)で使用され、これらのイベント名はそこで意味を持ちます。
イベントごとに、ドロップダウン・リストを使用して、「統計コレクタ」を「選択肢イベント統計コレクタ」に設定します。これはデフォルトの統計コレクタです。このコレクタによって、各イベントに関する統計が収集されます。
「イベント履歴(日数)」が「セッション継続時間」に設定されていることを確認します。
「値属性」は空欄のままにします。
これは、イベントの自動処理に使用されます。このチュートリアルでは、フィードバック・インフォーマントのロジックによりイベントを記録します。
「ファイル」→「すべて保存」を選択します。
ここまでで、イベントの定義が完了し、統計を追跡する準備が整いました。イベントでは、統計の追跡に加えて、様々な要因(顧客の特性、通話とエージェント、およびオファーの成功や失敗)間における相関関係に関する学習が自己学習モデルにおいて行われます。この知識は次の2つの目的で役立ちます。
マーケティング担当者や営業担当者の洞察力と把握力の向上
様々な状況で最適なオファーを提示する自動予測
このチュートリアルでは、これらの両方に対する使用方法について説明します。
選択肢イベント・モデルを定義する手順は、次のとおりです。
「インライン・サービス・エクスプローラ」で、「モデル」を右クリックしてから、「新規選択肢イベント・モデル」を選択します。新しいモデルの名前をOffer Acceptance Predictor
に設定し、「OK」をクリックします。
モデルのエディタで、「新規選択肢イベント・モデル」の選択を解除し、「時間ウィンドウ」を1週間に設定します。
「選択肢グループ」で「Cross Selling Offer」を選択します。
このグループは選択肢階層の最上位グループで、このモデルを使用してオファーの受入れを追跡します。
「ベース・イベント」で「presented」を選択します。前項で、選択肢グループのこれらのイベント名を定義したことを思い出してください。
このイベントが、成功を測定する対象イベントになります。オファーが受け入れられたかどうかは、オファーの提示後に追跡します。
「正の結果イベント」で、「選択」をクリックして「accepted」を選択し、「OK」をクリックします。このチュートリアルでは、これが唯一の肯定的な結果です。複数のイベントを追跡する場合は、ここで追加します。
必要に応じて、イベントのラベルをオファー指向の名前に変更できます。
選択肢イベント・モデルには、他にも役に立つ設定があります。「属性」タブには重要な設定が2つあります。パーティション化属性と除外属性です。次の各項で、これらの属性などの設定について説明します。
この項には次のトピックが含まれます:
パーティション化属性は、大きく異なる結果をもたらす区分によってモデルを分割する目的で使用されます。たとえば、同じオファーでも、Webでの提示とコール・センターでの提示では、その受入れ特性が大きく異なる可能性があります。このような場合、提示チャネルをパーティション化属性として設定できます。
パーティション化属性は複数設定できますが、メモリー使用量に影響する場合があることに注意してください。各パーティション化属性では、属性値の数だけモデル数が倍増します。たとえば、モデルに3つの値を持つパーティション化属性と4つの値を持つパーティション化属性がある場合、メモリーの使用量はパーティション化でないモデルの12倍になります。それでもそうする意味がある場合は、それによってモデルの予測性能と説明性能が大きく向上するため、必ずパーティション化属性を使用してください。
モデルへの入力として意味がない属性もあります。たとえば、Reason Analysisモデル(第3.1.2項「デシジョン・センターにおける分析結果の表示」を参照)では、入力として理由コードを持つことで、理由コードと通話理由の選択肢との間に相関関係が検出されました。この関係は、第2.9.4項「選択肢の選択のためのロジックの追加」で作成したロジックの当然の結果です。この相関関係は人為的なものであり、有意義な洞察でないため、理由コードをモデルから除外しました。
他のモデルでは理由コードが重要な要素となる場合があるため、除外が適切でない場合があることに注意してください。エンティティ属性レベルではなく、モデル・レベルで理由コード属性を除外(「分析に使用」プロパティの選択を解除)するのはこのためです。エンティティ属性レベルで除外すると、インライン・サービスのすべてのモデルで理由コード属性が除外されます。たとえば、Offer Acceptance Predictorモデルでは、オファーの受入れと理由コードとの間における相関関係に注目する必然性があります。
「場所の学習」タブで、モデルの学習をプロセス内のどのタイミングで実行するかを設定します。ほとんどの場合は、デフォルトの「セッションのクローズ」が適しています。セッションにおいて複数の状態から学習を行う必要があるときは、特定の統合点において学習を設定すると有効な場合があります。
選択肢イベント・モデルの定義が完了し、使用する準備が整いました。モデルに適切な情報を入力するには、ループをクローズするロジックを完成する必要があります。
提案されたオファーをモデルで使用可能にするには、オファーIDをセッションで記憶する必要があります。フロントエンド・クライアントがそれを記憶する場合もあるため、この手順は必須ではありませんが、ここではフロントエンドの機能を前提にしません。オファーの記憶には単純な文字列属性を使用するだけですが、複雑な場合は配列を使用して複数の選択肢を記憶します。
提案されたオファーを記憶する手順は、次のとおりです。
「インライン・サービス・エクスプローラ」で、「エンティティ」の下の「セッション」をダブルクリックします。
「属性の追加」をクリックして属性を追加し、Offer Extended
と命名します。
属性の説明を入力します。「デシジョン・センターで表示」および「分析に使用」の選択を解除します。「OK」をクリックします。
この操作を行う理由は、現時点でこの属性を内部変数として扱い、ビジネス・ユーザーには表示しないためです。
「インライン・サービス・エクスプローラ」で、「統合点」→「アドバイザ」の下にある「Get Cross Sell Offer」をダブルクリックします。
「非同期ロジック」タブで、既存のコードを更新します。presentedイベントを記録してOfferExtendedセッション属性に選択肢IDの値を設定する行を既存のコードに追加します。更新後のコードは次のようになります。
logInfo("Integration Point - Get Cross Sell Offer"); logInfo(" Customer age = " + session().getCustomer().getAge() ); // 'choices' is array returned by the 'Select Offer' decision if (choices.size() > 0) { //Get the first offer from array Choice offer = choices.get(0); //For the selected offer, record that it has been 'presented' offer.recordEvent("Presented"); //Set the session attribute 'OfferExtended' with the offer's ID. session().setOfferExtended(offer.getSDOId()); logInfo(" Offer presented: '" + offer.getSDOLabel() + "'"); }
これにより、選択された選択肢のSDOIdがセッション・エンティティのOfferExtended属性に割り当てられます。SDOIdは一意の識別子です。Oracle RTD構成のすべてのオブジェクトには一意なSDOIdがあります。選択されたオファーのPresentedイベントも記録されます。イベント名は小文字表記で、Presentedの選択肢イベントIDに対応することに注意してください。このIDを表示するには、「インライン・サービス・エクスプローラ」で「選択肢」を開き、「Cross Selling Offer」をダブルクリックします。次に、「選択肢イベント」タブをクリックし、ラベル/IDの切替アイコンをクリックします。
デシジョンの時点で、どのオファーが選択されコール・センター・エージェントによって(Get Cross Sell Offerアドバイザを介して)顧客に提示されたかがセッションにおいて記憶されます。顧客からのレスポンスは判明していません。レスポンスは、次の項で説明するフィードバック・インフォーマントを介して送信されます。
このインフォーマントによりOracle RTDに対して、オファー選択デシジョンの結果評価に必要な情報が提供されます。
フィードバック・インフォーマントを作成する手順は、次のとおりです。
「インライン・サービス・エクスプローラ」で、「統合点」を開いて「インフォーマント」フォルダを右クリックし、「新規インフォーマント」を選択します。インフォーマント名をOffer Feedback
にします。
エディタで、インフォーマントの説明を入力します。「外部システム」で「CRM」を選択します。「順序」に4
を入力します。
セッション・キーをOffer Feedbackインフォーマントに追加するには、「セッション・キー」の横にある「選択」をクリックします。「customerId」を選択し、「OK」をクリックします。
「追加」をクリックして入力パラメータを追加します。パラメータ名をPositive
にします。
データ型が「String」でない場合は選択し、「OK」をクリックします。
パラメータはマップされないままにします。このパラメータにセッション属性へのマッピングが不要なのは、この引数がオファーの受入れの成否を即時に判定する目的で使用されるためです。オファーの受入れは、yes値によって示されます。
「ロジック」タブの「ロジック」に次のコードを入力し、受入れイベントの発生時に記録されるようにします。
logInfo("Integration Point - Offer Feedback"); //"yes" or "no" to accept offer. String positive = request.getPositive(); positive = positive.toLowerCase(); //Get the offer id from session attribute 'OfferExtended' String extendedOfferID = session().getOfferExtended(); if (extendedOfferID != null) { //Get the offer from choice group 'Cross Selling Offer' Choice offer = CrossSellingOffer.getChoice(extendedOfferID); if (offer != null){ String offerId = offer.getSDOId(); //If response is "yes", then record the offer as accepted. if (positive.equals("yes")) { offer.recordEvent ("Accepted"); logInfo(" Offer '" + offer.getSDOLabel() + "' accepted"); } } }
すべてを保存し、インライン・サービスを再デプロイします。「デプロイ」ダイアログで、「アクティブ・セッション(テスト用として使用)の終了」を選択します。
次の図に、Get Cross Sell Offerアドバイザがオファーを取得および提示してから、Offer Feedbackインフォーマントがオファーを受け入れるか拒否するまでのフローを示します。Call Endインフォーマントによってセッションがクローズされると、Offer Acceptance PredictorモデルがオファーのPresentedイベントまたはAcceptedイベントによって更新されます。
図5-1 Tutorialインライン・サービスのオブジェクト: アドバイザおよびインフォーマントのフロー
Offer Feedbackインフォーマントをテストするには、最初にGet Cross Sell Offerをコールしてオファーを取得して提示する必要があります。
フィードバック・インフォーマントをテストする手順は、次のとおりです。
「テスト」ビューで、Get Cross Sell Offer統合点を選択します。「customerId」に10
などの値を入力します。
「送信」アイコンをクリックします。
「レスポンス」サブタブでオファーが取得されたことを確認します。「ログ」サブタブには、次のような結果が表示されます。
00:45:28,466 Integration Point - Get Cross Sell Offer 00:45:28,466 Customer age = 38 00:45:28,466 Offer presented: 'Credit Card'
他の値を「customerId」に入力しても、提示されるオファーは必ずSavings AccountかCredit Cardのどちらかになります。これは、この段階ではパフォーマンス目標をコストの最小化に対してのみ構成しており、顧客の年齢に応じてSavings AccountまたはCredit Cardが最小コストとなるためです。
「統合点」ドロップダウン・リストから、「Offer Feedback」インフォーマントを選択します。同一セッションで手順を続行するため、「customerId」の値はそのままにします。入力の「Positive」に、yes
などの値を入力します。
「送信」をクリックし、Get Cross Sell Offerアドバイザによって取得されたオファーが受け入れられたことを「ログ」サブタブで確認します。次のようなマップが表示されます。
00:46:01,418 Integration Point - Offer Feedback 00:46:01,418 Offer 'Credit Card' accepted
入力の「Positive」値をno
に変更し、Offer Feedbackインフォーマントを再送信します。「ログ」サブタブの内容は次のようになります。
00:47:31,494 Integration Point - Offer Feedback
ロード・ジェネレータ・スクリプトを更新して、Get Cross Sell OfferアドバイザおよびOffer Feedbackインフォーマントに対するコールを追加します。これらの統合点コールは、ServiceCompleteインフォーマントの後からCallEndインフォーマント(セッションをクローズするインフォーマント)の前までに実行される必要があることに注意してください。ロジックは次のとおりです。1) コールが開始します。2) 標準サービスが完了します。ReasonAnalysisモデルを使用して通話理由を記録および分析します。3) エージェントがコスト最小化目標に基づいて抱合せ販売オファーを顧客に提示します。4) オファーを顧客が受け入れたかどうかを記録します。5) コール/セッションが終了し、OfferAcceptancePredictorモデルがオファーの提示や受入れについて学習します。
Get Cross Sell Offerアドバイザをロード・ジェネレータ・スクリプトに追加する手順は、次のとおりです。
RTD_HOME
\scripts\loadgen.cmd
を実行することで、ロード・ジェネレータを開きます。そして、以前のスクリプトを開きます。
「スクリプトの編集」タブを選択し、左側のツリー・ビューを右クリックして「アクションの追加」を選択します。アクションのタイプを「メッセージ」に、統合点の名前をGetCrossSellOfferにそれぞれ設定します。
「入力フィールド」で右クリックして「項目の追加」を選択し、入力フィールドを追加します。「名前」の下のスペースをクリックしてcustomerIdを入力してから、[Enter]を押します。
入力フィールドの「変数」をクリックし、ドロップダウン・リストを使用して、対応する変数のvar_customerId(詳細は第3.1.1項「ロード・ジェネレータ・スクリプトの作成」を参照)を選択します。「セッション・キー」を選択して、customerIdをセッション・キーとしてマークします。
このアクションをスクリプトに追加すると、アクション・リストの下部に追加されます。GetCrossSellOfferがServiceCompleteの後にコールされるように、順序を調整する必要があります。「スクリプトの編集」タブの左側で「GetCrossSellOffer」を右クリックしてから、「上に移動」または「下に移動」を使用して、順序がCallBegin、ServiceComplete、GetCrossSellOffer、CallEndになるようにします。
ロード・ジェネレータ・スクリプトを保存します。
Offer Feedbackインフォーマントをロード・ジェネレータ・スクリプトに追加する手順は、次のとおりです。
OfferFeedbackのコールを「スクリプトの編集」タブで追加する前に、 新しい変数を「変数」タブで作成する必要があります。OfferFeedbackインフォーマントの定義で、パラメータpositiveを使用してオファーの受入れを示していることを思い出してください。ロード・ジェネレータでは、このパラメータの値がランダムにyes(30%の割合)、no(70%の割合)になるように設定します。これには、加重された文字列配列を使用します。
「変数」タブの左側で「スクリプト」フォルダをクリックし、「変数の追加」を選択します。「変数名」に「var_positive」
を入力し、「コンテンツ」のタイプを「加重された文字列配列」に設定します。2つのアイテムを配列に追加します(コンテンツ・タイプの下のスペースを右クリックし、「項目の追加」を選択)。最初のアイテムでは、「加重」セルをダブルクリックして編集可能にし、値として30
を入力し、対応する「文字列」セルに値としてyes
を入力します。2番目のアイテムでは、加重値を70
にし、文字列値をno
にします。加重値は合計を100にする必要はありません。自動的に正規化されます。加重値を6と14にしても、同じ結果となります。
「スクリプトの編集」タブを選択し、左側のツリー・ビューを右クリックして「アクションの追加」を選択します。アクションのタイプを「メッセージ」に、統合点の名前をOfferFeedback
にします。
「入力フィールド」で右クリックして「項目の追加」を選択し、入力フィールドを追加します。「名前」の下のスペースをクリックし、customerIdを追加します。「変数」列で、対応する変数のvar_customerId(詳細は第3.1.1項「ロード・ジェネレータ・スクリプトの作成」を参照)を選択します。「セッション・キー」を選択して、customerIdをセッション・キーとしてマークします。
再び「入力フィールド」で右クリックして「項目の追加」を選択し、入力フィールドを追加します。「名前」の下のスペースをクリックし、positive
を追加します。「変数」列で、対応する変数のvar_positiveを選択します。
このアクションをスクリプトに追加すると、アクション・リストの下部に追加されます。OfferFeedbackがGetCrossSellOfferの後にコールされるように、順序を調整する必要があります。「スクリプトの編集」タブの左側で「OfferFeedback」を右クリックし、「上に移動」または「下に移動」を選択して、順序がCallBegin、ServiceComplete、GetCrossSellOffer、OfferFeedback、CallEndになるようにします。
「セキュリティ」タブで、「ユーザー名」と「パスワード」を入力します。
ロード・ジェネレータ・スクリプトを保存します。
この時点でロード・ジェネレータ・スクリプトを実行できます。実行結果に古いデータが混在しないように、スクリプトを実行する前に既存データを再び削除することをお薦めします。削除方法の詳細は、第3.2項「モデルの学習内容のリセット」を参照してください。
ロード・ジェネレータ・スクリプトを実行した場合は、その結果をデシジョン・センターで参照できます。デシジョン・センターにログインし、「Cross Selling Offer」選択肢グループをクリックし、Offer Acceptance Predictorモデルの結果を表示します。「パフォーマンス」タブ→「カウント」サブタブをクリックします。オファーの分布とパレート図が、図5-4のように表示されます。
図5-4デシジョン・センター→「Cross Selling Offer」→「パフォーマンス」→「カウント」
Credit CardとSavings Accountの2つのオファーのみが提示され、それぞれの受入れ率が約30%になっていることに注意してください。これは、これまでに設定したロジックの当然の結果です。 コスト最小化というパフォーマンス目標のみが満たされ、顧客の年齢に応じてSavings AccountまたはCredit Cardのコストが最小になっています(第4.4項「選択肢のスコアリング」を参照)。ロード・ジェネレータ・スクリプトで、OfferFeedbackインフォーマントによって、オファーへの肯定的なレスポンスが30%の確率で記録されるように指定しました。個々のオファーの分析レポートにドリルダウンすると、オファーの受入れとセッション属性の間には相関関係があまりないことがわかります。これは、ランダムな顧客プロファイル・データを使用し、顧客やその他の属性(通話の長さ、コール・エージェント名、通話理由など)に関係なく、受入れ率が30%になるように強制しているためです。
これまで、パフォーマンス目標を使用して提示オファーを決定する方法と、選択肢イベント・モデルを使用して提示オファーの受入れ率を追跡する方法についてそれぞれ説明しました。これまでに使用したのは、分析に関するモデルのみです。次の項では、2番目のパフォーマンス目標(売上の最大化)を追加し、そのモデルの学習内容を使用して、提示するオファーに影響を与える方法について説明します。また、2人以上の子供を持つ顧客にLife Insuranceオファーが提示された場合に、その受入れ確率を高める人為的なバイアスを導入します。これによって、このバイアスがモデルの結果にどのように影響するかを調べます。
これまでに作成したモデルは、顧客の特性、通話の特性、抱合せ販売の結果の間にある相関関係を学習します。このモデルは、オファー受入れの確率を予測する予測計算にも使用できます。この確率情報を使用することで、提示するオファーを決定する際にオファーの値を調整できます。たとえば、オファーAの受入れ確率がオファーBの2倍と予測される場合は、提示するオファーの選択時に、オファーAを優先するのが妥当です。この項では、2番目のパフォーマンス目標としてMaximize Revenue(売上の最大化)を導入します。その値/スコアは、受入れ確率と売上単価の積として計算します。
たとえば、Brokerage Accountオファーの売上単価が$300で受入れ確率が30% (0.3)と仮定した場合、その売上最大化スコアは$300 x 0.3 = $90になります。Life Insuranceオファーの売上単価は$185で受入れ確率が60% (0.6)と仮定した場合、売上最大化スコアは$185 x 0.6 = $111になります。Brokerage Accountのほうが売上単価の値が高くても、売上最大化スコアが高くなるLife Insuranceオファーを優先して選択するほうが有利になります。
ここでは、コストと売上最大化の両方に基づいて、提示するオファーを選択することに注意してください。前述の例で、コストと売上最大化の重み付けされた合計においてBrokerage AccountがLife Insuranceよりも高い場合は、Brokerage Accountが選択されます。
この項では、最初に売上単価を追加し、その後で2番目のパフォーマンス目標である売上最大化を追加します。次に、売上最大化の目標のスコアとして、売上単価と受入れ確率との積の値を設定します。設定が完了したら、提示するオファーの選択時にコストと売上最大化の両方の目標が適用されるように、Select Offerデシジョンを更新します。最後に、Offer Feedbackに、Life Insuranceオファーの提示先であり特定のプロファイルを持つ顧客に対して、オファー受入れバイアスを導入するロジックを追加します。
この項には次のトピックが含まれます:
売上単価選択肢属性を追加する手順は、次のとおりです。
「インライン・サービス・エクスプローラ」の「選択肢」で、「Cross Selling Offer」選択肢グループをダブルクリックします。「選択肢属性」タブで、「追加」をクリックします。
この属性の名前をRevenueに、データ型をIntegerにそれぞれ設定します。オファーごとに異なる値を割り当てるため、「オーバーライド可能」オプションが選択されていることを確認し、「OK」をクリックします。
「Cross Selling Offer」選択肢グループの各選択肢に、表5-1に示すように、Revenue属性の値を設定します。
このチュートリアルにおける前述の項で、Costパフォーマンス目標を定義しました。ここでは、2番目のパフォーマンス目標としてMaximize Revenueを追加します。この新しいパフォーマンス・メトリックのスコアの計算では、選択肢の受入れ確率と売上単価を使用します。その計算式は、売上単価×受入れ確率=潜在売上スコアとなります。
2番目のパフォーマンス目標を追加する手順は、次のとおりです。
「インライン・サービス・エクスプローラ」で、「パフォーマンス目標」をダブルクリックし、エディタを起動します。「追加」をクリックして、パフォーマンス・メトリックを追加します。メトリック名をMaximize Revenueとし、「OK」をクリックします。
「最適化」で、「最大化」を選択し、メトリックを「必須」にします。コストの$1と売上の$1は等しいため、正規化ファクタは調整不要です。
次に、このメトリックを「Cross Selling Offer」選択肢グループに追加する必要があります。「インライン・サービス・エクスプローラ」で、「Cross Selling Offer」をダブルクリックします。「スコア」タブで「メトリックの選択」をクリックします。「選択」ダイアログで「Maximize Revenue」を選択し、「OK」をクリックします。
Maximize Revenue目標のスコア値を計算するには、Offer Acceptance Predictor選択肢イベント・モデルによって決定される受入れ確率値と売上単価が必要です。この値は、「値の編集」ダイアログで値スコアを「モデル予測」に変更することで取得できます。
パフォーマンス目標であるMaximize Revenueのスコア値を計算する手順は、次のとおりです。
「インライン・サービス・エクスプローラ」の「選択肢」で、「Cross Selling Offer」選択肢グループをダブルクリックします。「スコア」タブで、Maximize Revenueメトリックの「スコア」列→省略記号をクリックし、「値の編集」ダイアログを起動します。
「値ソース」で、「関数またはルール・コール」を選択します。「コールする関数」で、「乗算」関数を選択します。「パラメータ」の表で、aパラメータの「値」セルをクリックします。省略記号をクリックして「属性または変数」を選択します。「選択肢」フォルダを開き、「収益」を選択して「OK」をクリックします。「パラメータ」の表で、bパラメータの「値」セルをクリックします。省略記号をクリックして「モデル予測」を選択します。Offer Acceptance PredictorモデルとAcceptedイベントによって予測される確率を選択し、「OK」をクリックします。「値の編集」ダイアログでもう一度「OK」をクリックします。
実際の確率の値は0から1までの間であり、1は100%の受入れ確率を意味します。この値はNaN (Not a number)になる場合もあり、これは確率値の計算に十分なデータがモデルになかったことを意味します。この場合、Maximize Revenueのスコアは計算不能で、Select Offerデシジョンによるオファー選択は、組込みのスコア計算ロジックに基づきます(スコアが必須かどうかに応じて処理される)。
Maximize Revenueのスコアを選択肢グループ・レベルで定義することで、グループ内のすべての選択肢においてその定義が継承され、選択肢固有の売上単価値と受入れ確率値が実行時に適用されます。
これまで、新しいパフォーマンス・メトリックとその値の計算方法を定義しました。次に、提示するオファーの選択時に両方のパフォーマンス・メトリックが適用されるように、Select Offerデシジョンを更新します。
Select Offerデシジョンを更新する手順は、次のとおりです。
「インライン・サービス・エクスプローラ」で、「デシジョン」フォルダを開き、「Select Offer」をダブルクリックします。
「選択基準」タブの「"Default"セグメントの優先度」表には、パフォーマンス目標のCostのみが100%の重み付け値で表示されます。「目標」をクリックしてパフォーマンス目標の「Maximize Revenue」を選択し、「OK」をクリックします。
優先度の表に、2つのパフォーマンス目標が、それぞれ重み付け値50%で表示されます。デフォルトでは、重み付けは、選択されたすべてのメトリック間で均等に分配されます。Maximize Revenueパフォーマンス目標をCostよりも優先する場合は、このパーセント値を調整して重み付けを高くします。このチュートリアルでは、デフォルトの重み付けの50%を使用します。
表5-2に、Select Offerデシジョンにより特定のオファーに対する合計スコアを計算する例を示します。この例では、オファーのCostスコアを150、Maximize Revenueスコアを215とします。
表5-2 オファーの合計スコアの計算
パフォーマンス目標 | スコア | 重み付け | 最大/最小 | 正規化 | 重み付けされたスコア |
---|---|---|---|---|---|
Cost |
150 |
50% |
最小 |
1 |
-75 |
Maximize Revenue |
215 |
50% |
最大 |
1 |
107.5 |
表5-2の値に基づいて計算されたスコアの合計は32.5になります。Costの重み付けされたスコアは、「最適化」が「最小化」のため負の値になります。オファーの合計スコアは、2つの重み付けされたスコアの加算値です。合計スコアはオファーごとに計算され、最高値を持つオファーが選択されます。
受入れ確率の値を表示するには、対応する選択肢属性を追加し、logInfoを介して表示するか、「テスト」ビューの「レスポンス」タブに表示します。
選択肢属性を追加する手順は、次のとおりです。
「インライン・サービス・エクスプローラ」の「選択肢」で、「Cross Selling Offer」選択肢グループをダブルクリックします。「選択肢属性」タブで、「追加」をクリックして属性を追加します。プロパティ・ダイアログで、「ラベルの表示」をLikelihood Of Acceptanceに設定します。「ラベルの表示」をDoubleに設定します。
この選択肢グループ内のすべての選択肢によってこの属性に同じ定義が使用されるため、「オーバーライド可能」オプションの選択を解除します。「クライアントへ送信」オプションを選択し、「OK」をクリックします。
Likelihood Of Acceptance属性の「値」列で、省略記号をクリックし、その値を設定します。「値の編集」ダイアログで、「値ソース」を「モデル予測」に設定します。Offer Acceptance PredictorモデルとAcceptedイベントを選択し、「OK」をクリックします。
インライン・サービスに対するすべての変更を保存します。
受入れ確率値を表示するには、次に示すように、logInfo文をGet Cross Sell Offerアドバイザに追加します。
「インライン・サービス・エクスプローラ」で、「統合点」→「アドバイザ」の下にある「Get Cross Sell Offer」フォルダをダブルクリックします。
「非同期ロジック」タブで、受入れ確率の値を出力する行を追加して、既存コードを更新します。更新後のコードは次のようになります。
logInfo("Integration Point - Get Cross Sell Offer"); logInfo(" Customer age = " + session().getCustomer().getAge() ); // 'choices' is array returned by the 'Select Offer' decision. The // name 'choices' was set (and can be changed) in the 'Choice Array' // text box in the 'Select Offer' decision's 'Pre/Post Selection // Logic' tab. if (choices.size() > 0) { //Get the first offer from array Choice offer = choices.get(0); //For the selected offer, record that it has been 'presented' offer.recordEvent("Presented"); //Set the session attribute 'OfferExtended' with the offer's ID. session().setOfferExtended(offer.getSDOId()); logInfo(" Offer presented: '" + offer.getSDOLabel() + "'"); //Cast selected offer to type CrossSellingOfficeChoice - //the base Choice type of choice group 'Cross Selling Offer' CrossSellingOfferChoice cso = (CrossSellingOfferChoice) offer; logInfo(" Likelihood of Acceptance = " + cso.getLikelihoodOfAcceptance()); }
アドバイザの変更結果を確認するには、すべてを保存し、インライン・サービスをデプロイします。
「テスト」ビューで、Get Cross Sell Offer統合点を選択し、「customerId」に8
などの値を入力します。「送信」をクリックします。「テスト」ビューの「レスポンス」サブタブに、図5-6に示すような結果が表示されます。
「ログ」サブタブには、次のような結果が表示されます。
14:07:37,908 Integration Point - Get Cross Sell Offer 14:07:37,908 Customer age = 57 14:07:37,908 Offer presented: 'Savings Account' 14:07:37,908 Likelihood of Acceptance = 0.30354643094453865
Likelihood Of AcceptanceでNaN (Not A Number)値を取得した場合は、受入れ確率値の計算に十分なデータがモデルにないことを意味します。モデルの収束(受入れ確率値がNaNでなくなる)に必要な反復実行回数は、アプリケーションとデータの質によって異なります。
このケースでは、オファーの受入れ確率を30%にして(第5.1.7項「ロード・ジェネレータ・スクリプトの更新」を参照)、ランダムな顧客プロファイル・データを使用するため、Offer Acceptance Predictorモデルは短時間で収束し、数百回の反復実行で受入れ確率を計算できます。モデルが収束する前に、オファー選択プロセスは、組込みのスコア計算ロジックに基づいて決定します(スコアが必須かどうかに応じて処理される)。
次の図に、各オファーの合計スコアをCostとMaximize Revenueの2つのスコアの重み付けされた合計として、Get Cross Sell OfferアドバイザがCross Selling Offer選択肢グループからオファーを取得するフローを示します。
これまで、Offer Feedbackインフォーマントにおいて、提示されたオファーが受け入れられたかどうかを示すPositiveインフォーマント・パラメータを指定しました。次に、このインフォーマントがコールされたときに、Positiveパラメータにyesの値が30%の割合で渡されるように、ロード・ジェネレータ・スクリプトを更新しました(第5.1.7項「ロード・ジェネレータ・スクリプトの更新」を参照)。このパーセント値は顧客のプロファイル・データによって変わらないため、どのような顧客に対しても、提示されたすべてのオファーの受入れ確率が30%程度になります。
この段階でロード・ジェネレータ・スクリプトを実行しても、モデルによって、顧客属性とオファー受入れとの間において密接な相関関係が示されることはありません。ここでは、2人以上の子供を持つ顧客にLife Insuranceオファーが提示された場合に、肯定的なオファー受入れをOffer Feedbackインフォーマントのロジックに必ず記録する人為的なバイアスを導入します。このロジックでは、デフォルトの受入れ確率(ロード・ジェネレータ・スクリプトに定義済)に加えて、Life Insuranceオファーの受入れ確率を30%よりも高い値に偏向させます。デシジョン・センターでは、子供の数とこのオファーの受入れ確率との間に明確な相関関係が見られるようになります。
オファー受入れバイアスを導入する手順は、次のとおりです。
「インライン・サービス・エクスプローラ」で、「統合点」→「インフォーマント」の下にある「Offer Feedback」をダブルクリックします。
「ロジック」タブで、2人以上の子供を持つ顧客にLife Insuranceオファーが提示された場合にオファー受入れバイアスを追加する行を追加して、既存コードを更新します。更新後のコードは次のようになります。
logInfo("Integration Point - Offer Feedback"); //"yes" or "no" to accept offer. String positive = request.getPositive(); positive = positive.toLowerCase(); //Get the offer id from session attribute 'OfferExtended' String extendedOfferID = session().getOfferExtended(); if (extendedOfferID != null) { //Get the offer from choice group 'Cross Selling Offer' Choice offer = CrossSellingOffer.getChoice(extendedOfferID); if (offer != null){ String offerId = offer.getSDOId(); //Introduce artificial bias for customers with 2 or more //children to always accept "LifeInsurance" if it was //selected after scoring. //If data source is Oracle, change the following method from //getNumberOfChildren() to getNumberofchildren() int numOfChildren = session().getCustomer().getNumberOfChildren(); if ( numOfChildren >= 2 && offerId.equals("LifeInsurance")) { positive="yes"; } //If response is "yes", then record the offer as accepted. if (positive.equals("yes")) { offer.recordEvent ("Accepted"); logInfo(" Offer '" + offer.getSDOLabel() + "' accepted"); } } }
すべての変更を保存し、インライン・サービスをデプロイします。
第5.1.7項「ロード・ジェネレータ・スクリプトの更新」で、Get Cross Sell OfferアドバイザとOfferFeedbackインフォーマントが含まれるようにロード・ジェネレータ・スクリプトを更新しました。この時点では、オファー選択プロセスは、コストの最小化というパフォーマンス目標にのみ基づいていました。次に、2番目のパフォーマンス目標として売上の最大化を追加し、それにOffer Acceptance Predictorモデルによって計算される受入れ確率の予測値を使用しました。これによってオファー選択プロセスは、両方のパフォーマンス目標に基づくことになります。さらに、特定のプロファイルに合致する顧客にLife Insuranceオファーが提示された場合の受入れバイアスを導入しました。ここで、ロード・ジェネレータ・スクリプトを再度実行して、結果を確認します。
ロード・ジェネレータ・スクリプトを実行する手順は、次のとおりです。
第3.2項「モデルの学習内容のリセット」の手順1から7の説明に従って、Enterprise ManagerのOracle RTD用のシステムMBeanブラウザを使用して、このインライン・サービスの操作データをすべて削除します。
ロード・ジェネレータを起動し、前の項で定義したロード・ジェネレータ・スクリプトを開きます。変更は不要です。
「セキュリティ」タブで、「ユーザー名」と「パスワード」を入力し、ロード・ジェネレータ・スクリプトを開始します。約200回スクリプト実行後、「一時停止」アイコンをクリックし、サーバーへのリクエストの送信を一時的に停止します。
RTD_RUNTIME_HOME\logディレクトリにあるサーバー・ログ・ファイルでサーバーの出力を確認します。サーバー・ログ・ファイルの一般的な名前は、server_name
-diagnostic
[-<n>]
.log
です。
すべてのセッションでは、出力された受入れ確率値がNaNになります。これは、受入れ確率値を計算できるだけ十分なデータの学習がモデルにおいて行われていないことを意味します。確率値がなくても、オファーは提示されることに注意してください。オファーは、組込みのスコア計算ロジックを使用して選択されます。
ロード・ジェネレータ・スクリプトの一時停止を解除し、実行回数が2000回になるまでスクリプトを実行します。今回は、サーバー出力に受入れ確率の実際値が出力されます。Life Insurance以外のすべてのオファーでは0.3前後になりますが、Life Insuranceオファーでは導入したバイアスの結果として値が高くなります。
特定のオファーで、モデルが予測する受入れ確率値が顧客のプロファイルに応じて異なることに注目することが重要です。たとえば、顧客が2人(JohnとTom)いて、子供の数のみが異なると仮定します。2人の顧客のLife Insuranceオファーに対する受入れ確率値を調べると(ある時点でのスナップショットとして)、表5-3に示すように、Tomの値のほうが高いことが判明します。これは、Tomには3人の子供がいて、Life Insuranceオファーが提示された場合の受入れ確率が高くなることによります。
顧客に提示されるオファーはCostスコアとMaximize Revenueスコアの組合せに基づいて決定され、オファーごとにモデルによって予測される受入れ確率値にMaximize Revenueが基づくため、2人以上の子供を持つ顧客ではLife InsuranceオファーのMaximize Revenue値が高くなり、結果として、こうした顧客に対しては、他のオファーよりもLife Insuranceの提示率(さらには受入れ率)が高くなります。
ロード・ジェネレータの実行結果を参照するには、デシジョン・センターにログインします。「Cross Selling Offer」選択肢グループを左側のナビゲーション・ボックスでクリックします。ここにOffer Acceptance Predictorモデルの結果が表示されます。「パフォーマンス」タブ→「カウント」サブタブをクリックします。図5-8に示すような結果が表示されます。
図5-8 「Cross Selling Offer」選択肢グループの「パフォーマンス」→「カウント」
デシジョン・センターの表はオファーの分布(つまり、オファーごとの提示数と受入れ数)を示しています。Life Insurance以外のすべてのオファーでは、図5-8に示すように、受入れ率が30%前後になっています。これは、ロード・ジェネレータ・スクリプトの設定の当然の結果です(第5.1.7項「ロード・ジェネレータ・スクリプトの更新」を参照)。Life Insuranceの受入れ率は30%よりも高くなっています。これは、 第5.2.7項「特定の顧客に対するオファー受入れバイアスの導入」で人為的なバイアスを導入したためです。このバイアスによって、30%の顧客がすべてのオファーを受入れることに加えて、2人以上の子供を持つ顧客がLife Insuranceをオファーされた場合は必ずそのオファーを受け入れるようにしています。
人為的なバイアスを加えたことで、Life InsuranceオファーではNumberOfChildren属性がオファー受入れの重要な指標となることが、モデル結果に反映されます。デシジョン・センター・レポートで、このことを確認できます。Cross Selling Offer選択肢グループ→「分析」タブ→「ドライバ」サブタブをクリックします。「レポート設定」セクションで、「最小予測」の値を0に変更し、「実行」をクリックします。属性の一覧が、予測値の高い順に表示されます。「最大予測」の最高値は、NumberOfChildren属性になります。この属性が、追加した唯一の人為的なバイアスのためです。対応するオファーは、図5-9の画像のようにLife Insuranceになります。
Life Insuranceオファー固有のレポートを表示することで、このオファーに対してNumberOfChildren属性が持つ重要性をさらに分析できます。デシジョン・センターのナビゲーション・ボックスで、「Cross Selling Offer」選択肢グループを開き、選択肢の「Life Insurance」→「分析」タブ→「ドライバ」タブをクリックします。このレポートには、この特定のオファー(Life Insurance)の受入れに対する重要な誘因が示されます。
「レポート設定」セクションで、「最小予測」の値を0
に変更し、「実行」をクリックします。属性の一覧が、「予測」値の順に表示されます。NumberOfChildren属性の予測値が最も高くなっています。属性名をクリックして詳細レポートを表示します。その中の1つに、図5-10に示すようなグラフが表示されます。
図5-10に示すグラフは、NumberOfChildrenの値が2以上の場合、オファー受入れと密接な正の相関関係があることを示しています。これは、この属性値(2以上)の場合、このオファーの受入れ数が期待値よりも大きくなることを意味します。同様に、値が0または1の場合も相関関係が非常に密接になりますが、この相関関係は負で、子供がいないか子供が1人の顧客には期待するほどLife Insuranceオファーが受け入れられないことを意味します。