チュートリアル: Evidently のサンプルアプリケーションを使用した A/B テスト
重要
サポート終了通知: 2025 年 10 月 16 日、AWS は CloudWatch Evidently のサポートを終了します。2025 年 10 月 16 日以降、Evidently コンソールまたは Evidently リソースにアクセスできなくなります。
このセクションでは、A/B テストに Amazon CloudWatch Evidently を使用するチュートリアルを提供します。このチュートリアルでは、シンプルな React アプリケーションである Evidently のサンプルアプリケーションを使用します。サンプルアプリケーションで、showDiscount
機能を表示するかどうかを設定します。ユーザーがこの機能を表示すると、ショッピングサイトで表示される価格が 20% の割引価格で表示されます。
このチュートリアルでは、一部のユーザーに割引を表示して他のユーザーには表示しなくすることに加え、両方のバリエーションからページのロード時間のメトリクスを収集するように Evidently を設定します。
警告
このシナリオでは、プログラムによるアクセスと長期的な認証情報を持つ IAM ユーザーが必要です。これはセキュリティ上のリスクをもたらします。このリスクを軽減するために、これらのユーザーにはタスクの実行に必要な権限のみを付与し、不要になったユーザーを削除することをお勧めします。アクセスキーは、必要に応じて更新できます。詳細については、「IAM ユーザーガイド」の「アクセスキーの更新」を参照してください。
ステップ 1: サンプル アプリケーションのダウンロード
まず、Evidently のサンプルアプリケーションをダウンロードします。
サンプルアプリケーションをダウンロードするには
次の Amazon S3 バケットから、サンプルアプリケーションをダウンロードします。
https://evidently-sample-application.s3.us-west-2.amazonaws.com/evidently-sample-shopping-app.zip
パッケージを解凍します。
ステップ 2: Evidently エンドポイントの追加と認証情報の設定
次に、以下の例のように、サンプルアプリケーションのパッケージの src
ディレクトリにある config.js
ファイルに、Evidently の リージョンとエンドポイントを追加します。
evidently: { REGION: "us-west-2", ENDPOINT: "https://evidently.us-west-2.amazonaws.com (https://evidently.us-west-2.amazonaws.com/)", },
また、アプリケーションに CloudWatch を呼び出すためのアクセス許可があることを確認する必要があります。
サンプルアプリケーションに Evidently を呼び出すためのアクセス許可を付与するには
AWS アカウントにフェデレートします。
IAM ユーザーを作成し、AmazonCloudWatchEvidentlyFullAccess ポリシーをそのユーザーにアタッチします。
次のステップで必要になるため、IAM ユーザーのアクセスキー ID とシークレットアクセスキーを書きとめておきます。
次の例のように、このセクションの前半で変更したものと同じ
config.js
ファイルに、アクセスキー ID とシークレットアクセスキーの値を入力します。credential: { accessKeyId: "
Access key ID
", secretAccessKey: "Secret key
" }重要
このステップを使用すると、サンプルアプリケーションを可能な限り簡単に試すことができます。実際の本番アプリケーションに IAM ユーザーの認証情報を組み込むことはお勧めしません。代わりに、Amazon Cognito を認証に使用することをお勧めします。詳細については、「Amazon Cognito のウェブアプリケーションとモバイルアプリケーションとの統合」を参照してください。
ステップ 3: 機能評価用のコードをセットアップする
CloudWatch Evidently を使用して機能を評価する場合は、[EvaluateFeature] オペレーションを使用して、ユーザーセッションごとに機能のバリエーションをランダムに選択する必要があります。このオペレーションは、実験で指定した割合に従って、機能の各バリエーションにユーザーセッションを割り当てます。
ブックストアデモアプリケーションの機能評価コードをセットアップするには
サンプルアプリケーションが Evidently を呼び出せるようにするために、
src/App.jsx
ファイルにクライアントビルダーを追加します。import Evidently from 'aws-sdk/clients/evidently'; import config from './config'; const defaultClientBuilder = ( endpoint, region, ) => { const credentials = { accessKeyId: config.credential.accessKeyId, secretAccessKey: config.credential.secretAccessKey } return new Evidently({ endpoint, region, credentials, }); };
const App
コードセクションに以下を追加して、クライアントを起動します。if (client == null) { client = defaultClientBuilder( config.evidently.ENDPOINT, config.evidently.REGION, );
次のコードを追加して、
evaluateFeatureRequest
を作成します。このコードで、チュートリアルの後半で推奨するプロジェクト名と機能名を事前に入力しておきます。Evidently コンソールでプロジェクト名と機能名を指定すれば、独自のプロジェクト名と機能名に置き換えることができます。const evaluateFeatureRequest = { entityId: id, // Input Your feature name feature: 'showDiscount', // Input Your project name' project: 'EvidentlySampleApp', };
機能評価のために Evidently を呼び出すコードを追加します。リクエストが送信されると、Evidently は
showDiscount
機能を表示するかどうかを指定するためにユーザーセッションをランダムに割り当てます。client.evaluateFeature(evaluateFeatureRequest).promise().then(res => { if(res.value?.boolValue !== undefined) { setShowDiscount(res.value.boolValue); } getPageLoadTime() })
ステップ 4: 実験メトリクスのコードのセットアップ
カスタムメトリクスの場合は、Evidently のPutProjectEvents
API を使用してメトリクスの結果を Evidently に送信します。次の例では、カスタムメトリクスを設定し、実験データを Evidently に送信する方法を示しています。
以下の関数を追加してページのロード時間を計算し、PutProjectEvents
を使用してメトリクスの値を Evidently に送信します。次の機能を Home.tsx
に追加し、EvaluateFeature
API でこの関数を呼び出します。
const getPageLoadTime = () => { const timeSpent = (new Date().getTime() - startTime.getTime()) * 1.000001; const pageLoadTimeData = `{ "details": { "pageLoadTime": ${timeSpent} }, "UserDetails": { "userId": "${id}", "sessionId": "${id}"} }`; const putProjectEventsRequest = { project: 'EvidentlySampleApp', events: [ { timestamp: new Date(), type: 'aws.evidently.custom', data: JSON.parse(pageLoadTimeData) }, ], }; client.putProjectEvents(putProjectEventsRequest).promise(); }
ダウンロード後、編集した App.js
ファイルは次のようになります。
import React, { useEffect, useState } from "react"; import { BrowserRouter as Router, Switch } from "react-router-dom"; import AuthProvider from "contexts/auth"; import CommonProvider from "contexts/common"; import ProductsProvider from "contexts/products"; import CartProvider from "contexts/cart"; import CheckoutProvider from "contexts/checkout"; import RouteWrapper from "layouts/RouteWrapper"; import AuthLayout from "layouts/AuthLayout"; import CommonLayout from "layouts/CommonLayout"; import AuthPage from "pages/auth"; import HomePage from "pages/home"; import CheckoutPage from "pages/checkout"; import "assets/scss/style.scss"; import { Spinner } from 'react-bootstrap'; import Evidently from 'aws-sdk/clients/evidently'; import config from './config'; const defaultClientBuilder = ( endpoint, region, ) => { const credentials = { accessKeyId: config.credential.accessKeyId, secretAccessKey: config.credential.secretAccessKey } return new Evidently({ endpoint, region, credentials, }); }; const App = () => { const [isLoading, setIsLoading] = useState(true); const [startTime, setStartTime] = useState(new Date()); const [showDiscount, setShowDiscount] = useState(false); let client = null; let id = null; useEffect(() => { id = new Date().getTime().toString(); setStartTime(new Date()); if (client == null) { client = defaultClientBuilder( config.evidently.ENDPOINT, config.evidently.REGION, ); } const evaluateFeatureRequest = { entityId: id, // Input Your feature name feature: 'showDiscount', // Input Your project name' project: 'EvidentlySampleApp', }; // Launch client.evaluateFeature(evaluateFeatureRequest).promise().then(res => { if(res.value?.boolValue !== undefined) { setShowDiscount(res.value.boolValue); } }); // Experiment client.evaluateFeature(evaluateFeatureRequest).promise().then(res => { if(res.value?.boolValue !== undefined) { setShowDiscount(res.value.boolValue); } getPageLoadTime() }) setIsLoading(false); },[]); const getPageLoadTime = () => { const timeSpent = (new Date().getTime() - startTime.getTime()) * 1.000001; const pageLoadTimeData = `{ "details": { "pageLoadTime": ${timeSpent} }, "UserDetails": { "userId": "${id}", "sessionId": "${id}"} }`; const putProjectEventsRequest = { project: 'EvidentlySampleApp', events: [ { timestamp: new Date(), type: 'aws.evidently.custom', data: JSON.parse(pageLoadTimeData) }, ], }; client.putProjectEvents(putProjectEventsRequest).promise(); } return ( !isLoading? ( <AuthProvider> <CommonProvider> <ProductsProvider> <CartProvider> <CheckoutProvider> <Router> <Switch> <RouteWrapper path="/" exact component={() => <HomePage showDiscount={showDiscount}/>} layout={CommonLayout} /> <RouteWrapper path="/checkout" component={CheckoutPage} layout={CommonLayout} /> <RouteWrapper path="/auth" component={AuthPage} layout={AuthLayout} /> </Switch> </Router> </CheckoutProvider> </CartProvider> </ProductsProvider> </CommonProvider> </AuthProvider> ) : ( <Spinner animation="border" /> ) ); }; export default App;
ユーザーがサンプルアプリケーションにアクセスするたびに、カスタムメトリクスが Evidently に送信され分析されます。Evidently は各メトリクスを分析し、Evidently ダッシュボードにリアルタイムで結果を表示します。次の例で、メトリクスペイロードを示します。
[ {"timestamp": 1637368646.468, "type": "aws.evidently.custom", "data": "{\"details\":{\"pageLoadTime\":2058.002058},\"userDetails\":{\"userId\":\"1637368644430\",\"sessionId\":\"1637368644430\"}}" } ]
ステップ 5: プロジェクト、機能、実験の作成
次に、CloudWatch Evidently コンソールでプロジェクト、機能、および実験を作成します。
このチュートリアルのプロジェクト、機能、および実験を作成するには
CloudWatch コンソール (https://console.aws.amazon.com/cloudwatch/
) を開きます。 ナビゲーションペインで、[Application Signals]、[Evidently] の順に選択します。
[Create project] (プロジェクトを作成) を選択し、フィールドに入力します。サンプルが正しく動作するためには、プロジェクト名に
EvidentlySampleApp
を使用する必要があります。[Evaluation event storage] (評価イベントストレージ) で、[Don't store Evaluation events] (評価イベントを保存しない) を選択します。フィールドに入力したら、[Create profile] (プロファイルを作成) を選択します。
詳細については、「 の新規プロジェクトの作成」を参照してください。
プロジェクトを作成したら、そのプロジェクトに機能を作成します。機能の名前は「
showDiscount
」にします。この機能では、Boolean
型のバリエーションを 2 つ作成します。最初のバリエーションの名前を「disable
」、値を「False
」とし、第 2 のバリエーションの名前を「enable
」、値を「True
」とします。機能の作成の詳細については、「プロジェクトに機能を追加する」を参照してください。
機能の作成が完了したら、プロジェクト内の実験を作成します。実験の名前は「
pageLoadTime
」にします。この実験では、テスト対象ページのページロード時間を測定する
pageLoadTime
というカスタムメトリクスを使用します。実験のカスタムメトリクスは、Amazon EventBridge を使用して作成されます。EventBridge の詳細については、「Amazon EventBridge とは」を参照してください。そのカスタムメトリクスを作成するには、実験の作成時に次の操作を行います。
[Metrics] (メトリクス) の下で、 [Metric source] (メトリクスソース) として [Custom metrics] (カスタムメトリクス) を選択します。
[Metric name] (メトリクス名) に、「
pageLoadTime
」を入力します。[Goal] (目標) には [Decrease] (減少) を選択します。これは、このメトリクスの値が小さいほど機能のバリエーションが最適であることを示します。
[Metric rule] (メトリクスルール) では、次のように入力します。
エンティティ IDには、
UserDetails.userId
と入力します。[Value key] (値キー) には「
details.pageLoadTime
」と入力します。[Units] (単位) には、「
ms
」と入力します。
[Add metric] (メトリクスを追加) を選択します。
[Audiences] (対象者) には [100%] を選択し、すべてのユーザーが実験に参加するようにします。バリエーション間のトラフィック分割をそれぞれ 50% に設定します。
次に、[Create experiment] (実験を作成) を選択して、実験を作成します。作成しても、Evidently に開始するように指示するまで実験は開始されません。
ステップ 6: 実験を開始し、CloudWatch Evidently をテストする
最後のステップでは、実験を開始してサンプルアプリケーションを起動します。
チュートリアルの実験を開始するには
CloudWatch コンソール (https://console.aws.amazon.com/cloudwatch/
) を開きます。 ナビゲーションペインで、[Application Signals]、[Evidently] の順に選択します。
[EvidentlySampleApp] プロジェクトを選択します。
[Experiments] (実験) タブを選択します。
[pageLoadTime] の横にあるボタンをクリックし、[Actions] (アクション)、[Start experiment] (実験を開始) を選択します。
実験が終了する時間を選択します。
[Start experiment] (実験を開始) を選択します。
実験がすぐに開始されます。
次に、以下のコマンドを使用して Evidently サンプルアプリケーションを起動します。
npm install -f && npm start
アプリケーションが起動すると、テストされる 2 つの機能のバリエーションのうちの 1 つに割り当てられます。1 つのバリエーションでは「20% 割引」と表示されますが、もう一方のバリエーションでは表示されていません。ページの更新を繰り返して、さまざまなバリエーションを表示します。
注記
Evidently にはスティッキーの評価があります。機能の評価は決定論的です。つまり、同じ entityId
と機能では、必ず同じバリエーションがユーザーに割り当てられます。時間変動の割り当てが変更されるのは、エンティティがオーバーライドに追加されるか、実験トラフィックがダイヤルアップされる場合のみです。
ただし、サンプルアプリケーションのチュートリアルでの使用を簡単にするために、ページを更新するたびに Evidently によってサンプルアプリケーションの機能の評価が再割り当てされているため、オーバーライドを追加しなくても両方のバリエーションを体験できます。
トラブルシューティング
npm
バージョン 6.14.14 を使用することをお勧めします。サンプルアプリケーションの構築または起動に関するエラーが表示されており、別のバージョンの npm を使用している場合は、次の手順を実行します。
npm
バージョン 6.14.14 をインストールするには
ブラウザを使用して、https://nodejs.org/download/release/v14.17.5/
に接続します。 node-v14.17.5.pkg
をダウンロードし、pkg ファイルを開いて npm をインストールします。 webpack not found
エラーが表示された場合は、evidently-sample-shopping-app
フォルダを開き、以下のことを試します。package-lock.json
を削除するyarn-lock.json
を削除するnode_modules
を削除するpackage.json
から webpack の依存関係を削除する下記を実行します。
npm install -f && npm