机器学习的工作流程分为以下几个步骤:

  1. 理解问题
  2. 准备数据
    • 加载数据
    • 提取特征
  3. 构建与训练
    • 训练模型
    • 评估模型
  4. 运行
    • 使用模型

理解问题

本教程需要解决的问题是根据网站内评论的意见采取合适的行动。

可用的训练数据集中,网站评论可能是有毒(toxic)(1)或者无毒(not toxic)(0)两种类型。这种场景下,机器学习中的分类任务最为适合。

分类任务用于区分数据内的类别(category),类型(type)或种类(class)。常见的例子有:

  • 识别情感是正面或是负面
  • 将邮件按照是否为垃圾邮件归类
  • 判定病人的实验室样本是否为癌症
  • 按照客户的偏好进行分类以响应销售活动

分类任务可以是二元又或是多元的。这里面临的是二元分类的问题。

准备数据

首先建立一个控制台应用程序,基于.NET Core。完成搭建后,添加Microsoft.ML类库包。接着在工程下新建名为Data的文件夹。

之后,下载WikiPedia-detox-250-line-data.tsvwikipedia-detox-250-line-test.tsv文件,并将它们放入Data文件夹,值得注意的是,这两个文件的Copy to Output Directory属性需要修改成Copy if newer

加载数据

Program.cs文件的Main方法里加入以下代码:

  1. MLContext mlContext = new MLContext(seed: 0);
  2. _textLoader = mlContext.Data.TextReader(new TextLoader.Arguments()
  3. {
  4. Separator = "tab",
  5. HasHeader = true,
  6. Column = new[]
  7. {
  8. new TextLoader.Column("Label", DataKind.Bool, 0),
  9. new TextLoader.Column("SentimentText", DataKind.Text, 1)
  10. }
  11. });

其目的是通过使用TextLoader类为数据的加载作好准备。

Column属性中构建了两个对象,即对应数据集中的两列数据。不过第一列这里必须使用Label而不是Sentiment

提取特征

新建一个SentimentData.cs文件,其中加入SentimentData类与SentimentPrediction。

  1. public class SentimentData
  2. {
  3. [Column(ordinal: "0", name: "Label")]
  4. public float Sentiment;
  5. [Column(ordinal: "1")]
  6. public string SentimentText;
  7. }
  8. public class SentimentPrediction
  9. {
  10. [ColumnName("PredictedLabel")]
  11. public bool Prediction { get; set; }
  12. [ColumnName("Probability")]
  13. public float Probability { get; set; }
  14. [ColumnName("Score")]
  15. public float Score { get; set; }
  16. }

SentimentData类中的SentimentText为输入数据集的特征,Sentiment则是数据集的标记(label)。

SentimentPrediction类用于模型被训练后的预测。

训练模型

Program类中加入Train方法。首先它会读取训练数据集,接着将特征列中的文本型数据转换为浮点型数组并设定了训练时所使用的决策树二元分类模型。之后,即是实际训练模型。

  1. public static ITransformer Train(MLContext mlContext, string dataPath)
  2. {
  3. IDataView dataView = _textLoader.Read(dataPath);
  4. var pipeline = mlContext.Transforms.Text.FeaturizeText("SentimentText", "Features")
  5. .Append(mlContext.BinaryClassification.Trainers.FastTree(numLeaves: 50, numTrees: 50, minDatapointsInLeaves: 20));
  6. Console.WriteLine("=============== Create and Train the Model ===============");
  7. var model = pipeline.Fit(dataView);
  8. Console.WriteLine("=============== End of training ===============");
  9. Console.WriteLine();
  10. return model;
  11. }

评估模型

加入Evaluate方法。到了这一步,需要读取的是用于测试的数据集,且读取后的数据仍然需要转换成合适的数据类型。

  1. public static void Evaluate(MLContext mlContext, ITransformer model)
  2. {
  3. IDataView dataView = _textLoader.Read(_testDataPath);
  4. Console.WriteLine("=============== Evaluating Model accuracy with Test data===============");
  5. var predictions = model.Transform(dataView);
  6. var metrics = mlContext.BinaryClassification.Evaluate(predictions, "Label");
  7. Console.WriteLine();
  8. Console.WriteLine("Model quality metrics evaluation");
  9. Console.WriteLine("--------------------------------");
  10. Console.WriteLine($"Accuracy: {metrics.Accuracy:P2}");
  11. Console.WriteLine($"Auc: {metrics.Auc:P2}");
  12. Console.WriteLine($"F1Score: {metrics.F1Score:P2}");
  13. Console.WriteLine("=============== End of model evaluation ===============");
  14. }

使用模型

