最近,我遇到了有关
机器学习框架Ml.NET的越来越多的信息。 关于它的参考文献数量越来越多,因此我决定至少一目了然地看一下它是哪种动物。
早些时候,我们尝试使用.NET生态系统中的线性回归解决最简单的预测问题。 为此,我们使用了Accord.NET Framework。 为此,
从公开数据中收集了有关公民向行政当局和个人
向莫斯科市长的 呼吁的公开数据 。
在
更新的数据集上
使用了几年之后
,我们将尝试解决
最简单的问题 。 使用Ml.NET Framework中的回归模型,我们可以预测每月有多少个请求得到肯定的解决方案。 在此过程中,我们将把Ml.NET与Accord进行比较。 NET和Python库。
您是否想掌握预测器的强度和功能? 那么,在猫之下,欢迎您。
PS让S.S. 索比亚宁,本文将不谈政治。内容:
第一部分:简介和有关数据的一些知识第二部分:编写C#代码第三部分:结论我认为有必要立即警告您,我通常不是数据分析和编程方面的专家,我也不参与莫斯科市政厅。 因此,从初学者到初学者,文章的可能性更高。 尽管我的知识有限,但我希望本文对您有所帮助。那些已经熟悉周期内过去文章的人可能会记得,我们已经尝试解决了从公民向莫斯科行政部门提出的呼吁中预测积极解决的问题数量的问题。 为此,我们使用了
Python和
Accord.Net框架 。
在任何情况下,重新解析再次使用的数据集都不是多余的。
所有文章材料,包括代码和数据集,都
可以在GitHub上免费获得 。
GitHub上的数据以csv格式表示,包含44个条目,并且原则上,它们不仅可以(而且应该)用于示例分析。
数据列的含义如下:
- num-记录索引
- 记录年份
- 录制月份
- total_appeals-每月总点击数
- Appeals_to_mayor-向市长提出的上诉总数
- res_positive-积极决策的数量
- res_explained-澄清请求的次数
- res_negative-否定决定的通话次数
- El_form_to_mayor-以电子形式向市长提出的上诉数量
- Pap_form_to_mayor-在纸上向市长的上诉数to_10K_total_VAO ... to_10K_total_YUZAO-莫斯科各个地区每10,000人口的上诉数
- to_10K_mayor_VAO ... to_10K_mayor_YUZAO-在城市各个地区中,每10,000人向莫斯科市长和莫斯科政府的呼吁数量
我没有找到自动执行数据收集过程并手动收集它们的方法,因此我可能会误会。 否则,数据的可靠性将留给作者。
目前,莫斯科政府网站上的数据是2016年1月至2019年8月的完整数据(9月缺少某些数据)。 因此,我们将有44个条目。 当然有一点,但是对于演示给我们来说就足够了。
在您开始之前,请先简单介绍一下本文的英雄。
ML.NET Framework-微软的开源开发。 根据社交媒体广告,这是他们对Python机器学习库的回答。 该框架是跨平台的,可让您解决从简单的回归和分类到深度学习的各种任务。 在Habr上,同志们已经在Python中进行了ML.NET和库的分析。 谁在乎,这是
链接 。
我将不提供有关安装和使用Ml.NET的详细指南,因为从本质上讲,所有内容都是根据
Microsoft官方网站上的
教科书 “改编”
而来 。
在那里,出租车的旅行价格问题得到了解决,老实说,它有更多好处但是我认为,小的解释不会是多余的。
我将Visual Studio 2017与最新更新一起使用。
该项目基于.NET Core控制台应用程序模板(2.1版)。
该项目必须安装NuGet包Microsoft.ML,Microsoft.ML.FastTree。 实际上,这就是整个准备工作。
我们直接进入代码。
首先,我创建了MayorAppel类,在其中按顺序描述了包含csv文件中数据的列。
不难猜测[LoadColumn(0)]
-告诉我们我们从csv文件中选择哪一列。
接下来,按照教程,我创建了MayorAppelPrediction类-用于预测结果
尽管事实上数据集中几乎所有列都具有整数值,但是为了避免在将数据粘贴到管道中的阶段出现错误,我不得不为其分配浮点类型(以便所有数据类型都相同)。
清单足够大,因此将其放在破坏者下方。
数据描述的类代码using Microsoft.ML.Data; namespace app_to_mayor_mlnet { class MayorAppel { [LoadColumn(0)] public float Year; [LoadColumn(1)] public string Month; [LoadColumn(2)] public float TotalAppeals; [LoadColumn(3)] public float AppealsToMayor; [LoadColumn(4)] public float ResPositive; [LoadColumn(5)] public float ResExplained; [LoadColumn(6)] public float ResNegative; [LoadColumn(7)] public float ElFormToMayor; [LoadColumn(8)] public float PapFormToMayor; [LoadColumn(9)] public float To10KTotalVAO; [LoadColumn(10)] public float To10KMayorVAO; [LoadColumn(11)] public float To10KTotalZAO; [LoadColumn(12)] public float To10KMayorZAO; [LoadColumn(13)] public float To10KTotalZelAO; [LoadColumn(14)] public float To10KMayorZelAO; [LoadColumn(6)] public float To10KTotalSAO; [LoadColumn(15)] public float To10KMayorSAO; [LoadColumn(16)] public float To10KTotalSVAO; [LoadColumn(17)] public float To10KMayorSVAO; [LoadColumn(18)] public float To10KTotalSZAO; [LoadColumn(19)] public float To10KMayorSZAO; [LoadColumn(20)] public float To10KTotalTiNAO; [LoadColumn(21)] public float To10KMayorTiNAO; [LoadColumn(22)] public float To10KTotalCAO; [LoadColumn(23)] public float To10KMayorCAO; [LoadColumn(24)] public float To10KTotalYUAO; [LoadColumn(25)] public float To10KMayorYUAO; [LoadColumn(26)] public float To10KTotalYUVAO; [LoadColumn(27)] public float To10KMayorYUVAO; [LoadColumn(28)] public float To10KTotalYUZAO; [LoadColumn(29)] public float To10KMayorYUZAO; } public class MayorAppelPrediction { [ColumnName("Score")] public float ResPositive; } }
让我们继续主程序代码。
不要忘了在开始时添加:
using System.IO; using Microsoft.ML;
以下是数据字段的说明。
namespace app_to_mayor_mlnet { class Program { static readonly string _trainDataPath = Path.Combine(Environment.CurrentDirectory, "Data", "train_data.csv"); static readonly string _testDataPath = Path.Combine(Environment.CurrentDirectory, "Data", "test_data.csv"); static readonly string _modelPath = Path.Combine(Environment.CurrentDirectory, "Data", "Model.zip");
实际上,在这些字段中,存储了数据文件的路径,这一次我决定提前将它们分开(与Accord.NET的情况不同)
顺便说一句,如果您正在执行项目,请不要忘记在数据文件的属性中设置“复制更高版本”选项,以避免由于缺少汇编文件而导致错误。
接下来是构成模型,进行评估并为我们提供预测的方法所面临的挑战。
static void Main(string[] args) { MLContext mlContext = new MLContext(seed: 0); var model = Train(mlContext, _trainDataPath); Evaluate(mlContext, model); TestSinglePrediction(mlContext, model); }
让我们去吧
需要训练方法来训练模型。
public static ITransformer Train(MLContext mlContext, string dataPath) { IDataView dataView = mlContext.Data.LoadFromTextFile<MayorAppel>(dataPath, hasHeader: true, separatorChar: ','); var pipeline = mlContext.Transforms.CopyColumns(outputColumnName: "Label", inputColumnName: "ResPositive") .Append(mlContext.Transforms.Categorical.OneHotEncoding(outputColumnName: "MonthEncoded", inputColumnName: "Month")) .Append(mlContext.Transforms.Concatenate("Features", "Year", "MonthEncoded", "TotalAppeals", "AppealsToMayor", "ResExplained", "ResNegative", "ElFormToMayor", "PapFormToMayor", "To10KTotalVAO", "To10KMayorVAO", "To10KTotalZAO", "To10KMayorZAO", "To10KTotalZelAO", "To10KMayorZelAO", "To10KTotalSAO", "To10KMayorSAO" , "To10KTotalSVAO", "To10KMayorSVAO", "To10KTotalSZAO", "To10KMayorSZAO", "To10KTotalTiNAO", "To10KMayorTiNAO" , "To10KTotalCAO", "To10KMayorCAO", "To10KTotalYUAO", "To10KMayorYUAO", "To10KTotalYUVAO", "To10KMayorYUVAO" , "To10KTotalYUZAO", "To10KMayorYUZAO")).Append(mlContext.Regression.Trainers.FastTree()); var model = pipeline.Fit(dataView); return model; }
首先,我们从训练样本中读取数据。 然后在链中,我们确定将进行预测的参数(标签)。
在我们的案例中,这是每月成功解决的有关公民上诉的问题。
由于在这种情况下,使用了基于回归的决策树模型,因此我们需要将所有符号带入数值。
与Accord.NET的情况不同,现成的OneHotEncoding解决方案将立即在文档中显示。
如前所述,在保留形成列之后,它们都应具有相同的数据类型,在这种情况下,应为浮点型。
总之,我们形成并返回完成的模型。
接下来,我们通过模型评估预测的质量。
private static void Evaluate(MLContext mlContext, ITransformer model) { IDataView dataView = mlContext.Data.LoadFromTextFile<MayorAppel>(_testDataPath, hasHeader: true, separatorChar: ','); var predictions = model.Transform(dataView); var metrics = mlContext.Regression.Evaluate(predictions, "Label", "Score"); Console.WriteLine(); Console.WriteLine($"*************************************************"); Console.WriteLine($"* Model quality metrics evaluation "); Console.WriteLine($"*------------------------------------------------"); Console.WriteLine($"* RSquared Score: {metrics.RSquared:0.##}"); Console.WriteLine($"* Root Mean Squared Error: {metrics.RootMeanSquaredError:#.##}"); }
我们加载测试样本(距离集合最近4个月),然后使用Transform()方法在经过训练的模型上获得测试数据的预测。 然后我们计算指标并打印出来。 在这种情况下,它是确定系数和标准偏差。 理想情况下,第一个应该趋于1,第二个基本上趋于零。
原则上,为了做出预测,我们不需要此方法,但是很高兴了解我们的模型对某事的预测有多么糟糕。
最后一种方法仍然是-预测本身。
我们也将其隐藏在扰流板下。
预测方法和数据 private static void TestSinglePrediction(MLContext mlContext, ITransformer model) { var predictionFunction = mlContext.Model.CreatePredictionEngine<MayorAppel, MayorAppelPrediction>(model); var MayorAppelSampleMinData = new MayorAppel() { Year = 2019, Month = "August", ResPositive = 0 }; var MayorAppelSampleMediumData = new MayorAppel() { Year = 2019, Month = "August", TotalAppeals = 111340, AppealsToMayor = 17932, ResExplained = 66858, ResNegative = 8945, ElFormToMayor = 14931, PapFormToMayor = 2967, ResPositive = 0 }; var MayorAppelSampleMaxData = new MayorAppel() { Year = 2019, Month = "August", TotalAppeals = 111340, AppealsToMayor = 17932, ResExplained = 66858, ResNegative = 8945, ElFormToMayor = 14931, PapFormToMayor = 2967, To10KTotalVAO = 67, To10KMayorVAO = 13, To10KTotalZAO = 57, To10KMayorZAO = 13, To10KTotalZelAO = 49, To10KMayorZelAO = 9, To10KTotalSAO = 71, To10KMayorSAO = 14, To10KTotalSVAO = 86, To10KMayorSVAO = 27, To10KTotalSZAO = 68, To10KMayorSZAO = 12, To10KTotalTiNAO = 93, To10KMayorTiNAO = 36, To10KTotalCAO = 104, To10KMayorCAO = 24, To10KTotalYUAO = 56, To10KMayorYUAO = 12, To10KTotalYUVAO = 59, To10KMayorYUVAO = 13, To10KTotalYUZAO = 78, To10KMayorYUZAO = 23, ResPositive = 0 }; var predictionMin = predictionFunction.Predict(MayorAppelSampleMinData); var predictionMed = predictionFunction.Predict(MayorAppelSampleMediumData); var predictionMax = predictionFunction.Predict(MayorAppelSampleMaxData); Console.WriteLine($"**********************************************************************"); Console.WriteLine($"Prediction for August 2019"); Console.WriteLine($"Predicted Positive decisions (Minimum Features): {predictionMin.ResPositive:0.####}, actual res_positive : 22313"); Console.WriteLine($"Predicted Positive decisions (Medium Features: {predictionMed.ResPositive:0.####}, actual res_positive : 22313"); Console.WriteLine($"Predicted Positive decisions (Maximum Features): {predictionMax.ResPositive:0.####}, actual res_positive : 22313"); Console.WriteLine($"**********************************************************************"); }
在示例中,我们使用PredictionEngine类,该类使我们能够基于训练后的模型和测试数据集获得单个预测。
我们将使用预测数据创建三个“探针”。
第一个分别具有最少的数据集(仅一个月和一年),第二个具有平均值,第三个具有完整的属性集。
我们得到三个不同的预测并打印它们。
正如您在屏幕快照(Windows 10 x64)中所看到的那样,在这种情况下,添加有关每10,000位居民在该地区的呼叫次数的数据只会破坏所有内容,但是添加其余数据会稍微提高预测的准确性。

在Linux下,Mint 19也可以在Mono中完美地编译。
事实证明,该框架是跨平台的。

总结,正如所承诺的,我将对使用Accord.NET和Python机器学习库的ML.NET进行一些主观的比较分析。
1.感觉到开发人员正在努力顺应机器学习领域的趋势。 当然,在
Python中 ,在Anaconda中安装了一堆库,可以更紧凑地解决此任务,并减少开发时间。 但是总的来说,在我看来,使用ML.NET解决问题的方法对于习惯于使用Python解决机器学习问题的人们来说是友好的。
2.与
Accord.NET Framework相比,对于尝试使用Python进行机器学习的人来说,ML.NET看起来更方便且有希望。 我记得两年前当我试图在Accord.NET上写东西时,我非常缺少某些类和方法的解释和示例。 在这方面,尽管该框架比Accord.NET还要年轻得多,但带有文档的Ml.NET的表现要好一些。 另一个重要因素是,根据GitHub上的活动判断,ML.NET的开发比Accord.NET更加密集,并且具有更多的俄语培训材料。
因此,乍一看,如果无法使用Python或R(例如,使用在.NET上执行的CAD API时),ML.NET看起来像是一种便捷的工具,可以对
您的武器库进行
补充 。
一周工作愉快!