TypeScriptでAmazon Personalizeのイベントトラッキングを実行する
「Amplify使えばトラッキングできるよ」とドキュメントに書かれてますが、そこ以外でもトラッキングしたい時だってあります。ということでざっと調べました。 事前準備 事前にAmazon Personalizeのデータセッ […]
目次
「Amplify使えばトラッキングできるよ」とドキュメントに書かれてますが、そこ以外でもトラッキングしたい時だってあります。ということでざっと調べました。
事前準備
事前にAmazon Personalizeのデータセットグループとデータセットを用意する必要があります。
この辺りについては、チュートリアルをみながら先に触っておいてください。
Personalize入門系記事
- TypeScriptでAmazon Personalizeのレコメンドを取得する
- TypeScriptでAmazon PersonalizeのCampaignを使った推論を試す
- Amazon Personalizeのデータをチューニングしてみる
- Amazon Personalize触ってみる
本記事で使用しているSchema
データセットは以下のSchemaを利用しています。
{
"name": "Interactions",
"namespace": "com.amazonaws.personalize.schema",
"type": "record",
"fields": [
{
"name": "USER_ID",
"type": "string"
},
{
"name": "ITEM_ID",
"type": "string"
},
{
"name": "EVENT_TYPE",
"type": "string"
},
{
"name": "EVENT_VALUE",
"type": "float"
},
{
"name": "TIMESTAMP",
"type": "long"
},
{
"name": "SESSION_ID",
"type": "string"
}
],
"version": "1.0"
}
トラッキングコード
PersonalizeEventsのputEvents
を実行すれば、任意のイベントをトラッキングできます。
UUIDとmomentのライブラリを入れてますが、そこは好みです。
import {
PersonalizeEvents,
} from 'aws-sdk'
import { v4 } from 'uuid'
import moment from 'moment'
const trackEvent = async () => {
const client = new PersonalizeEvents({
region: 'ap-northeast-1'
})
const params: PersonalizeEvents.Types.PutEventsRequest = {
trackingId: YOUR_PERSONALIZE_TRACKING_ID,
userId: '1',
sessionId: v4(),
eventList: [{
eventId: v4(),
sentAt: moment().toDate(),
eventType: 'rating',
properties: {
itemId: '1',
eventValue: 1.0
} as any as PersonalizeEvents.Types.EventPropertiesJSON
}]
}
await client.putEvents(params).promise()
return
}
trackEvent()
成功したら、CloudWatchのメトリクスから記録を確認できます。
イベントからモデルを作るために必要なデータ量は1000レコード
モデルを作成するには、以下の条件を満たす必要があります。
モデルをトレーニングするための最小データ要件は次のとおりです。
・組み合わされたやり取りデータの 1000 レコード (
eventType
およびeventValueThreshold
が指定されている場合は、それらを使用したフィルタリング後)・少なくともそれぞれ 2 つのやり取りを持つ 25 人の一意のユーザー
https://docs.aws.amazon.com/ja_jp/personalize/latest/dg/recording-events.html
力技で1000レコード作る
せっかくなのでputEventsから入れたデータだけでモデルを作りたいと思います。と、いうことで以下のようなコードで1000レコード作っちゃいましょう。
const trackEvent = async () => {
const client = new PersonalizeEvents({
region: 'ap-northeast-1'
})
const t1 = Array(1000)
const t2 = [...t1.keys()]
const arr = t2.map(i => ++i)
return Promise.all(arr.map(async (userNo: number): Promise<void> => {
const params: PersonalizeEvents.Types.PutEventsRequest = {
trackingId: YOUR_PERSONALIZE_TRACKING_ID,
userId: String(userNo),
sessionId: v4(),
eventList: [{
eventId: v4(),
sentAt: moment().toDate(),
eventType: 'access',
properties: {
itemId: String(Math.floor(Math.random() * 10)),
eventValue: 1.0
}
}, {
eventId: v4(),
sentAt: moment().toDate(),
eventType: 'rating',
properties: {
itemId: String(Math.floor(Math.random() * 10)),
eventValue: Math.floor(Math.random() * 100) / 10
}
}]
}
await client.putEvents(params).promise()
return
}))
}
CWのメトリクスが楽しいことになっていたら仕込み完了です。
いつトレーニングがはじまるのか?
前述の条件を満たしてすぐ開始ではない様子です。
ドキュメントにいつ開始するかの記載はありませんでしたが、2000 ~ 3000件データを放り込んでもいきなりソリューションを作れるようになるというわけではありませんでした。
退社間際や寝る前などにデータの投入を行い、次の日続きをするようなイメージで構えるのが穏やかに触れる気はします。
Appendix: V2.517.0または記事公開時点での問題
プロパティの中でしれっと as any as~
を使っているのはSDK側のバグ(おそらく)が原因です。
AWS SDKの型定義とAPI側で想定しているパラメータの型が違う様子で、「TypeScriptのエラー」or「APIのバリデーションエラー」で詰む状態が発生しています。
APIのバリデーションを通過しないとなにもできないので、現状はas any
をかませてTypeScript側をすり抜けるしかないかなと思います。