2018-07-11 15:36:27 +00:00
|
|
|
|
using BotSharp.Core.Abstractions;
|
|
|
|
|
|
using BotSharp.Core.Agents;
|
2018-08-01 20:25:50 +00:00
|
|
|
|
using BotSharp.MachineLearning.NLP;
|
2018-07-11 15:36:27 +00:00
|
|
|
|
using EntityFrameworkCore.BootKit;
|
|
|
|
|
|
using Microsoft.Extensions.Configuration;
|
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
|
|
using System;
|
2018-08-01 20:25:50 +00:00
|
|
|
|
using System.Collections;
|
2018-07-11 15:36:27 +00:00
|
|
|
|
using System.Collections.Generic;
|
2018-08-01 20:25:50 +00:00
|
|
|
|
using System.IO;
|
2018-07-11 15:36:27 +00:00
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Text.RegularExpressions;
|
2018-08-01 20:25:50 +00:00
|
|
|
|
using System.Threading;
|
2018-07-11 15:36:27 +00:00
|
|
|
|
|
|
|
|
|
|
namespace BotSharp.Core.Engines.CRFsuite
|
|
|
|
|
|
{
|
|
|
|
|
|
public class CRFsuiteEntityRecognizer : INlpPipeline
|
|
|
|
|
|
{
|
|
|
|
|
|
public IConfiguration Configuration { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
public bool Process(Agent agent, JObject data)
|
|
|
|
|
|
{
|
|
|
|
|
|
var dc = new DefaultDataContextLoader().GetDefaultDc();
|
2018-08-01 20:25:50 +00:00
|
|
|
|
var corpus = agent.Corpus;
|
|
|
|
|
|
|
|
|
|
|
|
List<List<String>> tags = data["Tags"].ToObject<List<List<String>>>();
|
|
|
|
|
|
List<List<NlpToken>> tokens = data["Tokens"].ToObject<List<List<NlpToken>>>();
|
|
|
|
|
|
List<TrainingIntentExpression<TrainingIntentExpressionPart>> userSays = corpus.UserSays;
|
|
|
|
|
|
List<List<TrainingData>> list =new List<List<TrainingData>>();
|
2018-07-11 15:36:27 +00:00
|
|
|
|
|
2018-08-01 20:25:50 +00:00
|
|
|
|
FileStream fs = new FileStream("/home/bolo/Desktop/BotSharp/TrainingFiles/rawTrain.txt", FileMode.Create);
|
|
|
|
|
|
StreamWriter sw = new StreamWriter(fs);
|
2018-07-11 15:36:27 +00:00
|
|
|
|
|
2018-08-01 20:25:50 +00:00
|
|
|
|
for (int i = 0 ; i < tags.Count; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
List<TrainingData> curLine = Merge(tokens[i], tags[i], userSays[i].Entities);
|
|
|
|
|
|
list.Add(curLine);
|
|
|
|
|
|
curLine.ForEach(trainingData =>{
|
|
|
|
|
|
string[] wordParams = {trainingData.Entity, trainingData.Token, trainingData.Tag, trainingData.Chunk};
|
|
|
|
|
|
string wordStr = string.Join(" ", wordParams);
|
|
|
|
|
|
sw.Write(wordStr + "\n");
|
|
|
|
|
|
});
|
|
|
|
|
|
sw.Write("\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
sw.Flush();
|
|
|
|
|
|
sw.Close();
|
|
|
|
|
|
fs.Close();
|
|
|
|
|
|
|
2018-08-01 21:40:51 +00:00
|
|
|
|
new MachineLearning.CRFsuite.Ner().NerStart();
|
2018-08-01 20:25:50 +00:00
|
|
|
|
|
|
|
|
|
|
Runcmd();
|
2018-07-11 15:36:27 +00:00
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
2018-08-01 20:25:50 +00:00
|
|
|
|
|
|
|
|
|
|
public void Runcmd ()
|
|
|
|
|
|
{
|
|
|
|
|
|
string cmd = "/home/bolo/Desktop/BotSharp/TrainingFiles/crfsuite learn -m /home/bolo/Desktop/BotSharp/TrainingFiles/crfsuite/bolo.model /home/bolo/Desktop/BotSharp/TrainingFiles/crfsuite/1.txt";
|
|
|
|
|
|
System.Diagnostics.Process p = new System.Diagnostics.Process();
|
|
|
|
|
|
p.StartInfo.FileName = "sh";
|
|
|
|
|
|
p.StartInfo.UseShellExecute = false;
|
|
|
|
|
|
p.StartInfo.RedirectStandardInput = true;
|
|
|
|
|
|
p.StartInfo.RedirectStandardOutput = true;
|
|
|
|
|
|
p.StartInfo.RedirectStandardError = true;
|
|
|
|
|
|
p.StartInfo.CreateNoWindow = false;
|
|
|
|
|
|
p.Start();
|
|
|
|
|
|
|
|
|
|
|
|
p.StandardInput.WriteLine(cmd + "&exit");
|
|
|
|
|
|
p.StandardInput.AutoFlush = false;
|
|
|
|
|
|
|
|
|
|
|
|
string output = p.StandardOutput.ReadToEnd();
|
|
|
|
|
|
|
|
|
|
|
|
p.WaitForExit();//等待程序执行完退出进程
|
|
|
|
|
|
p.Close();
|
|
|
|
|
|
Console.WriteLine(output);
|
|
|
|
|
|
}
|
|
|
|
|
|
public List<TrainingData> Merge(List<NlpToken> sentence, List<string> tags, List<TrainingIntentExpressionPart> entities)
|
2018-07-11 15:36:27 +00:00
|
|
|
|
{
|
|
|
|
|
|
List<TrainingData> trainingTuple = new List<TrainingData>();
|
|
|
|
|
|
HashSet<String> entityWordBag = new HashSet<String>();
|
2018-08-01 20:25:50 +00:00
|
|
|
|
int wordCandidateCount = 0;
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < sentence.Count; i++)
|
2018-07-11 15:36:27 +00:00
|
|
|
|
{
|
2018-08-01 20:25:50 +00:00
|
|
|
|
TrainingIntentExpressionPart curEntity = null;
|
|
|
|
|
|
if (entities != null)
|
2018-07-11 15:36:27 +00:00
|
|
|
|
{
|
2018-08-01 20:25:50 +00:00
|
|
|
|
bool entityFinded = false;
|
|
|
|
|
|
entities.ForEach(entity => {
|
|
|
|
|
|
if (!entityFinded)
|
|
|
|
|
|
{
|
|
|
|
|
|
string[] words = entity.Value.Split(" ");
|
|
|
|
|
|
for (int j = 0; j < words.Length; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (sentence[i + j].Text == words[j])
|
|
|
|
|
|
{
|
|
|
|
|
|
wordCandidateCount++;
|
|
|
|
|
|
if (j == words.Length - 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
curEntity = entity;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
wordCandidateCount = 0;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (wordCandidateCount != 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
String entityName = curEntity.Entity.Contains(":")? curEntity.Entity.Substring(curEntity.Entity.IndexOf(":") + 1): curEntity.Entity;
|
|
|
|
|
|
foreach(string s in words)
|
|
|
|
|
|
{
|
|
|
|
|
|
trainingTuple.Add(new TrainingData(entityName, s, tags[i], "I"));
|
|
|
|
|
|
}
|
|
|
|
|
|
entityFinded = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2018-07-11 15:36:27 +00:00
|
|
|
|
}
|
2018-08-01 20:25:50 +00:00
|
|
|
|
if (wordCandidateCount == 0)
|
2018-07-11 15:36:27 +00:00
|
|
|
|
{
|
2018-08-01 20:25:50 +00:00
|
|
|
|
trainingTuple.Add(new TrainingData("O", sentence[i].Text, tags[i], "O"));
|
2018-07-11 15:36:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
else
|
2018-08-01 20:25:50 +00:00
|
|
|
|
{
|
|
|
|
|
|
i = i + wordCandidateCount - 1;
|
|
|
|
|
|
}
|
2018-07-11 15:36:27 +00:00
|
|
|
|
}
|
2018-08-01 20:25:50 +00:00
|
|
|
|
return trainingTuple;
|
2018-07-12 21:22:42 +00:00
|
|
|
|
|
2018-07-11 15:36:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2018-08-01 21:40:51 +00:00
|
|
|
|
|
2018-07-11 15:36:27 +00:00
|
|
|
|
public class TrainingData
|
|
|
|
|
|
{
|
|
|
|
|
|
public String Token { get; set; }
|
|
|
|
|
|
public String Entity { get; set; }
|
|
|
|
|
|
public String Tag { get; set; }
|
2018-08-01 20:25:50 +00:00
|
|
|
|
public String Chunk { get; set; }
|
2018-07-11 15:36:27 +00:00
|
|
|
|
|
2018-08-01 20:25:50 +00:00
|
|
|
|
public TrainingData(string entity, string token, string tag, string chunk)
|
2018-07-11 15:36:27 +00:00
|
|
|
|
{
|
|
|
|
|
|
this.Token = token;
|
|
|
|
|
|
this.Entity = entity;
|
|
|
|
|
|
this.Tag = tag;
|
2018-08-01 20:25:50 +00:00
|
|
|
|
this.Chunk = chunk;
|
2018-07-11 15:36:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class Token
|
|
|
|
|
|
{
|
|
|
|
|
|
public String Text { get; set; }
|
|
|
|
|
|
public int Offset { get; set; }
|
|
|
|
|
|
public int End { get; set; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class Entity
|
|
|
|
|
|
{
|
|
|
|
|
|
public String EntityName { get; set; }
|
|
|
|
|
|
public String Value { get; set; }
|
|
|
|
|
|
public int Start { get; set; }
|
|
|
|
|
|
public int End { get; set; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|