ROMANCE DAWN for the new world

Microsoft Azure を中心とした技術情報を書いています。

Azure SignalR Service で ASP.NET SignalR を使ってみる

この記事は、Azure Advent Calendar 2018 の 8 日目 の記事です。
qiita.com
Ignite 2018 で GA が発表された Azure SignalR Service ですが、ASP.NET Core SignalR だけでなく、まだプレビューですが ASP.NET SignalR にも対応しています。
今回は、Core ではない ASP.NET SignalR を使って試してみました。

Azure SignalR Service とは

Azure SignalR Service は、SignalR を使って開発したアプリケーションのコネクションやスケーリングを管理してくれるマネージドサービスです。
build 2018 のセッションから引用したスライドです。
f:id:TonyTonyKun:20181118124127j:plain
アプリケーションの規模が大きくなると、バックエンドで Redis や Service Bus を使ったコネクションやスケーリングの管理が必要になります。このような面倒なところを Azure SignalR Service に任せることができます。
Azure SignalR Service の使い方は、こちらの公式ドキュメントにある通りですが、早速試していきます。
github.com

Azure SignalR Service を作成する

Azure Portal から、Azure SignalR Service を作成します。

f:id:TonyTonyKun:20181118142922p:plain

Standard プラン以外の他に、20 コネクションまでの Free プランもあります。東日本リージョンもあるので、安心して使えます。

ASP.NET SignalR のコードを変更する

ASP.NET SignalR のプロジェクトに対して、Azure SignalR Service に対応するための変更を加えていきます。

NuGet ライブラリのインストール

まず、Azure SignalR Service 用の NuGet ライブラリの Microsoft.Azure.SignalR.AspNet をインストールします。

PM> Install-Package Microsoft.Azure.SignalR.AspNet -Version 1.0.0-preview1-10259

NuGet ライブラリをインストールしたら、HTML ファイルで指定されている JavaScript のパスを変更します。

<script src="Scripts/jquery.signalR-2.4.0-preview2-20181018-02.min.js"></script>

Startup クラスを変更する

Startup クラスで呼び出している MapSignalR メソッドを MapAzureSignalR メソッドに置き換えます。引数には、他のアプリケーションと区別する一意な名前を渡します。

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        //app.MapSignalR();
        app.MapAzureSignalR(this.GetType().FullName);
    }
}

接続文字列の追加

Web.config に Azure SignalR Service の接続文字列を設定します。接続文字列は、Azure Portal から取得できます。

<connectionStrings>
  <add name="Azure:SignalR:ConnectionString" connectionString="Endpoint=xxx;AccessKey=xxx;Version=1.0;"/>
</connectionStrings>

動作確認

ASP.NET SignalR のサンプルとして、クリスマスなので懐かしい Fireworks のアプリケーションを Azure Web Apps にデプロイしました。

f:id:TonyTonyKun:20181208094616p:plain

自分で打ち上げた花火を、他のブラウザでもリアルタイムに観ることができます。
試してみたい方は、こちらの URL からどうぞ。

ブラウザの開発者ツールで確認すると、Azure SignalR Service に接続されていることがわかります。

f:id:TonyTonyKun:20181208103828p:plain

まとめ

ASP.NET SignalR は、チャットやダッシュボードなどのリアルタイムな Web アプリケーションを開発できるフレームワークです。
今から開発するなら ASP.NET Core SignalR を選択すべきですが、それが難しい場合でも Azure SignalR Service を使うことができます。
本番運用では、バックエンドでコネクションやスケーリングの管理が必須となるので、 Redis や Service Bus を使わずに Azure に任せられる嬉しいサービスだと思います。

Azure Recommendations Solution Template を使ってみる

Microsoft Cognitive Services で提供されていた Recommendations API は、プレビューのまま開発が中断され、2018年2月15日に正式に廃止されました。
その代わりとして、Recommendations Solution Template が提供されています。

github.com

今回は、Recommendations Solution Template を使って、商品カタログのレコメンド API を試してみます。

Recommendations Solution Template とは

このテンプレートを使うと、Azure にレコメンデーション エンジンがデプロイされ、商品カタログとトランザクション履歴のデータに基づいて、商品のレコメンド予測モデルを構築できます。
レコメンデーション エンジンは、Azure Web Apps、Web Jobs、Storage で構成されるアーキテクチャとなっています。

f:id:TonyTonyKun:20181021161224p:plain

SAR(Smart Adaptive Recommendations)アルゴリズムによって、次の2つのシナリオがサポートされています。

Item-to-Item Recommendations

「この商品をチェックした人はこんな商品もチェックしています」のようなレコメンドを表示するシナリオです。関連する商品を表示することで、カタログ内の商品を見つけやすくします。

Personalized Recommendations

ユーザーの最近のトランザクション履歴をもとに、そのユーザーに特化したレコメンドを表示します。

レコメンデーション エンジンをデプロイする

GitHub リポジトリの「Deploy to Azure」ボタンをクリックすると Azure ポータルの ARM テンプレートが開くので、リソースグループ名を入力して、デプロイするだけです。

f:id:TonyTonyKun:20181021155134p:plain

数分で作成が完了します。

f:id:TonyTonyKun:20181021155146p:plain

作成されたリソースグループを開き、Deployment → Microsoft Template → Outputs の順でメニューを開くと、レコメンド API の URL や Key が表示されます。

f:id:TonyTonyKun:20181021155202p:plain

モデルのトレーニングに使うデータをアップロードする

モデルのトレーニングに使うサンプルデータが提供されているので、withTimestamps フォルダにある「catalog.csv」と「usage1.csv」をダウンロードします。
aka.ms

