C#機(jī)器入門(mén)學(xué)習(xí)之判斷日?qǐng)?bào)是否合格詳解
前言
簡(jiǎn)單來(lái)說(shuō)機(jī)器學(xué)習(xí)的核心步驟在于“獲取學(xué)習(xí)數(shù)據(jù);選擇機(jī)器算法;定型模型;評(píng)估模型,預(yù)測(cè)模型結(jié)果”,下面本人就以判斷日?qǐng)?bào)內(nèi)容是否合格為例為大家簡(jiǎn)單的闡述一下C#的機(jī)器學(xué)習(xí)。
第一步:?jiǎn)栴}分析
根據(jù)需求可以得出我們的模型是以日?qǐng)?bào)的內(nèi)容做為學(xué)習(xí)的特征確定的,然后通過(guò)模型判斷將該目標(biāo)對(duì)象預(yù)測(cè)為是否符合標(biāo)準(zhǔn)(合格與不合格),簡(jiǎn)單來(lái)說(shuō)就是一種分類場(chǎng)景(此場(chǎng)景結(jié)果屬于二元分類,不是A就是B),那么也就確定了核心算法為分類算法當(dāng)然還有其它的分類算法有興趣的可以自己去了解一下在這里就不多做說(shuō)明了。
第二步:環(huán)境準(zhǔn)備
其他的代碼編譯運(yùn)行的環(huán)境并沒(méi)有太多要求,你只需要引用C#機(jī)器學(xué)習(xí)的NuGet 包,名為Microsoft.ML 具體的安裝步驟在此就不做詳細(xì)介紹了。
第三步:準(zhǔn)備數(shù)據(jù)
這里會(huì)準(zhǔn)備兩個(gè)數(shù)據(jù)集 一個(gè)定型模型的數(shù)據(jù)集(可以稱之為學(xué)習(xí)資料)wikipedia-detox-250-line-data.tsv數(shù)據(jù)實(shí)例部分展示如下(你的數(shù)據(jù)按照這種排列格式即可該該格式的定義取決于你的輸入數(shù)據(jù)集類的結(jié)構(gòu)在下面會(huì)講到):
Sentiment SentimentText 第一天上班 無(wú)事 完成了領(lǐng)導(dǎo)的安排任務(wù) 編寫(xiě)了一些代碼然后寫(xiě)了一些雜七雜八的文檔 和一般的碼農(nóng)做了一樣的事情 和產(chǎn)品經(jīng)理一起做了一些項(xiàng)目上的事情 早上來(lái)的時(shí)候就開(kāi)始討論需求,然后開(kāi)始寫(xiě)代碼,快下班的時(shí)候完成了整個(gè)過(guò)程的文檔分享 ***項(xiàng)目的整體編排會(huì)議,設(shè)計(jì)圖的首頁(yè)以及我的個(gè)人中心制作 **項(xiàng)目需求的對(duì)接,需求的梳理,實(shí)體結(jié)構(gòu)的定義,數(shù)據(jù)庫(kù)的遷移,腦圖的完善 1、**項(xiàng)目的模板消息代碼編寫(xiě),2、**項(xiàng)目管理后臺(tái)的模板發(fā)送完善,
定型模型數(shù)據(jù)集準(zhǔn)備好之后還有一個(gè)評(píng)估模型的測(cè)試數(shù)據(jù)集(可以稱之為標(biāo)準(zhǔn)答案)wikipedia-detox-250-line-test.tsv格式與上面展示的評(píng)估數(shù)據(jù)集一樣
定型數(shù)據(jù)的數(shù)據(jù)越豐富算法的回歸曲線方程就會(huì)越接近理想的模型方程,你的模型預(yù)測(cè)結(jié)果就會(huì)越符合你的要求。
第四步:定義特征類
根據(jù)分享的模型確定其分析的特征項(xiàng)并定義為相關(guān)的類并且需要引用機(jī)器學(xué)習(xí)的包using Microsoft.ML.Data;,由此模型定義的數(shù)據(jù)集類如下(結(jié)果可看注釋):
/// <summary> /// 輸入數(shù)據(jù)集類 /// </summary> public class SentimentData { /// <summary> /// 日志是否合格的值(0:為合格,1:不合格) /// </summary> [Column(ordinal: "0", name: "Label")] public float Sentiment; /// <summary> /// 日?qǐng)?bào)內(nèi)容 /// </summary> [Column(ordinal: "1")] public string SentimentText; } /// <summary> /// 預(yù)測(cè)結(jié)果集類 /// </summary> public class SentimentPrediction { /// <summary> /// 預(yù)測(cè)值(是否合格) /// </summary> [ColumnName("PredictedLabel")] public bool Prediction { get; set; } /// <summary> /// 或然率(結(jié)果分布概率) /// </summary> [ColumnName("Probability")] public float Probability { get; set; } }
第一個(gè)SentimentData類為輸入數(shù)據(jù)集類,指的就是根據(jù)定型的數(shù)據(jù)集的特征項(xiàng)定義的集類,第二個(gè)SentimentPrediction類為預(yù)測(cè)結(jié)果集類,也就是你所需要的結(jié)果的類定義 該類的結(jié)構(gòu)一般受你所使用的學(xué)習(xí)算法影響,根據(jù)你的學(xué)習(xí)管道輸出的結(jié)果以及個(gè)人需求的綜合考慮來(lái)定義。輸入集類帶的Column屬性標(biāo)注其在數(shù)據(jù)集的格式位置的編排以及何為L(zhǎng)abel值。預(yù)測(cè)集的PredictedLabel在預(yù)測(cè)和評(píng)估過(guò)程中使用。
第五步:代碼實(shí)現(xiàn)
首先定義以指定這些路徑和 _textLoader 變量,用來(lái)讀取數(shù)據(jù)或者是保存實(shí)驗(yàn)數(shù)據(jù),具體如下所示:
_trainDataPath 具有用于定型模型的數(shù)據(jù)集路徑。
_testDataPath 具有用于評(píng)估模型的數(shù)據(jù)集路徑。
_modelPath 具有在其中保存定型模型的路徑。
_textLoader 是用于加載和轉(zhuǎn)換數(shù)據(jù)集的 TextLoader。
然后定義程序的入口(main函數(shù))以及相應(yīng)的處理方法:
定義SaveModelAsFile方法將模型保存為 .zip 文件代碼如下所示:
private static void SaveModelAsFile(MLContext mlContext, ITransformer model) { using (var fs = new FileStream(_modelPath, FileMode.Create, FileAccess.Write, FileShare.Write)) mlContext.Model.Save(model, fs); Console.WriteLine("模型保存路徑為{0}", _modelPath); Console.ReadLine(); }
定義Train方法選擇學(xué)習(xí)方法并且創(chuàng)建相應(yīng)的學(xué)習(xí)管道,輸出定型后的模型model代碼如下所示:
public static ITransformer Train(MLContext mlContext, string dataPath) { IDataView dataView = _textLoader.Read(dataPath); //數(shù)據(jù)特征化(按照管道所需的格式轉(zhuǎn)換數(shù)據(jù)) var pipeline = mlContext.Transforms.Text.FeaturizeText(inputColumnName: "SentimentText", outputColumnName: "Features") //根據(jù)學(xué)習(xí)算法添加學(xué)習(xí)管道 .Append(mlContext.BinaryClassification.Trainers.FastTree(numLeaves: 50, numTrees: 50, minDatapointsInLeaves: 20)); //得到模型 var model = pipeline.Fit(dataView); Console.WriteLine(); //返回定型模型 return model; }
模型定型之后,我們需要?jiǎng)?chuàng)建一個(gè)方法(Evaluate)來(lái)評(píng)測(cè)該模型的質(zhì)量,根據(jù)你自己的標(biāo)準(zhǔn)測(cè)試數(shù)據(jù)集與該模型的符合程度來(lái)判斷,并且輸出相應(yīng)的指標(biāo),該指標(biāo)參數(shù)根據(jù)你所調(diào)用的評(píng)估方法返回具體的根據(jù)你的算法方程返回相應(yīng)的方程的參數(shù) 。代碼如下所示:
public static void Evaluate(MLContext mlContext, ITransformer model) { var dataView = _textLoader.Read(_testDataPath); Console.WriteLine("===============用測(cè)試數(shù)據(jù)評(píng)估模型的準(zhǔn)確性==============="); var predictions = model.Transform(dataView); //評(píng)測(cè)定型模型的質(zhì)量 var metrics = mlContext.BinaryClassification.Evaluate(predictions, "Label"); Console.WriteLine(); Console.WriteLine("模型質(zhì)量量度評(píng)估"); Console.WriteLine("--------------------------------"); Console.WriteLine($"精度: {metrics.Accuracy:P2}"); Console.WriteLine($"Auc: {metrics.Auc:P2}"); Console.WriteLine("=============== 模型結(jié)束評(píng)價(jià) ==============="); Console.ReadLine(); //評(píng)測(cè)完成之后開(kāi)始保存定型的模型 SaveModelAsFile(mlContext, model); }
定義單個(gè)數(shù)據(jù)的預(yù)測(cè)方法(Predict)與批處理預(yù)測(cè)的方法(PredictWithModelLoadedFromFile):
單個(gè)數(shù)據(jù)集的預(yù)測(cè)代碼如下所示:
private static void Predict(MLContext mlContext, ITransformer model) { //創(chuàng)建包裝器 var predictionFunction = model.CreatePredictionEngine<SentimentData, SentimentPrediction>(mlContext); SentimentData sampleStatement = new SentimentData { SentimentText = "愛(ài)車新需求開(kāi)發(fā);麥扣日志監(jiān)控部分頁(yè)面數(shù)據(jù)綁定;" }; //預(yù)測(cè)結(jié)果 var resultprediction = predictionFunction.Predict(sampleStatement); Console.WriteLine(); Console.WriteLine("===============單個(gè)測(cè)試數(shù)據(jù)預(yù)測(cè) ==============="); Console.WriteLine(); Console.WriteLine($"日?qǐng)?bào)內(nèi)容: {sampleStatement.SentimentText} | 是否合格: {(Convert.ToBoolean(resultprediction.Prediction) ? "合格" : "不合格")} | 符合率: {resultprediction.Probability} "); Console.WriteLine("=============== 預(yù)測(cè)結(jié)束 ==============="); Console.WriteLine(); Console.ReadLine(); }
批處理數(shù)據(jù)集預(yù)測(cè)方法代碼如下所示:
public static void PredictWithModelLoadedFromFile(MLContext mlContext) { IEnumerable<SentimentData> sentiments = new[] { new SentimentData { SentimentText = "1、完成愛(ài)車年卡代碼編寫(xiě) 2、與客戶完成需求對(duì)接" }, new SentimentData { SentimentText = "沒(méi)有工作內(nèi)容" } }; ITransformer loadedModel; using (var stream = new FileStream(_modelPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { loadedModel = mlContext.Model.Load(stream); } // 創(chuàng)建預(yù)測(cè)(也稱之為創(chuàng)建預(yù)測(cè)房屋) var sentimentStreamingDataView = mlContext.Data.ReadFromEnumerable(sentiments); var predictions = loadedModel.Transform(sentimentStreamingDataView); // 使用模型預(yù)測(cè)結(jié)果值為1(不合格)還是0 (合格) var predictedResults = mlContext.CreateEnumerable<SentimentPrediction>(predictions, reuseRowObject: false); Console.WriteLine(); Console.WriteLine("=============== 多樣本加載模型的預(yù)測(cè)試驗(yàn) ==============="); var sentimentsAndPredictions = sentiments.Zip(predictedResults, (sentiment, prediction) => (sentiment, prediction)); foreach (var item in sentimentsAndPredictions) { Console.WriteLine($"日?qǐng)?bào)內(nèi)容: {item.sentiment.SentimentText} | 是否合格: {(Convert.ToBoolean(item.prediction.Prediction) ? "合格" : "不合格")} | 符合率: {item.prediction.Probability} "); } Console.WriteLine("=============== 預(yù)測(cè)結(jié)束 ==============="); Console.ReadLine(); }
在以上的方法定義完成之后開(kāi)始進(jìn)行方法的調(diào)用:
public static void Main(string[] args) { //創(chuàng)建一個(gè)MLContext,為ML作業(yè)提供一個(gè)上下文 MLContext mlContext = new MLContext(seed: 0); //初始化_textLoader以將其重復(fù)應(yīng)用于所需要的數(shù)據(jù)集 _textLoader = mlContext.Data.CreateTextLoader( columns: new TextLoader.Column[] { new TextLoader.Column("Label", DataKind.Bool,0), new TextLoader.Column("SentimentText", DataKind.Text,1) }, separatorChar: '\t', hasHeader: true ); //定型模型 var model = Train(mlContext, _trainDataPath); //評(píng)測(cè)模型 Evaluate(mlContext, model); //單個(gè)數(shù)據(jù)預(yù)測(cè) Predict(mlContext, model); //批處理預(yù)測(cè)數(shù)據(jù) PredictWithModelLoadedFromFile(mlContext); }
準(zhǔn)備代碼之后,你的小小的機(jī)器人就要開(kāi)始學(xué)習(xí)啦,好吧開(kāi)始編譯運(yùn)行吧。。。。。。
運(yùn)行產(chǎn)生結(jié)果為:
由于訓(xùn)練的數(shù)據(jù)集特征化參數(shù)的準(zhǔn)確性以及數(shù)據(jù)的涵蓋廣度不夠?qū)е露x的模型質(zhì)量非常的不理想因此我們可以看到 我們的預(yù)測(cè)結(jié)果也是不夠符合我們的理想狀態(tài),可見(jiàn)我們小機(jī)器的學(xué)習(xí)之路是非常漫長(zhǎng)的過(guò)程啊。
由此次的機(jī)器學(xué)習(xí)的小小實(shí)踐本人也深有體會(huì),機(jī)器就像一個(gè)小孩一樣首先你得根據(jù)他的性格(特征化參數(shù))確定應(yīng)該給予他什么樣的學(xué)習(xí)環(huán)境(學(xué)習(xí)算法創(chuàng)建的學(xué)習(xí)管道)并提供學(xué)習(xí)資料(定型機(jī)器學(xué)習(xí)模型數(shù)據(jù)集),然后為其確定一個(gè)發(fā)展目標(biāo)(評(píng)估模型數(shù)據(jù)集),并且不斷的進(jìn)行考試(單個(gè)數(shù)據(jù)的預(yù)測(cè)與批量數(shù)據(jù)的預(yù)測(cè)),考試需要特定的考試場(chǎng)地(預(yù)測(cè)所需要調(diào)用的方法)。通過(guò)該種方式讓機(jī)器不斷的學(xué)習(xí)不斷的精進(jìn)。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
詳解C#如何監(jiān)控選定文件夾中文件的變動(dòng)情況
這篇文章主要為大家詳細(xì)介紹了C#如何監(jiān)控選定文件夾中文件的變動(dòng)情況,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-12-12DevExpress實(shí)現(xiàn)自定義GridControl中按鈕文字內(nèi)容的方法
這篇文章主要介紹了DevExpress實(shí)現(xiàn)自定義GridControl中按鈕文字內(nèi)容的方法,需要的朋友可以參考下2014-08-08WPF ProgressBar實(shí)現(xiàn)實(shí)時(shí)進(jìn)度效果
這篇文章主要介紹了WPF ProgressBar實(shí)現(xiàn)實(shí)時(shí)進(jìn)度效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12