使用ML.Net和CSharp语言进行机器学习

介绍

本文介绍.net中的机器学习技术实现,不涉及数学方面的内容。它将重点关注在.net中的基本工作流程及其数据处理结构,以及怎么样通过使用开源项目ML.Net 0.2来进行机器学习的实验。

ML.Net项目0.2版本只适用于.net Core 2.0和.net Standard2.0,只支持x64架构(目前Any CPU选项的编译方式还不能用)。因此,它应该适用于任何.net Standard2.0(. net Framework 4.6.1)环境。该项目目前正在处在Review阶段,所提供的API在未来可能会发生改变。

背景

如果您想使用c#或VB.Net这样的面向对象语言,来学习ML机器学习(Machine Learning )技术,大部分时候是很困难。因为大多数情况下,您必须先学习Python,然后还需要学习一些示例教程,这些教程可以教给您很多相关知识。

甚至是学习很多机器学习的项目,Accord.Net, Tensor.Flow, or CNTK等。学习这些并不容易,因为它们都有各自的API,以不同的方式实现类似内容的东西。

我对Build 2018[2]会议的演示感到兴奋,因为它们表明,我们可以使用一种通用的工作流方法,允许我们使用本地数据、本地.net程序、本地模型和结果来进行机器学习,而不必去使用服务或其他编程语言,比如Python。

概述

机器学习是人工智能(AI)的一个子集,它可以回答5种类型的问题[3]:

受监督的Supervised

1、分类Classification (二元分类Binary 和多分类 Multiclass)

问题:它属于哪一类?

2、回归Regression

问题:How much or how many?

无人管理的Unsupervised

1、排名Ranking

问题:接下来我该怎么做?

2、聚类Clustering

问:这是如何组织的?

3、异常探测Anomaly Detection

问题:这是奇怪的吗?

每种类型的问题都有许多应用,为了使用正确的机器学习方法,我们必须首先确定我们是否想要回答给定的任何问题,如果是,我们是否有数据支持它。

受监督机器学习

本文讨论了用于二元分类和多类分类的.net示例(包括示例数据的源代码)。

这种机器学习算法假设我们可以标记一个条目来确定它是否属于:

1、二元分类中的一个

2、多类分类中的一个

当你想用真或假的答案回答一个问题时,可以使用二元分类Binary 分类。你通常会发现自己可以将一个条目(图像或文本)分成两个类中的一个。

例如,我们使用这样一个问题:客户对你最近的调查的反馈是好还是坏?

用机器学习来回答这个问题需要我们标记样本项(例如:图像或文本)是属于哪个一个组的。

正常的工作流程需要两个独立的数据集来进行标记:

1、训练数据集(训练机器学习算法)和

2、一个评估数据集(用来度量ml算法的效率)。

标记的一行文本可能是这样的:

1 Grow up you biased child.

0 I hope this helps.

第一列中的“1”表示消极情绪,第一列中的“0”表示积极情绪。根据经验,如果我们有更多的训练数据,ml算法通常会工作得更好。同时也要保证培训数据和以后使用的数据是干净的,并且高质量的,以支持有效的算法。

使用kpi确定有效算法的总体工作流程由下面左边的图表表示,其中我们(理想情况下)找到了一个最能反映分类问题的模型。

这里没有更详细地解释模型。在ML.Net中,它是一个zip文件,包含从标记的训练数据中学到的持久化存储的事实。

第二个独立的评估数据集用于确定kpi对学习分类的效率。这些步骤通过将机器学习算法的结果与可用的标记(不使用算法中的标记)进行比较,估计我们的算法在未来将如何对项目进行分类。一个衡量效率的KPI是,例如,分类正确的项目数量和错误分类项目的百分比。我们可以回到训练步骤,调整参数,或者用一种算法换另一种算法,如果我们发现我们的kpi没有达到我们的期望,我们需要优化模型的方法。

训练阶段有望以一个有效的模型结束,该模型可以在第二个预测阶段应用,对我们未来看到的每一项进行分类。这一阶段需要来自前一阶段的模型和要分类的项目,它们用于输出一个分类的预测(例如)。:正面或负面情绪)。

