Amazon Personalize Web-APIで情報推薦サービスを実現する(5)

AWS

2019.7.25

Topics

今までの記事では、次のような内容を説明してきました。

この記事では、前の記事で登録したデータと選んだレシピに基づいて、情報推薦するためのモデルを学習する方法を説明したいと思います。

ソリューションを操作する

ソリューションは、データに対する前処理の方法や、機械学習のアルゴリズムとパラメータ(つまりレシピ)をひとまとめにした設定を作成することを指します。
ソリューションの一覧を得るメソッドは、他のデータの場合と同じで、データセットグループARNを与えるだけです。

def ListSolutions(datasetGroupArn, maxResults = 100)
  endpoint = "https://personalize.#{REGION}.amazonaws.com/"
  post_data = {'datasetGroupArn' => datasetGroupArn,
               'maxResults' => maxResults,
              }.to_json
  call(endpoint, 'AmazonPersonalize.ListSolutions', post_data)
end

呼び出すと、最初はやはりカラのJSON配列が返ってくることでしょう。

ListSolutions('arn:aws:personalize:ap-northeast-1:123456:dataset-group/sample-dataset-group')

{
  "solutions": [

  ]
}

前回までの記事で、イベントタイプはInteractions、機械学習アルゴリズムはHRNN(hierarchical recurrent neural network)を採用することにしました。そのようなソリューションを作成するためのメソッドは次のようになります。

def CreateSolution(datasetGroupArn, name)
  endpoint = "https://personalize.#{REGION}.amazonaws.com/"
  post_data = {'datasetGroupArn' => datasetGroupArn,
               'eventType' => 'Interactions',
               'name' => name,
               'recipeArn' => 'arn:aws:personalize:::recipe/aws-hrnn',
               'performAutoML' => false,
               'solutionConfig' => {
                   'algorithmHyperParameters': {
                                                 'hidden_dimension' => "32",
                                                 'recency_mask' => "false",
                                                 'bptt' => "32"
                                               }
               }
              }.to_json
  call(endpoint, 'AmazonPersonalize.CreateSolution', post_data)
end

ここでは、自動的に機械学習アルゴリズムを選んでくれるperformAutoMLの機能はオフにし、recipeArnでHRNNレシピを指定しています(この辺りのパラメータは引数で指定するべきですが、今回はテストのため決めうちにしました)。また、レシピに含まれるハイパーパラメータの値を上書きする設定をしています。ハイパーパラメータのデフォルト値や、指定できる値は次のアルゴリズムの詳細を得るメソッドで確認できます。

def DescribeAlgorithm(algorithmArn)
  endpoint = "https://personalize.#{REGION}.amazonaws.com/"
  post_data = {'algorithmArn' => algorithmArn,
              }.to_json
  call(endpoint, 'AmazonPersonalize.DescribeAlgorithm', post_data)
end

公式ドキュメントにもそれらの値は記載されていますが、実際の値と異なることが多い(内部でチューニングしていて、ドキュメントの更新が遅れているのかもしれません)ので、ぜひ確認することをお勧めします。例えば、指定できる値の最小値・最大値がドキュメントと実際とで異なり、そのため、ドキュメントに記載されている範囲でパラメータに極端な値を設定した実験をした時にエラーになったことがありました。引数には、レシピARNであるarn:aws:personalize:::recipe/aws-hrnnでは無く、アルゴリズムARNであるarn:aws:personalize:::algorithm/aws-hrnnを渡します。

DescribeAlgorithm('arn:aws:personalize:::algorithm/aws-hrnn')

{
  "algorithm": {
    "algorithmArn": "arn:aws:personalize:::algorithm/aws-hrnn",
    "algorithmImage": {
      "name": "Hierarchal Recurrent Neural Net"
    },
    "creationDateTime": 1543190400.0,
    "defaultHyperParameterRanges": {
      "categoricalHyperParameterRanges": [
        {
          "isTunable": true,
          "name": "recency_mask",
          "values": [
            "true",
            "false"
          ]
        }
      ],
      "continuousHyperParameterRanges": [

      ],
      "integerHyperParameterRanges": [
        {
          "isTunable": true,
          "maxValue": 256,
          "minValue": 32,
          "name": "hidden_dimension"
        },
        {
          "isTunable": true,
          "maxValue": 256,
          "minValue": 32,
          "name": "bptt"
        }
      ]
    },
    "defaultHyperParameters": {
      "bptt": "32",
      "hidden_dimension": "149",
      "recency_mask": "true"
    },
    "defaultResourceConfig": {
      "maxNumberOfTrainingJobs": "16",
      "maxParallelTrainingJobs": "8"
    },
    "lastUpdatedDateTime": 0.0,
    "name": "aws-hrnn",
    "trainingInputMode": "File"
  }
}

「sample-solution」という名前を付けてCreateSolutionを実行することで、ソリューションARNを得ることができます。

CreateSolution('arn:aws:personalize:ap-northeast-1:123456:dataset-group/sample-dataset-group', 'sample-solution')

{
  "solutionArn": "arn:aws:personalize:ap-northeast-1:123456:solution/sample-solution"
}

