iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 27
0

前言

個人在研究所期間曾經參與了文史脈流計畫,在這個計畫中學習到很多知識與技術,當時研究領域是資料探勘,也嘗試為了這個系統撰寫了推薦系統。工作了幾年,開始具備一些開發能力後,總是會想要將過去的系統做得更好,或者運用更多服務在這個系統,讓他更人性化。本篇文章將使用旅遊資訊與自動產生的交易資料進行訓練,並提供服務給機器人使用,建構一個簡單的旅遊推薦機器人。


介紹

彙整我們之前的操作步驟,我們只需要

  1. 上傳 catalog 與 usage data
  2. 設定 model 與進行訓練
  3. 從 Skype bot 取得推薦項目

上傳 catalog 與 usage data
Step 1. 我們先隨機建立 catalog 與 usage data

Step 2. 我們將資料上傳到 Azure Blob Storage

設定 model 與進行訓練
Step 1. 回到UI介面,我們開始進行訓練…

Step 2. 我們進行推薦測試

從 Skype bot 取得推薦項目
Step 1. 還記得這個 WebAPI 有提供swagger 嗎? 我們可以透過swagger進行 API 測試…

Step 2.我們先接回傳資料貼上 json2csharp,取得回物件格式

public class RootObject
{
    public string recommendedItemId { get; set; }
    public double score { get; set; }
}

Step 3. 我們取回的資料都是代號,我們需要 catalog 內的資料幫忙做對應,故我們讀取資料後,轉換成 Dictionary 方便我們等等轉換。

private Dictionary<string, string> GetMappingData()
{
    string[] allLines = File.ReadAllLines(@"D:\\catalog_Travel.csv");

    var query = from line in allLines
                let data = line.Split(',')
                select new
                {
                    ID = data[0],
                    Name = data[1],
                    Type = data[2]
                };
    return query.ToDictionary( x=>x.ID, x=> x.Name);
}

Step 4. 加入需要的key 與modelId

private string key = "your_key";
private string modelId = "your_model_Id";

Step 5. 我們開啟 Bot Template 新專案,修改 MessageReceivedAsync 方法,需要的處理的工作有:

  1. 使用者輸入景點,轉換成景點ID
  2. 呼叫服務取得推薦資料
  3. 將推薦資料內的景點ID轉換成景點名稱
  4. 回傳推薦景點名稱

程式碼如下

private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
    var activity = await result as Activity;

    var dic = GetMappingData();
    var DicKey = dic.FirstOrDefault(x => x.Value == activity.Text).Key;

    var client = new RestClient("https://recommandfpwhzly62oyzkws.azurewebsites.net");
    var request = new RestRequest("api/models/"+ modelId+ "/recommend", Method.GET);
    request.AddHeader("Accept", "application/json");
    request.AddHeader("x-api-key", key);
    request.AddParameter("itemId", DicKey);
    request.AddParameter("recommendationCount","10");

    var response = await client.ExecuteTaskAsync<List<RootObject>>(request);
    var recommendationString = string.Empty;

    foreach (var item in response.Data)
    {
        recommendationString += dic[item.recommendedItemId] + ",";
    }
    await context.PostAsync($"{recommendationString}");
    context.Wait(MessageReceivedAsync);
}

Step 6. 你的 RootDialog.cs 程式碼應該如下:

[Serializable]
public class RootDialog : IDialog<object>
{
    public Task StartAsync(IDialogContext context)
    {
        context.Wait(MessageReceivedAsync);

        return Task.CompletedTask;
    }

    private string key = "your_key";
    private string modelId = "your_model_id";

    private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
    {
        var activity = await result as Activity;

        var dic = GetMappingData();
        var DicKey = dic.FirstOrDefault(x => x.Value == activity.Text).Key;

        var client = new RestClient("https://recommandfpwhzly62oyzkws.azurewebsites.net");
        var request = new RestRequest("api/models/"+ modelId+ "/recommend", Method.GET);
        request.AddHeader("Accept", "application/json");
        request.AddHeader("x-api-key", key);
        request.AddParameter("itemId", DicKey);
        request.AddParameter("recommendationCount","10");

        var response = await client.ExecuteTaskAsync<List<RootObject>>(request);
        var recommendationString = string.Empty;

        foreach (var item in response.Data)
        {
            recommendationString += dic[item.recommendedItemId] + ",";
        }
        await context.PostAsync($"{recommendationString}");
        context.Wait(MessageReceivedAsync);
    }

    private Dictionary<string, string> GetMappingData()
    {
        string[] allLines = File.ReadAllLines(@"D:\\catalog_Travel.csv", Encoding.UTF8);

        var query = from line in allLines
                    let data = line.Split(',')
                    select new
                    {
                        ID = data[0].ToLower(),
                        Name = data[1],
                        Type = data[2]
                    };
        return query.ToDictionary( x=>x.ID, x=> x.Name);
    }
}

public class RootObject
{
    public string recommendedItemId { get; set; }
    public double score { get; set; }
}

Step 7. 啟動專案,透過模擬器進行測試,成功


作者目前狀態


上一篇
26. Recommendations Solution (3) - 訓練與結果
下一篇
28. Cognitive Service - Language Understanding Intelligent Service, LUIS(1) 介紹與新增實體
系列文
利用 MS Bot framework 與 Cognitive Service 建構自用智慧小秘書31

尚未有邦友留言

立即登入留言