这是关于机器学习的工作流程的简要概述。我们需要理解这一点,才能使用本文后面讨论的代码示例。

让我们依次来看看每个样本。

二元分类

情绪分析维基百科

本节讨论的示例基于ML.Net教程中的情绪分析二进制分类场景。

  • Wikipedia_SentimentAnalysis.zip (下载链接:https://www.codeproject.com/KB/AI/1249611/Wikipedia_SentimentAnalysis.zip)

训练阶段

前一节中讨论的工作流程在本文附带的演示项目中得到了一定程度的实现。演示项目包含两个可执行项目:

1、培训

2、预测

我们编译并启动培训项目,得到如下输出:

Training Data Set
-----------------Not adding a normalizer.
Making per-feature arrays
Changing data from row-wise to column-wise
Processed 250 instances
Binning and forming Feature objects
Reserved memory for tree learner: 1943796 bytes
Starting to train ...
Not training a calibrator because it is not needed.Evaluating Training Results
---------------------------PredictionModel quality metrics evaluation
------------------------------------------Accuracy: 61,11% Auc: 96,30% F1Score: 72,00%

我们在这里看到程序如何首先训练一个模型,然后在第二个步骤中评估结果。

训练和预测模块共享对前面提到的Model.zip文件(大部分是手工复制的——请参阅下面的详细信息)的引用、对ML.Net库的引用以及模型项目中定义的数据输入和分类输出的通用模型:

ClassificationData中定义的属性将每个列映射到文本输入文件中显示的输入。Label列定义了包含我们想要针对每一行文本进行训练的类定义的项。文本属性本身不能被标记为“特性”,因为它包含多个“列”(在文本文件中)。这就是为什么我们需要在下面的管道中添加新的TextFeaturizer(“特性”、“文本”)行,以便将文本读入输入数据结构。

ClassificationData是对输入的粗略描述,以及如何将其映射到标签或特性。尝试删除标签列定义、编译和执行,以验证系统将抛出异常,如果在输入文本中不能找到名为Label的列。

ClassPrediction只声明一个二进制输出结果,预期是一个布尔值,将输入映射到任何一个二分的类。这一部分涉及:

1、验证学习是否成功(在测试阶段已知输入)。

2、确定了机器学习算法在生产过程中的实际分类。

总的来说:分类数据被用来描述我们如何处理输入(总是由标签和特征组成),并且类路径将这个输入映射到一个学习的结果。在模块上共享对前面提到的Model.zip文件(大部分是手工复制的——请参阅下面的详细信息)的引用、对ML.Net库的引用以及模型项目中定义的数据输入和分类输出的通用模型。

通过ClassificationData定义使用文本输入的训练管道如下所示:

ML.Net框架附带了一个可扩展的管道概念,其中可以插入不同的处理步骤,如上面所示。TextLoader步骤从文本文件加载数据,TextFeaturizer步骤将给定的输入文本转换为feature vector,这是给定文本的数字表示。这个数字表示然后输入ML社区称为学习者的东西。本例中的学习者是一个FastTreeBinaryClassifier。

学习者或培训师是将数字特征向量转换为模型的组成部分,该模型可用于以后对输入进行分类。这些学习者的文档目前正在建设中,并不是所有的学习者都得到了充分的实施和测试。对于二元(二进制)分类,有几种可供选择的学习者(只需编辑构造函数,如下所示):

对以上所有学习者进行了测试,结果表明,基于测量的kpi, StochasticDualCoordinateAscentBinaryClassifier最有效。

这些kpi是通过BinaryClassificationMetrics的一个实例来度量的,该实例还提供其他kpi,例如,精确度和可收回性。请注意,您仍然可以分析更多的kpi,例如内存消耗和处理时间,这里也没有度量这些kpi。所提出的测试是相当小和简短的。我们也可以使用不同的设置,个别学习者可能仍然显示出重大的改进。当我们面对大量条目(文本或图像等)的自动分类问题时,能够使用这些不同的场景看起来像是一个有趣的摘录。

简单地说,这就是机器学习的原理。机器使用数据(文本),将其转换为数值向量,并将矢量化的数据集成到一个模型中。模型是第一阶段的主要输出。让我们看一下分类阶段,以了解完整的工作流程。

预测阶段

预测阶段是表示在生产中运行的代码的模块,并在新项目进入系统时对数据进行分类。这部分在wikipedia_sensibility分析解决方案中预测项目的PredictAsync方法中实现。

此方法的代码如下所示:

PredictionModel.ReadAsync方法将模型从文件系统加载到内存中谓词模型:

加载的模型存储在项目的学习文件夹中。这个模型。每当我们发现有重大的改进并且想要在预测模块中利用它时,就必须从训练模块输出中复制zip文件。

模型加载代码行下面的所有内容根据加载的模型计算输入,并在方法的最后部分输出预测的分类。您可以使用交互式输入提示来测试您自己的示例文本,并在一个小范围内测试所学习的内容和没有的内容。记住,所学习的数据通常是干净的(与原始输入不同),您只能在这样的小范围内进行测试。一个更好、更合理的测试可能是从一个真实的数据源中输入最后的n个文本行,获取它们的分类,并查看独立的审阅者是否有一个紧密匹配的结果。

在本节中,我们看到了二元(二进制)分类如何在一个非常“简单”的场景中进行情绪分析。但ml的真正优势在于,每种类型的问题(这里是:这是A还是B?)都可以应用于各种各样的应用。

让我们在下一节中再检查一个示例,以检查另一个二元(二进制)分类用例。

你有垃圾邮件

  • YouGotSpam_Analysis.zip(下载:https://www.codeproject.com/KB/AI/1249611/YouGotSpam_Analysis.zip)

本节中讨论的示例的数据基于您已经获得的垃圾邮件的文章。这个二进制分类项目的目的是,我们想知道一个给定的文本是否应该被归类为垃圾邮件。

本文附带的有关YouGotSpam_Analysis解决方案的源代码与上一节中解释的代码几乎相同。甚至可执行的项目实际上几乎是相同的。这里唯一的区别是用于培训和测试评估的数据源,在本例中是来自上述codeproject文章的测试数据(请参阅training project中的data文件夹)。

培训项目产生以下输出:

Training Data Set
-----------------Not adding a normalizer.
Making per-feature arrays
Changing data from row-wise to column-wise
Processed 2000 instances
Binning and forming Feature objects
Reserved memory for tree learner: 24082752 bytes
Starting to train ...
Not training a calibrator because it is not needed.Evaluating Training Results
---------------------------PredictionModel quality metrics evaluation
------------------------------------------Accuracy: 100,00% Auc: 100,00% F1Score: 100,00%

…这表明我们可以达到原始文章中基于Python的kpi。

您可以再次使用预测项目从文件系统加载模型,并使用进一步的输入对其进行测试。

到目前为止讨论的项目表明,ML.Net可以帮助以自动方式确定二元(二进制)分类。但是,如果我想要划分超过两个类别(如:消极、中立和积极情绪),该怎么办呢?

下一节将检查对这个用例的数据进行分类。

多类分类

语言检测

  • LanguageDetection.zip(https://www.codeproject.com/KB/AI/1249611/LanguageDetection.zip)

本节中讨论的示例的数据是从http://wortschatz.uni-leipzig.de下载的,并经过预处理(删除引号字符)来改进解析体验。

这里讨论的多类分类用例是基于给定文本的语言检测。想象一下,你有一个社交媒体代理团队,你正试图传递在线客户反馈(例如:(聊天),用不同的语言,给说那种语言的正确团队。

本节附带的语言检测解决方案遵循前面讨论的二进制分类示例的结构。我们有一个培训项目、一个预测项目和模型类库,它们在可执行文件之间共享。培训项目可以用来创建一个特定学习者的模型。然后可以将成功的模型从培训项目复制到预测项目中,对未来的输入进行消费和多类分类。

语言检测解决方案的预测项目在定义ClassificationData类中的LanguageClass属性和ClassPrediction类中的class属性方面有所不同。

两个属性必须是数据类型浮点数,以支持多分类:

分类数据中的输入映射与二进制分类问题中的输入映射相同。唯一的区别不是我们在输入的文本文件的标签列中有两个以上的值。

ClassPrediction中的输出映射是不同的,因为我们现在必须映射到一个浮点值,以便对多个类进行分类。

所需的培训流程如下:

Dictionarizer(“Label”);步骤将每一行的标签输入值(0-5)映射到一个桶中。谓词PredictedLabelColumnOriginalValueConverter 将预测值(一个向量)映射到原始值数据类型(一个浮点数)。

编译和运行训练模块得到以下输出:

Training Data Set
-----------------Not adding a normalizer.
Using 4 threads to train.
Automatically choosing a check frequency of 4.
Auto-tuning parameters: maxIterations = 48.
Auto-tuning parameters: L2 = 2.778334E-05.
Auto-tuning parameters: L1Threshold (L1/L2) = 1.
Using best model from iteration 8.
Not training a calibrator because it is not needed.Evaluating Training Results
---------------------------PredictionModel quality metrics evaluation
------------------------------------------ Accuracy Macro: 98.66% Accuracy Micro: 98.66% Top KAccuracy: 0.00% LogLoss: 7.50% PerClassLogLoss: Class: 0 - 11.18% Class: 1 - 4.08% Class: 2 - 5.95% Class: 3 - 10.43% Class: 4 - 7.86% Class: 5 - 5.52%

在ML.Net版本0.2中有三个多级分类学习者。其KPIs比较如下所示:

这就是我们如何基于一个特性输入列对文本进行多类分类。同样的机器学习方法(multiclass的二进制)也适用于多个特性输入列,我们将在下文中看到。

虹膜花分类

版本1

  • IrisClassification.zip

https://www.codeproject.com/KB/AI/1249611/IrisClassification.zip

本节讨论的多类分类问题是模式识别社区[4]中一个众所周知的参考测试。最初的数据库是Ronald Fisher在1936年创建的,.Net示例来自于ML.Net教程的Get Started部分。问题语句是创建一个接受多个浮点值(表示花的属性)的输入向量的算法,该算法的输出应该是花最可能的名称。

在ML.Net中这样做需要我们创建一个包含多个列的输入映射:

我们正在输入一组特征列(即SepalLength、SepalWidth、PetalLength、PetalWidth),然后将它们组合成一个特征向量。在本例中,标签是作为最后一列给出的字符串,用于在算法的训练和测试阶段标识每个数据行。

预测类的结果应该是一个字符串(这并不奇怪):

本案例的培训代码与前一节非常相似:

这里只有两个新内容。在这种情况下,原始输入数据是一个逗号分隔的列表,因此,当从管道中的文本文件加载数据时,我们必须使用一个分隔符:','参数。我们使用ColumnConcatenator将一组特征列转换为一个包含命名为特征向量的列。

输出结果与我们之前看到的相似(我们还可以对另外两个学习者进行实验,如最后一节所示):

Training Data Set
-----------------Automatically adding a MinMax normalization transform, use 'norm=Warn' or 'norm=No' to turn this behavior off.
Using 4 threads to train.
Automatically choosing a check frequency of 4.
Auto-tuning parameters: maxIterations = 45452.
Auto-tuning parameters: L2 = 2.667051E-05.
Auto-tuning parameters: L1Threshold (L1/L2) = 0.
Using best model from iteration 1956.
Not training a calibrator because it is not needed.Evaluating Training Results
---------------------------PredictionModel quality metrics evaluation
------------------------------------------ Accuracy Macro: 95.73% Accuracy Micro: 95.76% Top KAccuracy: 0.00% LogLoss: 8.19% PerClassLogLoss: Class: 0 - 0.72% Class: 1 - 10.62% Class: 2 - 13.43%

同样,我们可以使用IrisClassification solution的训练模块来训练不同的学习者和设置,并使用预测模块使用先前确定的模型来预测新的分类。

在本节中,我们已经看到了如何使用ColumnConcatenator转换器将4个输入列(SepalLength、SepalWidth、PetalLength、PetalWidth)转换为一个向量化特征列。

不需要在管道代码中使用ColumnConcatenator的等效方法是使用以下输入类定义:

但是,通过如上所示的ClassificationData定义定义实际的特性集是一种不好的做法。因此,我们应该删除[ColumnName(“Features”))行,并在管道代码中添加新的ColumnConcatenator(“Features”,nameof(digital .Features))。当我们尝试评估不同的特性配置时,这个设计可以给我们更多的灵活性。

版本2

  • IrisClassification_uint.zip

下载:https://www.codeproject.com/KB/AI/1249611/IrisClassification_uint.zip

让我们假设一下,我们不希望机器学习算法处理字符串(因为我们确实希望本地化应用程序的那个部分)。最好回到处理整型值,并将每个整型作为索引来指示分类(花的类型)。

但究竟如何才能做到这一点呢?我们可以改变输入和预测输出的定义如下:

接下来,我们将不得不从前一个解决方案的管道中删除谓词PredictedLabelColumnOriginalValueConverter ,这就是我们如何针对这个场景进行调整(假设我们也调整了数据)。这种方法也可以在附加的irisfication_uint解决方案中得到验证。

结论

回顾的示例应用程序显示,二元(二进制)和多类分类可以基于不同类型的输入和输出。

这种输入和输出总是需要:

1、标签Label和特性Feature列作为输入

2、谓词标签PredictedLabel 列作为输出。

输入和输出的数据类型是灵活的,因为在向引擎输入输入输入数据时,可以使用转换器将值转换为数字和向量,当我们必须解释分类结果时,同样的转换显然是可能的。

我希望这篇文章是有用的,因为这可以帮助我们来推动基于ML.Net的应用。

原文发布于微信公众号 - 程序你好(codinghello)

原文发表时间:2018-07-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏人工智能

完全云端运行:使用谷歌CoLaboratory训练神经网络

选自Medium 作者:Sagar Howal 机器之心编译 参与:路雪 Colaboratory 是一个 Google 研究项目,旨在帮助传播机器学习培训和研...

7698
来自专栏人工智能LeadAI

宠物狗图片分类之迁移学习代码笔记

本文主要是总结之前零零散散抽出时间做的百度西交大狗狗图片分类竞赛题目 竞赛.目前本人已经彻底排到了50名后面,,,也没有想到什么办法去调优,并且平时也忙没时间再...

981
来自专栏WOLFRAM

版本 11.1 的新功能概要

1093
来自专栏点滴积累

geotrellis使用(十六)使用缓冲区分析的方式解决投影变换中边缘数据值计算的问题

Geotrellis系列文章链接地址http://www.cnblogs.com/shoufengwei/p/5619419.html 目录 前言 问题探索 ...

3504
来自专栏申龙斌的程序人生

零基础学编程037:小数据分析

R语言内置强大的向量运算,是搞数据分析的强大的编程语言,而Python也毫不逊色。今天就试着分析一下考试成绩表中两门科目的相关性。 问题描述: 有一个CSV文件...

3519
来自专栏数据处理

Home Depot Product Search Relevance

kaggle赛题链接Home Depot Product Search Relevance,这个题目关键点就是特征提取,给的数据需要观察处理

911
来自专栏PPV课数据科学社区

大数据竞赛平台-Kaggle入门篇

本文作者: wopon_ 来源:36大数据 本文长度为1500字,建议阅读4分钟 这篇文章适合那些刚接触Kaggle、想尽快熟悉Kaggle并且独立完成一个竞赛...

4568
来自专栏人工智能

如何仅使用TensorFlow C+来训练深度神经网络

作者|Florian Courtial 译者|Debra 编辑|Emily AI 前线导读:训练神经网络是一件十分复杂,难度非常大的工作,有没有可能让训练的过程...

2245
来自专栏Aloys的开发之路

判断一个数是不是2的幂

我们经常会遇到这样一个问题,就是判断某个数据是否为2的n次方(1,2,4,8,16...)。例如如果用户输入的不是2^n,则要求用户重新输入。为了说明这种判断算...

2228
来自专栏企鹅号快讯

PaddlePaddle之手写数字识别

作者:Charlotte77数学系的数据挖掘民工 博客专栏:http://www.cnblogs.com/charlotte77/ 个人公众号:Charlott...

2368

扫码关注云+社区

领取腾讯云代金券