ソリューションバージョンを操作する

データを登録し、ソリューションを作成することで、機械学習アルゴリズムを実行する準備ができました。ソリューションはあくまで設定であって、学習を実行するにはソリューションバージョンを作成しなければなりません。
ソリューションバージョンを作成するのは簡単で、ソリューションARNを指定するだけです。

def CreateSolutionVersion(solutionArn)
  endpoint = "https://personalize.#{REGION}.amazonaws.com/"
  post_data = {'solutionArn' => solutionArn,
              }.to_json
  call(endpoint, 'AmazonPersonalize.CreateSolutionVersion', post_data)
end

CreateSolutionVersion('arn:aws:personalize:ap-northeast-1:123456:solution/sample-solution')

{
  "solutionVersionArn": "arn:aws:personalize:ap-northeast-1:123456:solution/sample-solution/86dc1097"
}

これは機械学習を実行するので、とても時間がかかります。

def DescribeSolutionVersion(solutionVersionArn)
  endpoint = "https://personalize.us-west-2.amazonaws.com/"
  post_data = {'solutionVersionArn' => solutionVersionArn,
              }.to_json
  call(endpoint, 'AmazonPersonalize.DescribeSolutionVersion', post_data)
end

DescribeSolutionVersion('arn:aws:personalize:us-west-2:123456:solution/sample-solution/86dc1097')

{
  "solutionVersion": {
    "creationDateTime": 1559796642.489,
    "datasetGroupArn": "arn:aws:personalize:ap-northeast-1:123456:dataset-group/sample-dataset-group",
    "lastUpdatedDateTime": 1559796648.464,
    "performAutoML": false,
    "performHPO": false,
    "recipeArn": "arn:aws:personalize:::recipe/aws-hrnn",
    "solutionArn": "arn:aws:personalize:ap-northeast-1:123456:solution/sample-solution",
    "solutionConfig": {
      "algorithmHyperParameters": {
        "data.recency_mask": "false",
        "model.num_hidden": "32",
        "training.bptt": "32"
      }
    },
    "solutionVersionArn": "arn:aws:personalize:ap-northeast-1:123456:solution/sample-solution/86dc1097",
    "status": "CREATE IN_PROGRESS"
  }
}

長めのスリープを入れて待ちましょう。

ret = DescribeSolutionVersion('arn:aws:personalize:ap-northeast-1:123456:solution/sample-solution/86dc1097')
sampleSolutionVersion = JSON.parse(ret.body)['solutionVersion']
while sampleSolutionVersion['status'] =~ /(CREATE PENDING)|(CREATE IN_PROGRESS)/
  puts "solution version creation in progress..."          
  sleep(60) 
  ret = DescribeSolutionVersion('arn:aws:personalize:ap-northeast-1:123456:solution/sample-solution/86dc1097')                       
  sampleSolutionVersion = JSON.parse(ret.body)['solutionVersion']
end

執筆者が試した時点では、この記事での設定(データはMovieLensで約10万レコード・3メガバイト、学習アルゴリズムはHRNN)で約40分ほどかかりました。statusがACTIVEになれば、学習は完了です。

キャンペーンを操作する

ソリューションバージョンの作成は機械学習モデルを作成するだけで、まだその結果を使うことができません。機械学習結果を利用できる状態にするには、キャンペーンを作成する必要があります。公式ドキュメントでは、ソリューションバージョンをデプロイすると表現されています。キャンペーンを作成するのは簡単で、ソリューションバージョンARNを指定するだけです。

def CreateCampaign(solutionVersionArn, name)
  endpoint = "https://personalize.#{REGION}.amazonaws.com/"
  post_data = {'solutionVersionArn' => solutionVersionArn,
               'minProvisionedTPS' => 1,
               'name' => name,
              }.to_json
  call(endpoint, 'AmazonPersonalize.CreateCampaign', post_data)
end

ソリューションバージョンARNとキャンペーンの名前の他に、推薦情報入手のリクエストが来た場合に1秒間に処理する最低数というのを指定しなければなりません。ここでは試験的な利用のため、最小値である1を指定しています。この記事の執筆時時点で、最大値としては1秒間に500の処理ができるようです。キャンペーンの作成に成功すると、キャンペーンARNを得ることができます。

CreateCampaign('arn:aws:personalize:ap-northeast-1:123456:solution/sample-solution/86dc1097')

{
  "campaignArn": "arn:aws:personalize:ap-northeast-1:123456:campaign/sample-campaign"
}

次の予定

今回で、Amazon Personalizeの情報推薦サービスを利用する準備が整いました。

次回は、学習に使った映画情報のデータから、どのような推薦情報が得られるかを見たいと思います。

ts

大学で民俗学や宗教についてのフィールドワークを楽しんでいたのですが,うっかり新設された結び目理論と幾何学を勉強する研究室に移ってしまい,さらに大学院では一般相対性理論を研究するという迷走した人生を歩んでいます.プログラミングが苦手で勉強中です.

Recommends

こちらもおすすめ

Special Topics

注目記事はこちら