训练及评估模型完成后,就可以正式使用它了。这里需要建立一个用于预测的对象(PredictionFunction),其预测方法的输入参数是SentimentData类型,返回结果为SentimentPrediction类型。

  1. private static void Predict(MLContext mlContext, ITransformer model)
  2. {
  3. var predictionFunction = model.MakePredictionFunction<SentimentData, SentimentPrediction>(mlContext);
  4. SentimentData sampleStatement = new SentimentData
  5. {
  6. SentimentText = "This is a very rude movie"
  7. };
  8. var resultprediction = predictionFunction.Predict(sampleStatement);
  9. Console.WriteLine();
  10. Console.WriteLine("=============== Prediction Test of model with a single sample and test dataset ===============");
  11. Console.WriteLine();
  12. Console.WriteLine($"Sentiment: {sampleStatement.SentimentText} | Prediction: {(Convert.ToBoolean(resultprediction.Prediction) ? "Toxic" : "Not Toxic")} | Probability: {resultprediction.Probability} ");
  13. Console.WriteLine("=============== End of Predictions ===============");
  14. Console.WriteLine();
  15. }

完整示例代码

  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using Microsoft.ML;
  6. using Microsoft.ML.Core.Data;
  7. using Microsoft.ML.Runtime.Data;
  8. using Microsoft.ML.Transforms.Text;
  9. namespace SentimentAnalysis
  10. {
  11. class Program
  12. {
  13. static readonly string _trainDataPath = Path.Combine(Environment.CurrentDirectory, "Data", "wikipedia-detox-250-line-data.tsv");
  14. static readonly string _testDataPath = Path.Combine(Environment.CurrentDirectory, "Data", "wikipedia-detox-250-line-test.tsv");
  15. static readonly string _modelPath = Path.Combine(Environment.CurrentDirectory, "Data", "Model.zip");
  16. static TextLoader _textLoader;
  17. static void Main(string[] args)
  18. {
  19. MLContext mlContext = new MLContext(seed: 0);
  20. _textLoader = mlContext.Data.TextReader(new TextLoader.Arguments()
  21. {
  22. Separator = "tab",
  23. HasHeader = true,
  24. Column = new[]
  25. {
  26. new TextLoader.Column("Label", DataKind.Bool, 0),
  27. new TextLoader.Column("SentimentText", DataKind.Text, 1)
  28. }
  29. });
  30. var model = Train(mlContext, _trainDataPath);
  31. Evaluate(mlContext, model);
  32. Predict(mlContext, model);
  33. Console.Read();
  34. }
  35. public static ITransformer Train(MLContext mlContext, string dataPath)
  36. {
  37. IDataView dataView = _textLoader.Read(dataPath);
  38. var pipeline = mlContext.Transforms.Text.FeaturizeText("SentimentText", "Features")
  39. .Append(mlContext.BinaryClassification.Trainers.FastTree(numLeaves: 50, numTrees: 50, minDatapointsInLeaves: 20));
  40. Console.WriteLine("=============== Create and Train the Model ===============");
  41. var model = pipeline.Fit(dataView);
  42. Console.WriteLine("=============== End of training ===============");
  43. Console.WriteLine();
  44. return model;
  45. }
  46. public static void Evaluate(MLContext mlContext, ITransformer model)
  47. {
  48. IDataView dataView = _textLoader.Read(_testDataPath);
  49. Console.WriteLine("=============== Evaluating Model accuracy with Test data===============");
  50. var predictions = model.Transform(dataView);
  51. var metrics = mlContext.BinaryClassification.Evaluate(predictions, "Label");
  52. Console.WriteLine();
  53. Console.WriteLine("Model quality metrics evaluation");
  54. Console.WriteLine("--------------------------------");
  55. Console.WriteLine($"Accuracy: {metrics.Accuracy:P2}");
  56. Console.WriteLine($"Auc: {metrics.Auc:P2}");
  57. Console.WriteLine($"F1Score: {metrics.F1Score:P2}");
  58. Console.WriteLine("=============== End of model evaluation ===============");
  59. }
  60. private static void Predict(MLContext mlContext, ITransformer model)
  61. {
  62. var predictionFunction = model.MakePredictionFunction<SentimentData, SentimentPrediction>(mlContext);
  63. SentimentData sampleStatement = new SentimentData
  64. {
  65. SentimentText = "This is a very rude movie"
  66. };
  67. var resultprediction = predictionFunction.Predict(sampleStatement);
  68. Console.WriteLine();
  69. Console.WriteLine("=============== Prediction Test of model with a single sample and test dataset ===============");
  70. Console.WriteLine();
  71. Console.WriteLine($"Sentiment: {sampleStatement.SentimentText} | Prediction: {(Convert.ToBoolean(resultprediction.Prediction) ? "Toxic" : "Not Toxic")} | Probability: {resultprediction.Probability} ");
  72. Console.WriteLine("=============== End of Predictions ===============");
  73. Console.WriteLine();
  74. }
  75. }
  76. }

程序运行后显示的结果:

  1. =============== Create and Train the Model ===============
  2. =============== End of training ===============
  3. =============== Evaluating Model accuracy with Test data===============
  4. Model quality metrics evaluation
  5. --------------------------------
  6. Accuracy: 83.33%
  7. Auc: 98.77%
  8. F1Score: 85.71%
  9. =============== End of model evaluation ===============
  10. =============== Prediction Test of model with a single sample and test dataset ===============
  11. Sentiment: This is a very rude movie | Prediction: Toxic | Probability: 0.7387648
  12. =============== End of Predictions ===============