ダウンロードした CSV ファイルは、ARM テンプレートで作成された Azure Storage に Blob コンテナを作ってアップロードします。
今回は、Blob コンテナ「input-files」を作成し「catalog.csv」をアップロード、「trainUsage」ディレクトリの中に「usage1.csv」をアップロードしました。

input-files
 trainUsage
  usage1.csv
 catalog.csv

モデルをトレーニングする

Azure ポータルの Outputs メニューを確認し、「RECOMMENDATIONSSWAGGER」の URL から、Swagger UI を開きます。

f:id:TonyTonyKun:20181021155903p:plain

モデルをトレーニングするためには、POST /api/models API を使います。

POST https://<service_name>.azurewebsites.net/api/models
x-api-key: your_api_key
Content-Type: application/json
{
   "description": "Simple recommendations model",
   "blobContainerName": "input-files",
   "usageRelativePath": "trainUsage",
}

API Key は、「ADMINPRIMARYKEY」に記載されているキーを Swagger UI に貼り付けます。下記のようなレスポンスが返ってくれば、成功です。

{
  "id": "70f8d6f2-5cb2-4fe6-a311-9f64fcde6824",
  "description": "Simple recommendations model",
  "creationTime": "2018-10-21T06:13:39.5996404Z",
  "modelStatus": "Created",
  "parameters": {
    "blobContainerName": "input-files",
    "usageRelativePath": "trainUsage",
    "supportThreshold": 6,
    "cooccurrenceUnit": "User",
    "similarityFunction": "Jaccard",
    "enableColdItemPlacement": false,
    "enableColdToColdRecommendations": false,
    "enableUserAffinity": true,
    "enableUserToItemRecommendations": false,
    "allowSeedItemsInRecommendations": false,
    "enableBackfilling": true,
    "decayPeriodInDays": 30
  }
}

トレーニングの完了を確認する

トレーニングした結果確認には、GET /api/models/{modelId} API を使います。モデルIDは、先ほどの API のレスポンスにある id です。

GET https://<service_name>.azurewebsites.net/api/models/70f8d6f2-5cb2-4fe6-a311-9f64fcde6824
x-api-key: your_api_key

数分でトレーニングが完了し、下記のようなレスポンスが返ってきます。

{
  "id": "70f8d6f2-5cb2-4fe6-a311-9f64fcde6824",
  "description": "Simple recommendations model",
  "creationTime": "2018-10-21T06:13:39.5996404Z",
  "modelStatus": "Completed",
  "modelStatusMessage": "Model Training Completed Successfully",
  "parameters": {
    "blobContainerName": "input-files",
    "usageRelativePath": "trainUsage",
    "supportThreshold": 6,
    "cooccurrenceUnit": "User",
    "similarityFunction": "Jaccard",
    "enableColdItemPlacement": false,
    "enableColdToColdRecommendations": false,
    "enableUserAffinity": true,
    "enableUserToItemRecommendations": false,
    "allowSeedItemsInRecommendations": false,
    "enableBackfilling": true,
    "decayPeriodInDays": 30
  },

レコメンドを取得する

今回は、Item-to-Item Recommendations を使ってみます。レコメンドを取得するには、GET /api/models/{modelId} API を使います。itemId には、「catalog.csv」内の任意のデータを指定します。

GET https://<service_name>.azurewebsites.net/api/models/70f8d6f2-5cb2-4fe6-a311-9f64fcde6824/recommend?itemId=4XZ-00006
x-api-key: your_api_key
Content-Type: application/json

指定した商品のレコメンドが、下記のようなレスポンスが返ってくれば成功です。

[
  {
    "recommendedItemId": "fkf-00642",
    "score": 0.006606797222048044
  },
  {
    "recommendedItemId": "fkf-01145",
    "score": 0.00028058543102815747
  },
  {
    "recommendedItemId": "dhf-00285",
    "score": 0.0000208172423299402
  },
  {
    "recommendedItemId": "6gq-00364",
    "score": 0
  },
  {
    "recommendedItemId": "qr2-00011",
    "score": 0
  },
  {
    "recommendedItemId": "qq2-00031",
    "score": 0
  },
  {
    "recommendedItemId": "p2w-00004",
    "score": 0
  },
  {
    "recommendedItemId": "aaa-02875",
    "score": 0
  },
  {
    "recommendedItemId": "gza-00202",
    "score": 0
  },
  {
    "recommendedItemId": "r4t-00009",
    "score": 0
  }
]

なお、API だけでなく、Web のユーザーインターフェースも提供されています。同様に、モデルのトレーニングやレコメンドの取得を行うことができます。

f:id:TonyTonyKun:20181021160933p:plain

ユーザーインターフェースの URL は、Azure ポータルの Outputs メニューの「RECOMMENDATIONSUI」から取得できます。

まとめ

Cognitive Services で提供されていた頃に比べるとひと手間かかりますが、ARM テンプレートを使ってサクッとデプロイできるので、お手軽にレコメンド API を構築できます。
レコメンド機能をアプリケーションに追加してみると楽しいので、ぜひ試してみてください。

Microsoft MVP for Microsoft Azure を再受賞しました

2018年7月1日付けで、Microsoft Most Valuable Professional (MVP) アワードを再受賞しました。受賞カテゴリは、Microsoft Azure です。

f:id:TonyTonyKun:20180724211653j:plain

前回は制度変更に伴なう自動更新だったので、審査のある初めての更新でしたが、無事に再受賞できました。
今年はコミュニティーでの登壇やブログでの情報発信に加えて、製品チームへのフィードバックやコントリビュートにもチャレンジしたいです。