一、要解决的问题


问题:常常一些单位或组织召开会议时需要录入会议记录,我们需要通过机器学习对用户输入的文本内容进行自动评判,合格或不合格。(同样的问题还类似垃圾短信检测、工作日志质量分析等。)


处理思路:我们人工对现有会议记录进行评判,标记合格或不合格,通过对这些记录的学习形成模型,学习算法仍采用二元分类的快速决策树算法,和上一篇文章不同,这次输入的特征值不再是浮点数,而是中文文本。这里就要涉及到文本特征提取。


为什么要进行文本特征提取呢?因为文本是人类的语言,符号文字序列不能直接传递给算法。而计算机程序算法只接受具有固定长度的数字矩阵特征向量(float或float数组),无法理解可变长度的文本文档。

常用的文本特征提取方法有如下几种:



以上只是需要了解大致的含义,我们不需要去实现一个文本特征提取的算法,只需要使用平台自带的方法就可以了。


系统自带的文本特征处理的方法,输入是一个字符串,要求将一个语句中的词语用空格分开,英语的句子中词汇是天生通过空格分割的,但中文句子不是,所以我们需要首先进行分词操作,具体流程如下:



 

二、代码

代码整体流程和上一篇文章描述的基本一致,为简便起见,我们省略了模型存储和读取的过程。

先看一下数据集:



 

代码如下:
namespace BinaryClassification_TextFeaturize { class Program { static readonly
string DataPath = Path.Combine(Environment.CurrentDirectory, "Data", "
meeting_data_full.csv"); static void Main(string[] args) { MLContext mlContext =
new MLContext(); var fulldata =
mlContext.Data.LoadFromTextFile<MeetingInfo>(DataPath, separatorChar:',',
hasHeader:false); var trainTestData = mlContext.Data.TrainTestSplit(fulldata,
testFraction:0.15); var trainData = trainTestData.TrainSet; var testData =
trainTestData.TestSet;var trainingPipeline =
mlContext.Transforms.CustomMapping<JiebaLambdaInput,
JiebaLambdaOutput>(mapAction: JiebaLambda.MyAction, contractName:"JiebaLambda")
.Append(mlContext.Transforms.Text.FeaturizeText(outputColumnName:"Features",
inputColumnName:"JiebaText"))
.Append(mlContext.BinaryClassification.Trainers.FastTree(labelColumnName:"Label"
, featureColumnName:"Features")); ITransformer trainedModel =
trainingPipeline.Fit(trainData);//评估 var predictions =
trainedModel.Transform(testData);var metrics =
mlContext.BinaryClassification.Evaluate(data: predictions, labelColumnName:"
Label"); Console.WriteLine($"Evalution Accuracy: {metrics.Accuracy:P2}"); //
创建预测引擎 var predEngine = mlContext.Model.CreatePredictionEngine<MeetingInfo,
PredictionResult>(trainedModel); //预测1 MeetingInfo sampleStatement1 = new
MeetingInfo { Text ="支委会。" }; var predictionresult1 =
predEngine.Predict(sampleStatement1); Console.WriteLine($"
{sampleStatement1.Text}:{predictionresult1.PredictedLabel}"); //预测2 MeetingInfo
sampleStatement2 =new MeetingInfo { Text = "开展新时代中国特色社会主义思想三十讲党员答题活动。" }; var
predictionresult2 = predEngine.Predict(sampleStatement2); Console.WriteLine($"
{sampleStatement2.Text}:{predictionresult2.PredictedLabel}"); Console.WriteLine(
"Press any to exit!"); Console.ReadKey(); } } public class MeetingInfo {
[LoadColumn(0)] public bool Label { get; set; } [LoadColumn(1)] public string
Text {get; set; } } public class PredictionResult : MeetingInfo { public string
JiebaText {get; set; } public float[] Features { get; set; } public bool
PredictedLabel;public float Score; public float Probability; } } View Code
  

三、代码分析

 和上一篇文章中相似的内容我就不再重复解释了,重点介绍一下学习管道的建立。
var trainingPipeline = mlContext.Transforms.CustomMapping<JiebaLambdaInput,
JiebaLambdaOutput>(mapAction: JiebaLambda.MyAction, contractName:"JiebaLambda")
.Append(mlContext.Transforms.Text.FeaturizeText(outputColumnName:"Features",
inputColumnName:"JiebaText"))
.Append(mlContext.BinaryClassification.Trainers.FastTree(labelColumnName:"Label"
, featureColumnName:"Features"));

 首先,在进行文本特征转换之前,我们需要对文本进行分词操作,您可以对样本数据进行预处理,形成分词的结果再进行学习,我们没有采用这个方法,而是自定义了一个分词处理的数据处理管道,通过这个管道进行分词,其定义如下:
namespace BinaryClassification_TextFeaturize { public class JiebaLambdaInput {
public string Text { get; set; } } public class JiebaLambdaOutput { public
string JiebaText { get; set; } } public class JiebaLambda { public static void
MyAction(JiebaLambdaInput input, JiebaLambdaOutput output) {
JiebaNet.Segmenter.JiebaSegmenter jiebaSegmenter= new
JiebaNet.Segmenter.JiebaSegmenter(); output.JiebaText= string.Join(" ",
jiebaSegmenter.Cut(input.Text)); } } }
   最后我们新建了两个对象进行实际预测:
//预测1 MeetingInfo sampleStatement1 = new MeetingInfo { Text = "支委会。" }; var
predictionresult1 = predEngine.Predict(sampleStatement1); Console.WriteLine($"
{sampleStatement1.Text}:{predictionresult1.PredictedLabel}"); //预测2 MeetingInfo
sampleStatement2 =new MeetingInfo { Text = "开展新时代中国特色社会主义思想三十讲党员答题活动。" }; var
predictionresult2 = predEngine.Predict(sampleStatement2); Console.WriteLine($"
{sampleStatement2.Text}:{predictionresult2.PredictedLabel}");
 预测结果如下:



 

四、调试

上一篇文章提到,当我们运行Transform方法时,会对所有记录进行转换,转换后的数据集是什么样子呢,我们可以写一个调试程序看一下。
var predictions = trainedModel.Transform(testData); DebugData(mlContext,
predictions);private static void DebugData(MLContext mlContext, IDataView
predictions) {var trainDataShow = new
List<PredictionResult>(mlContext.Data.CreateEnumerable<PredictionResult>(predictions,
false, true)); foreach (var dataline in trainDataShow) {
dataline.PrintToConsole(); } }public class PredictionResult { public string
JiebaText {get; set; } public float[] Features { get; set; } public bool
PredictedLabel;public float Score; public float Probability; public void
PrintToConsole() { Console.WriteLine($"JiebaText={JiebaText}");
Console.WriteLine($"
PredictedLabel:{PredictedLabel},Score:{Score},Probability:{Probability}");
Console.WriteLine($"TextFeatures Length:{Features.Length}"); if (Features !=
null) { foreach (var f in Features) { Console.Write($"{f},"); }
Console.WriteLine(); } Console.WriteLine(); } }
  通过对调试结果的分析,可以看到整个数据处理管道的工作流程。

 

五、资源获取

源码下载地址:https://github.com/seabluescn/Study_ML.NET

工程名称:BinaryClassification_TextFeaturize

点击查看机器学习框架ML.NET学习笔记系列文章目录 <https://www.cnblogs.com/seabluescn/p/10904391.html>

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信