可以看到在预测This is a very rude movie(这是一部粗制滥造的电影)这句评论时,模型判定其是有毒的:-)

ML.NET教程之情感分析(二元分类问题)的更多相关文章

  1. LSTM 文本情感分析/序列分类 Keras

    LSTM 文本情感分析/序列分类 Keras 请参考 http://spaces.ac.cn/archives/3414/   neg.xls是这样的 pos.xls是这样的neg=pd.read_e ...

  2. ML.NET 示例:二元分类之用户评论的情绪分析

    写在前面 准备近期将微软的machinelearning-samples翻译成中文,水平有限,如有错漏,请大家多多指正. 如果有朋友对此感兴趣,可以加入我:https://github.com/fei ...

  3. Python爬虫和情感分析简介

    摘要 这篇短文的目的是分享我这几天里从头开始学习Python爬虫技术的经验,并展示对爬取的文本进行情感分析(文本分类)的一些挖掘结果. 不同于其他专注爬虫技术的介绍,这里首先阐述爬取网络数据动机,接着 ...

  4. Python爬取《你好李焕英》豆瓣短评并基于SnowNLP做情感分析

    爬取过程在这里: Python爬取你好李焕英豆瓣短评并利用stylecloud制作更酷炫的词云图 本文基于前文爬取生成的douban.txt,基于SnowNLP做情感分析. 依赖库: 豆瓣镜像比较快: ...

  5. 使用ML.NET实现情感分析[新手篇]

    在发出<.NET Core玩转机器学习>和<使用ML.NET预测纽约出租车费>两文后,相信读者朋友们即使在不明就里的情况下,也能按照内容顺利跑完代码运行出结果,对使用.NET ...

  6. ML.NET 示例:二元分类之信用卡欺诈检测

    写在前面 准备近期将微软的machinelearning-samples翻译成中文,水平有限,如有错漏,请大家多多指正. 如果有朋友对此感兴趣,可以加入我:https://github.com/fei ...

  7. 使用ML.NET实现情感分析[新手篇]后补

    在<使用ML.NET实现情感分析[新手篇]>完成后,有热心的朋友建议说,为何例子不用中文的呢,其实大家是需要知道怎么预处理中文的数据集的.想想确实有道理,于是略微调整一些代码,权作示范. ...

  8. ML.NET 示例:二元分类之垃圾短信检测

    写在前面 准备近期将微软的machinelearning-samples翻译成中文,水平有限,如有错漏,请大家多多指正. 如果有朋友对此感兴趣,可以加入我:https://github.com/fei ...

  9. pyhanlp文本分类与情感分析

    语料库 本文语料库特指文本分类语料库,对应IDataSet接口.而文本分类语料库包含两个概念:文档和类目.一个文档只属于一个类目,一个类目可能含有多个文档.比如搜狗文本分类语料库迷你版.zip,下载前 ...

随机推荐

  1. hdu2255 奔小康赚大钱,最大权匹配,KM算法

    点击打开链接 最大权匹配 KM算法 算法步骤: 设顶点Xi的顶标为a[i],顶点Yi的顶标为b[i] ⅰ.初始时.a[i]为与Xi相关联的边的最大权值.b[j]=0.保证a[i]+b[j]>=w ...

  2. Attempt to present <TestViewController2: 0x7fd7f8d10f30> on <ViewController: 0x7fd7f8c054c0> whose view is not in the window hierarchy!

    当 storyboard里面的 按钮 即连接了 类文件里面的点击方法  又  连接了   storyboard里 另一个  控制器的  modal 就会出现类似Attempt to present & ...

  3. runtime MethodSwizzle 实践之扩展 NIAttributedLabel

    runtime MethodeSwizzle 提供 简单的方法交换已知类的  Method IMP. Method 可以是 外部可访问的 public 或者 private Method .所谓的属性 ...

  4. java转换日期格式为 RFC1123

    import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util. ...

  5. java解析Excel(xls、xlsx两种格式)

    https://www.cnblogs.com/hhhshct/p/7255915.html ***************************************************** ...

  6. [转]对form:input标签中的数字进行格式化

    原文地址:https://blog.csdn.net/qq_29662201/article/details/80708373 数字进行格式化(保留2位小数) 单独使用<fmt:formatNu ...

  7. pyenv BUILD FAILED解决方法

    在本机mac上安装pyenv安装成功后,用pyenv来安装python 3.5.0又出现了如下的问题: -> pyenv install 3.5.0 Downloading Python-3.5 ...

  8. TCP拥塞控制-慢启动、拥塞避免、快重传、快启动

    一般原理:发生拥塞控制的原因:资源(带宽.交换节点的缓存.处理机)的需求>可用资源. 作用:拥塞控制就是为了防止过多的数据注入到网络中,这样可以使网络中的路由器或者链路不至于过载.拥塞控制要做的 ...

  9. Spring Security 匿名认证

    1.项目截图: 2.匿名认证配置: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=& ...

  10. hdoj:2034

    #include <iostream> #include <vector> #include<algorithm> //包含sort函数 using namespa ...