ML.NET 示例:搜索引擎结果排名
ML.NET 示例中文版:https://github.com/feiyun0112/machinelearning-samples.zh-cn/edit/master/samples/csharp/getting-started/Ranking_Web
英文原版請(qǐng)?jiān)L問:https://github.com/dotnet/machinelearning-samples/tree/master/samples/csharp/getting-started/Ranking_Web
| v1.3.1 | 動(dòng)態(tài)API | 最新 | 控制臺(tái)應(yīng)用程序 | .csv 文件 | 搜索引擎結(jié)果排名 | 排名 | LightGBM |
這個(gè)介紹性示例演示如何使用ml.net來預(yù)測(cè)顯示搜索引擎結(jié)果的最佳順序。在機(jī)器學(xué)習(xí)領(lǐng)域,這種預(yù)測(cè)被稱為排名。
問題
排名是搜索引擎面臨的一個(gè)常見問題,因?yàn)橛脩粝M樵兘Y(jié)果根據(jù)其相關(guān)性進(jìn)行排名/排序。這個(gè)問題包括各種業(yè)務(wù)場(chǎng)景,其中個(gè)性化排序是用戶體驗(yàn)的關(guān)鍵,這已經(jīng)超出了搜索引擎的需求。下面是幾個(gè)具體的例子:
旅行社-提供一份酒店列表,列出最有可能被排名靠前的用戶購(gòu)買/預(yù)訂的酒店。
購(gòu)物-按與用戶購(gòu)物偏好一致的順序顯示產(chǎn)品目錄中的項(xiàng)目。
招聘-檢索根據(jù)最適合新職位空缺的候選人排列的職位申請(qǐng)。
排名對(duì)任何場(chǎng)景都很有用,在這些場(chǎng)景中,按照增加點(diǎn)擊、購(gòu)買、預(yù)訂等可能性的順序列出項(xiàng)目非常重要。
在這個(gè)示例中,我們展示了如何將排名應(yīng)用于搜索引擎結(jié)果。要執(zhí)行排名,目前有兩種算法可用-FastTree Boosting(FastRank)和Light Gradient Boosting Machine(LightGBM)。在這個(gè)示例中,我們使用LightGBM的LambdaRank實(shí)現(xiàn)自動(dòng)構(gòu)建一個(gè)ML模型來預(yù)測(cè)排名。
數(shù)據(jù)集
本示例使用的數(shù)據(jù)基于最初由Microsoft Bing提供的公共數(shù)據(jù)集。數(shù)據(jù)集在CC-by 4.0許可證下發(fā)布,包括訓(xùn)練、驗(yàn)證和測(cè)試數(shù)據(jù)。
@article{DBLP:journals/corr/QinL13,author = {Tao Qin and Tie{-}Yan Liu},title = {Introducing {LETOR} 4.0 Datasets},journal = {CoRR},volume = {abs/1306.2597},year = {2013},url = {https:timestamp = {Mon, 01 Jul 2013 20:31:25 +0200},biburl = {https:bibsource = {dblp computer science bibliography, https: }此數(shù)據(jù)集的說明如下:
這些數(shù)據(jù)集是機(jī)器學(xué)習(xí)數(shù)據(jù),其中查詢和URL由ID表示。 數(shù)據(jù)集由從查詢-網(wǎng)址對(duì)中提取的特征向量以及相關(guān)性判斷標(biāo)簽組成:
相關(guān)性判斷是從商業(yè)網(wǎng)絡(luò)搜索引擎(Microsoft Bing)的一個(gè)失效標(biāo)簽集中獲得的,該標(biāo)簽集取5個(gè)值,從0(不相關(guān))到4(完全相關(guān))。
這些特征基本上是由我們(微軟)提取的,是研究界廣泛使用的特征。
在這些數(shù)據(jù)文件中,每一行對(duì)應(yīng)一個(gè)查詢-網(wǎng)址對(duì)。第一列是相關(guān)標(biāo)簽,第二列是查詢id,其他列是特性。相關(guān)性標(biāo)簽的值越大,查詢-網(wǎng)址對(duì)的相關(guān)性就越大。查詢-網(wǎng)址對(duì)由136維特征向量表示。
機(jī)器學(xué)習(xí)任務(wù) - 排名
如前所述,本示例使用LightGBM LambdaRank算法,該算法使用名為Learning to Rank的監(jiān)督學(xué)習(xí)技術(shù)。該技術(shù)要求訓(xùn)練/驗(yàn)證/測(cè)試數(shù)據(jù)集包含一組數(shù)據(jù)實(shí)例,每個(gè)實(shí)例都用它們的相關(guān)性得分(例如相關(guān)性判斷標(biāo)簽)進(jìn)行標(biāo)記。標(biāo)簽是一個(gè)數(shù)字/序數(shù)值,例如{0,1,2,3,4}。主題專家可以手動(dòng)對(duì)這些數(shù)據(jù)實(shí)例及其相關(guān)度評(píng)分進(jìn)行標(biāo)記。或者,可以使用其他度量來確定標(biāo)簽,例如對(duì)給定搜索結(jié)果的單擊次數(shù)。
預(yù)計(jì)數(shù)據(jù)集將具有比“完美”更多的“差的”相關(guān)性分?jǐn)?shù)。這有助于避免將排名列表直接轉(zhuǎn)換為大小相等的{0、1、2、3、4}容器。關(guān)聯(lián)度得分也會(huì)被重用,這樣每個(gè)組中大多數(shù)樣本被標(biāo)記為0,這意味著結(jié)果是“差的”。而只有一個(gè)或幾個(gè)標(biāo)記為4,這意味著結(jié)果是“完美”。下面是數(shù)據(jù)集標(biāo)簽分布的細(xì)分。您將注意到,0(差的)比4(完美)標(biāo)簽多70倍:
Label 0 -- 624,263
Label 1 -- 386,280
Label 2 -- 159,451
Label 3 -- 21,317
Label 4 -- 8,881
一旦訓(xùn)練/驗(yàn)證/測(cè)試數(shù)據(jù)集被標(biāo)記為相關(guān)分?jǐn)?shù),那么就可以使用這些數(shù)據(jù)對(duì)模型(ranker)進(jìn)行訓(xùn)練和評(píng)估。通過模型訓(xùn)練過程,ranker學(xué)習(xí)如何根據(jù)標(biāo)簽值對(duì)組內(nèi)的每個(gè)數(shù)據(jù)實(shí)例進(jìn)行評(píng)分。單個(gè)數(shù)據(jù)實(shí)例的結(jié)果得分本身并不重要——相反,應(yīng)該將這些得分相互比較,以確定組數(shù)據(jù)實(shí)例的相對(duì)順序。一個(gè)數(shù)據(jù)實(shí)例的得分越高,它在其組中的相關(guān)性越強(qiáng),排名也越高。
解決方案
由于本示例的數(shù)據(jù)集已經(jīng)標(biāo)記了相關(guān)分?jǐn)?shù),因此我們可以立即開始訓(xùn)練模型。如果您從一個(gè)沒有標(biāo)記的數(shù)據(jù)集開始,您將需要首先通過讓主題專家提供相關(guān)性得分或使用其他一些度量來確定相關(guān)性來完成此過程。
通常,訓(xùn)練、驗(yàn)證和測(cè)試模型的模式包括以下步驟:
模型是在訓(xùn)練數(shù)據(jù)集上訓(xùn)練的。然后使用驗(yàn)證數(shù)據(jù)集評(píng)估模型的度量。
重復(fù)步驟1,通過重新訓(xùn)練和重新模型,直到達(dá)到所需的指標(biāo)。此步驟的結(jié)果是應(yīng)用必要的數(shù)據(jù)轉(zhuǎn)換和訓(xùn)練器的管道。
管道用于在組合的訓(xùn)練+驗(yàn)證數(shù)據(jù)集上訓(xùn)練。然后在測(cè)試數(shù)據(jù)集上評(píng)估模型的度量(僅一次)——這是用于測(cè)量模型質(zhì)量的最后一組度量。
最后一步是對(duì)組合的訓(xùn)練+驗(yàn)證+測(cè)試的全部數(shù)據(jù)集上重新訓(xùn)練管道。然后,該模型就可以部署到生產(chǎn)環(huán)境中了。
對(duì)模型在生產(chǎn)中的表現(xiàn)的最終估計(jì)是步驟3中的指標(biāo)。生產(chǎn)環(huán)境使用的最終模型,根據(jù)所有可用數(shù)據(jù)進(jìn),在步驟4中進(jìn)行訓(xùn)練。
本示例執(zhí)行上述步驟的簡(jiǎn)化版本以對(duì)搜索引擎結(jié)果進(jìn)行排序:
管道是通過必要的數(shù)據(jù)轉(zhuǎn)換和LightGBM LambdaRank訓(xùn)練器設(shè)置的。
模型是使用訓(xùn)練數(shù)據(jù)集訓(xùn)練。然后使用驗(yàn)證數(shù)據(jù)集對(duì)模型進(jìn)行評(píng)估。這將為每個(gè)搜索引擎結(jié)果生成一個(gè)預(yù)測(cè)。預(yù)測(cè)通過檢查指標(biāo)進(jìn)行評(píng)估;特別是Normalized Discounted Cumulative Gain(NDCG)。
管道用于使用培訓(xùn)+驗(yàn)證數(shù)據(jù)集重新訓(xùn)練模型。使用測(cè)試數(shù)據(jù)集對(duì)生成的模型進(jìn)行評(píng)估——這是模型的最后一組度量。
最后一次使用培訓(xùn)+驗(yàn)證+測(cè)試數(shù)據(jù)集對(duì)模型進(jìn)行再訓(xùn)練。最后一步是使用模型來執(zhí)行新傳入搜索的排名預(yù)測(cè)。這將為每個(gè)搜索引擎結(jié)果產(chǎn)生一個(gè)分?jǐn)?shù)。分?jǐn)?shù)用于確定與同一查詢中的其他結(jié)果(例如組)相關(guān)的排名。
1. 設(shè)置管道
本示例使用依賴于LightGBM LambdaRank的LightGbmRankingTrainer訓(xùn)練模型。模型需要以下輸入列:
Group Id—包含每個(gè)數(shù)據(jù)實(shí)例的組ID的列。數(shù)據(jù)實(shí)例包含在表示單個(gè)查詢中所有候選結(jié)果的邏輯分組中,每個(gè)組都有一個(gè)稱為組ID的標(biāo)識(shí)符。對(duì)于搜索引擎數(shù)據(jù)集,搜索結(jié)果按其對(duì)應(yīng)的查詢分組,其中組ID對(duì)應(yīng)于查詢ID。組ID數(shù)據(jù)類型必須為鍵類型。
Label—包含每個(gè)數(shù)據(jù)實(shí)例的相關(guān)性標(biāo)簽的列,其中較高的值表示較高的相關(guān)性。標(biāo)簽數(shù)據(jù)類型必須是鍵類型或單精度浮點(diǎn)數(shù)。
Features—確定數(shù)據(jù)實(shí)例的相關(guān)性/排名方面有影響的列。 特征數(shù)據(jù)必須是單精度浮點(diǎn)數(shù)類型的固定大小向量。
當(dāng)設(shè)置訓(xùn)練器時(shí),自定義增益(或相關(guān)性增益)也可用于對(duì)每個(gè)標(biāo)記的相關(guān)性得分應(yīng)用權(quán)重。這有助于確保模型更加重視對(duì)權(quán)重更高的結(jié)果進(jìn)行排名。在本示例中,我們使用默認(rèn)提供的權(quán)重。
以下代碼用于設(shè)置管道:
const string FeaturesVectorName = "Features";IDataView trainData = mlContext.Data.LoadFromTextFile<SearchResultData>(trainDatasetPath, separatorChar: '\t', hasHeader: true);var featureCols = trainData.Schema.AsQueryable().Select(s => s.Name).Where(c =>c != nameof(SearchResultData.Label) &&c != nameof(SearchResultData.GroupId)).ToArray();IEstimator<ITransformer> dataPipeline = mlContext.Transforms.Concatenate(FeaturesVectorName, featureCols).Append(mlContext.Transforms.Conversion.MapValueToKey(nameof(SearchResultData.Label))).Append(mlContext.Transforms.Conversion.Hash(nameof(SearchResultData.GroupId), nameof(SearchResultData.GroupId), numberOfBits: 20));IEstimator<ITransformer> trainer = mlContext.Ranking.Trainers.LightGbm(labelColumnName: nameof(SearchResultData.Label), featureColumnName: FeaturesVectorName, rowGroupColumnName: nameof(SearchResultData.GroupId)); ; IEstimator<ITransformer> trainerPipeline = dataPipeline.Append(trainer);2. 訓(xùn)練與評(píng)估模型
首先,我們需要使用訓(xùn)練數(shù)據(jù)集訓(xùn)練我們的模型。然后,我們需要評(píng)估我們的模型,以確定它在排名上的有效性。為此,模型將針對(duì)另一個(gè)未在訓(xùn)練中使用的數(shù)據(jù)集(驗(yàn)證數(shù)據(jù)集)運(yùn)行。
Evaluate()將驗(yàn)證數(shù)據(jù)集的預(yù)測(cè)值與數(shù)據(jù)集的標(biāo)簽進(jìn)行比較,并生成您可以探索的各種度量。具體來說,我們可以使用Evaluate()返回的RankingMetrics中包含的Discounted Cumulative Gain(DCG)和Normalized Discounted Cumulative Gain(NDCG)來衡量模型的質(zhì)量。
在評(píng)估示例模型的RankingMetrics時(shí),您會(huì)注意到DCG和NDCG報(bào)告了以下度量值(運(yùn)行示例時(shí)看到的值將類似于這些值):
DCG - @1:11.9736, @2:17.5429, @3:21.2532, @4:24.4245, @5:27.0554, @6:29.5571, @7:31.7560, @8:33.7904, @9:35.7949, @10:37.6874
NDCG: @1:0.4847, @2:0.4820, @3:0.4833, @4:0.4910, @5:0.4977, @6:0.5058, @7:0.5125, @8:0.5182, @9:0.5247, @10:0.5312
NDCG值是最有用的檢查,因?yàn)檫@允許我們比較我們的模型在不同數(shù)據(jù)集的排名能力。NDCG的潛在值從0.0到1.0不等,其中1.0是一個(gè)完美的模型,與理想的排名完全匹配。
考慮到這一點(diǎn),讓我們看看我們的模型的NDCG值。特別是,讓我們看看*NDCG@10的值,即0.5312。這是返回前10搜索引擎結(jié)果的查詢的平均NDCG,有助于判斷前10結(jié)果的排名是否正確。為了提高模型的排序能力,需要對(duì)特征工程和模型超參數(shù)進(jìn)行實(shí)驗(yàn),并對(duì)流水線進(jìn)行相應(yīng)的修改。我們將通過修改管道、訓(xùn)練模型和評(píng)估度量來繼續(xù)迭代,直到達(dá)到所需的模型質(zhì)量。
請(qǐng)參閱以下用于訓(xùn)練和評(píng)估模型的代碼:
ITransformer model = pipeline.Fit(trainData);IDataView validationData = mlContext.Data.LoadFromTextFile<SearchResultData>(ValidationDatasetPath, separatorChar: '\t', hasHeader: false);[...]IDataView predictions = model.Transform(validationData);[...]RankingMetrics metrics = mlContext.Ranking.Evaluate(predictions);3. 重新訓(xùn)練并執(zhí)行模型的最終評(píng)估
一旦達(dá)到所需的度量,生成的管道將用于組合的訓(xùn)練+驗(yàn)證數(shù)據(jù)集上的訓(xùn)練。然后,我們最后一次使用測(cè)試數(shù)據(jù)集評(píng)估此模型,以獲得模型的最終度量。
請(qǐng)參閱以下代碼:
model = pipeline.Fit(trainValidationData);IDataView testData = mlContext.Data.LoadFromTextFile<SearchResultData>(TestDatasetPath, separatorChar: '\t', hasHeader: false);[...]IDataView predictions = model.Transform(testData);[...]RankingMetrics metrics = mlContext.Ranking.Evaluate(predictions);4. 重新訓(xùn)練并使用模型
最后一步是使用所有數(shù)據(jù)(培訓(xùn)+驗(yàn)證+測(cè)試)重新訓(xùn)練模型。
在模型被訓(xùn)練之后,我們可以使用Predict()?API來預(yù)測(cè)新的、傳入的用戶查詢的搜索引擎結(jié)果排名。
總結(jié)
以上是生活随笔為你收集整理的ML.NET 示例:搜索引擎结果排名的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .NET框架之“小马过河”
- 下一篇: .Net Core中使用Quartz.N