個人在研究所期間曾經參與了文史脈流計畫,在這個計畫中學習到很多知識與技術,當時研究領域是資料探勘,也嘗試為了這個系統撰寫了推薦系統。工作了幾年,開始具備一些開發能力後,總是會想要將過去的系統做得更好,或者運用更多服務在這個系統,讓他更人性化。本篇文章將使用旅遊資訊與自動產生的交易資料進行訓練,並提供服務給機器人使用,建構一個簡單的旅遊推薦機器人。
彙整我們之前的操作步驟,我們只需要
上傳 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 方法,需要的處理的工作有:
程式碼如下
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. 啟動專案,透過模擬器進行測試,成功
作者目前狀態