ML.NET教程之情感分析(二元分类问题)
机器学习的工作流程分为以下几个步骤:
- 理解问题
- 准备数据
- 加载数据
- 提取特征
- 构建与训练
- 训练模型
- 评估模型
- 运行
- 使用模型
理解问题
本教程需要解决的问题是根据网站内评论的意见采取合适的行动。
可用的训练数据集中,网站评论可能是有毒(toxic)(1)或者无毒(not toxic)(0)两种类型。这种场景下,机器学习中的分类任务最为适合。
分类任务用于区分数据内的类别(category),类型(type)或种类(class)。常见的例子有:
- 识别情感是正面或是负面
- 将邮件按照是否为垃圾邮件归类
- 判定病人的实验室样本是否为癌症
- 按照客户的偏好进行分类以响应销售活动
分类任务可以是二元又或是多元的。这里面临的是二元分类的问题。
准备数据
首先建立一个控制台应用程序,基于.NET Core。完成搭建后,添加Microsoft.ML类库包。接着在工程下新建名为Data
的文件夹。
之后,下载WikiPedia-detox-250-line-data.tsv与wikipedia-detox-250-line-test.tsv文件,并将它们放入Data
文件夹,值得注意的是,这两个文件的Copy to Output Directory
属性需要修改成Copy if newer
。
加载数据
在Program.cs
文件的Main
方法里加入以下代码:
MLContext mlContext = new MLContext(seed: 0);
_textLoader = mlContext.Data.TextReader(new TextLoader.Arguments()
{
Separator = "tab",
HasHeader = true,
Column = new[]
{
new TextLoader.Column("Label", DataKind.Bool, 0),
new TextLoader.Column("SentimentText", DataKind.Text, 1)
}
});
其目的是通过使用TextLoader类为数据的加载作好准备。
Column属性中构建了两个对象,即对应数据集中的两列数据。不过第一列这里必须使用Label
而不是Sentiment
。
提取特征
新建一个SentimentData.cs
文件,其中加入SentimentData类与SentimentPrediction。
public class SentimentData
{
[Column(ordinal: "0", name: "Label")]
public float Sentiment;
[Column(ordinal: "1")]
public string SentimentText;
}
public class SentimentPrediction
{
[ColumnName("PredictedLabel")]
public bool Prediction { get; set; }
[ColumnName("Probability")]
public float Probability { get; set; }
[ColumnName("Score")]
public float Score { get; set; }
}
SentimentData类中的SentimentText为输入数据集的特征,Sentiment则是数据集的标记(label)。
SentimentPrediction类用于模型被训练后的预测。
训练模型
在Program
类中加入Train
方法。首先它会读取训练数据集,接着将特征列中的文本型数据转换为浮点型数组并设定了训练时所使用的决策树二元分类模型。之后,即是实际训练模型。
public static ITransformer Train(MLContext mlContext, string dataPath)
{
IDataView dataView = _textLoader.Read(dataPath);
var pipeline = mlContext.Transforms.Text.FeaturizeText("SentimentText", "Features")
.Append(mlContext.BinaryClassification.Trainers.FastTree(numLeaves: 50, numTrees: 50, minDatapointsInLeaves: 20));
Console.WriteLine("=============== Create and Train the Model ===============");
var model = pipeline.Fit(dataView);
Console.WriteLine("=============== End of training ===============");
Console.WriteLine();
return model;
}
评估模型
加入Evaluate
方法。到了这一步,需要读取的是用于测试的数据集,且读取后的数据仍然需要转换成合适的数据类型。
public static void Evaluate(MLContext mlContext, ITransformer model)
{
IDataView dataView = _textLoader.Read(_testDataPath);
Console.WriteLine("=============== Evaluating Model accuracy with Test data===============");
var predictions = model.Transform(dataView);
var metrics = mlContext.BinaryClassification.Evaluate(predictions, "Label");
Console.WriteLine();
Console.WriteLine("Model quality metrics evaluation");
Console.WriteLine("--------------------------------");
Console.WriteLine($"Accuracy: {metrics.Accuracy:P2}");
Console.WriteLine($"Auc: {metrics.Auc:P2}");
Console.WriteLine($"F1Score: {metrics.F1Score:P2}");
Console.WriteLine("=============== End of model evaluation ===============");
}
使用模型
训练及评估模型完成后,就可以正式使用它了。这里需要建立一个用于预测的对象(PredictionFunction
),其预测方法的输入参数是SentimentData
类型,返回结果为SentimentPrediction
类型。
private static void Predict(MLContext mlContext, ITransformer model)
{
var predictionFunction = model.MakePredictionFunction<SentimentData, SentimentPrediction>(mlContext);
SentimentData sampleStatement = new SentimentData
{
SentimentText = "This is a very rude movie"
};
var resultprediction = predictionFunction.Predict(sampleStatement);
Console.WriteLine();
Console.WriteLine("=============== Prediction Test of model with a single sample and test dataset ===============");
Console.WriteLine();
Console.WriteLine($"Sentiment: {sampleStatement.SentimentText} | Prediction: {(Convert.ToBoolean(resultprediction.Prediction) ? "Toxic" : "Not Toxic")} | Probability: {resultprediction.Probability} ");
Console.WriteLine("=============== End of Predictions ===============");
Console.WriteLine();
}
完整示例代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.ML;
using Microsoft.ML.Core.Data;
using Microsoft.ML.Runtime.Data;
using Microsoft.ML.Transforms.Text;
namespace SentimentAnalysis
{
class Program
{
static readonly string _trainDataPath = Path.Combine(Environment.CurrentDirectory, "Data", "wikipedia-detox-250-line-data.tsv");
static readonly string _testDataPath = Path.Combine(Environment.CurrentDirectory, "Data", "wikipedia-detox-250-line-test.tsv");
static readonly string _modelPath = Path.Combine(Environment.CurrentDirectory, "Data", "Model.zip");
static TextLoader _textLoader;
static void Main(string[] args)
{
MLContext mlContext = new MLContext(seed: 0);
_textLoader = mlContext.Data.TextReader(new TextLoader.Arguments()
{
Separator = "tab",
HasHeader = true,
Column = new[]
{
new TextLoader.Column("Label", DataKind.Bool, 0),
new TextLoader.Column("SentimentText", DataKind.Text, 1)
}
});
var model = Train(mlContext, _trainDataPath);
Evaluate(mlContext, model);
Predict(mlContext, model);
Console.Read();
}
public static ITransformer Train(MLContext mlContext, string dataPath)
{
IDataView dataView = _textLoader.Read(dataPath);
var pipeline = mlContext.Transforms.Text.FeaturizeText("SentimentText", "Features")
.Append(mlContext.BinaryClassification.Trainers.FastTree(numLeaves: 50, numTrees: 50, minDatapointsInLeaves: 20));
Console.WriteLine("=============== Create and Train the Model ===============");
var model = pipeline.Fit(dataView);
Console.WriteLine("=============== End of training ===============");
Console.WriteLine();
return model;
}
public static void Evaluate(MLContext mlContext, ITransformer model)
{
IDataView dataView = _textLoader.Read(_testDataPath);
Console.WriteLine("=============== Evaluating Model accuracy with Test data===============");
var predictions = model.Transform(dataView);
var metrics = mlContext.BinaryClassification.Evaluate(predictions, "Label");
Console.WriteLine();
Console.WriteLine("Model quality metrics evaluation");
Console.WriteLine("--------------------------------");
Console.WriteLine($"Accuracy: {metrics.Accuracy:P2}");
Console.WriteLine($"Auc: {metrics.Auc:P2}");
Console.WriteLine($"F1Score: {metrics.F1Score:P2}");
Console.WriteLine("=============== End of model evaluation ===============");
}
private static void Predict(MLContext mlContext, ITransformer model)
{
var predictionFunction = model.MakePredictionFunction<SentimentData, SentimentPrediction>(mlContext);
SentimentData sampleStatement = new SentimentData
{
SentimentText = "This is a very rude movie"
};
var resultprediction = predictionFunction.Predict(sampleStatement);
Console.WriteLine();
Console.WriteLine("=============== Prediction Test of model with a single sample and test dataset ===============");
Console.WriteLine();
Console.WriteLine($"Sentiment: {sampleStatement.SentimentText} | Prediction: {(Convert.ToBoolean(resultprediction.Prediction) ? "Toxic" : "Not Toxic")} | Probability: {resultprediction.Probability} ");
Console.WriteLine("=============== End of Predictions ===============");
Console.WriteLine();
}
}
}
程序运行后显示的结果:
=============== Create and Train the Model ===============
=============== End of training ===============
=============== Evaluating Model accuracy with Test data===============
Model quality metrics evaluation
--------------------------------
Accuracy: 83.33%
Auc: 98.77%
F1Score: 85.71%
=============== End of model evaluation ===============
=============== Prediction Test of model with a single sample and test dataset ===============
Sentiment: This is a very rude movie | Prediction: Toxic | Probability: 0.7387648
=============== End of Predictions ===============
可以看到在预测This is a very rude movie
(这是一部粗制滥造的电影)这句评论时,模型判定其是有毒的:-)
ML.NET教程之情感分析(二元分类问题)的更多相关文章
- LSTM 文本情感分析/序列分类 Keras
LSTM 文本情感分析/序列分类 Keras 请参考 http://spaces.ac.cn/archives/3414/ neg.xls是这样的 pos.xls是这样的neg=pd.read_e ...
- ML.NET 示例:二元分类之用户评论的情绪分析
写在前面 准备近期将微软的machinelearning-samples翻译成中文,水平有限,如有错漏,请大家多多指正. 如果有朋友对此感兴趣,可以加入我:https://github.com/fei ...
- Python爬虫和情感分析简介
摘要 这篇短文的目的是分享我这几天里从头开始学习Python爬虫技术的经验,并展示对爬取的文本进行情感分析(文本分类)的一些挖掘结果. 不同于其他专注爬虫技术的介绍,这里首先阐述爬取网络数据动机,接着 ...
- Python爬取《你好李焕英》豆瓣短评并基于SnowNLP做情感分析
爬取过程在这里: Python爬取你好李焕英豆瓣短评并利用stylecloud制作更酷炫的词云图 本文基于前文爬取生成的douban.txt,基于SnowNLP做情感分析. 依赖库: 豆瓣镜像比较快: ...
- 使用ML.NET实现情感分析[新手篇]
在发出<.NET Core玩转机器学习>和<使用ML.NET预测纽约出租车费>两文后,相信读者朋友们即使在不明就里的情况下,也能按照内容顺利跑完代码运行出结果,对使用.NET ...
- ML.NET 示例:二元分类之信用卡欺诈检测
写在前面 准备近期将微软的machinelearning-samples翻译成中文,水平有限,如有错漏,请大家多多指正. 如果有朋友对此感兴趣,可以加入我:https://github.com/fei ...
- 使用ML.NET实现情感分析[新手篇]后补
在<使用ML.NET实现情感分析[新手篇]>完成后,有热心的朋友建议说,为何例子不用中文的呢,其实大家是需要知道怎么预处理中文的数据集的.想想确实有道理,于是略微调整一些代码,权作示范. ...
- ML.NET 示例:二元分类之垃圾短信检测
写在前面 准备近期将微软的machinelearning-samples翻译成中文,水平有限,如有错漏,请大家多多指正. 如果有朋友对此感兴趣,可以加入我:https://github.com/fei ...
- pyhanlp文本分类与情感分析
语料库 本文语料库特指文本分类语料库,对应IDataSet接口.而文本分类语料库包含两个概念:文档和类目.一个文档只属于一个类目,一个类目可能含有多个文档.比如搜狗文本分类语料库迷你版.zip,下载前 ...
随机推荐
- 〖Java〗Eclispe安装和使用viplugin
习惯了VIM的操作,每次打开Eclipse都习惯性的按下 hjkl: 感觉蛋疼了使用一下VIPlugin,发现给编码速度造成了成吨的伤害- 这个插件对于习惯于使用VIM的程序员来说,简直太有必要了.. ...
- Java 8系列之Stream的基本语法详解
本文转至:https://blog.csdn.net/io_field/article/details/54971761 Stream系列: Java 8系列之Stream的基本语法详解 Java 8 ...
- Rocket Typist for Mac(增强型文本快速输入工具)破解版安装
1.软件简介 Rocket Typist 是 macOS 系统上一款增强型文本快速输入工具,我们可以利用这款工具预先设置保存好很多日常生活学习或是工作中常用的文本片段,还能设定部分内容为变量,当 ...
- R语言手册
在R的官方教程里是这么给R下注解的:一个数据分析和图形显示的程序设计环境(A system for data analysis and visualization which is built bas ...
- hexo + Github Page 0元建立博客攻略
传送门: 5分钟 0元搭建个人独立博客网站(一):https://mp.weixin.qq.com/s/69isJE191WV2gaVbjrwTtw 5分钟 0元搭建个人独立博客网站(二):https ...
- Java 汇编代码
https://shipilev.net/blog/2015/black-magic-method-dispatch/ https://github.com/shipilev/article-meth ...
- python工具 - 从文件名读取特定信息到excel表格
情景:文件名中包含学号和用户名,其中用户名在前学好在后,学号为2位,如harry33.txt.natasha12.txt. 要求:将多个文件名中的用户名与学号分开并保存到excle中. 代码部分: i ...
- pdfcrop不能使用
最近,用到了pdfcrop,用来去除pdf中空白的边. 但是使用pdfcrop --margins 0 *.pdf 后,给出了错误: Error: pdfcrop cannot call ghost ...
- 《转》Babel 入门教程
ECMAScript 6是JavaScript语言的下一代标准,已经在2015年6月正式发布了.Mozilla公司将在这个标准的基础上,推出JavaScript 2.0.ES6的目标,是使得JavaS ...
- linux每日命令(38):iostat命令
Linux系统中的 iostat是I/O statistics(输入/输出统计)的缩写,iostat工具将对系统的磁盘操作活动进行监视.它的特点是汇报磁盘活动统计情况,同时也会汇报出CPU使用情况.同 ...