2018-09-04 02:05:57 +00:00
|
|
|
using BotSharp.Models.CRFLite;
|
2018-09-14 11:49:52 +00:00
|
|
|
using BotSharp.Models.CRFLite.Decoder;
|
2018-09-04 02:05:57 +00:00
|
|
|
using BotSharp.Models.CRFLite.Encoder;
|
|
|
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
2018-09-14 11:49:52 +00:00
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
2018-09-04 02:05:57 +00:00
|
|
|
|
|
|
|
|
namespace BotSharp.NLP.UnitTest.CRFLite
|
|
|
|
|
{
|
|
|
|
|
[TestClass]
|
|
|
|
|
public class EncoderTest
|
|
|
|
|
{
|
2018-09-14 12:23:37 +00:00
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
2018-09-04 02:05:57 +00:00
|
|
|
[TestMethod]
|
|
|
|
|
public void TestEncode()
|
|
|
|
|
{
|
|
|
|
|
var encoder = new CRFEncoder();
|
|
|
|
|
bool result = encoder.Learn(new EncoderOptions
|
|
|
|
|
{
|
2018-09-14 12:23:37 +00:00
|
|
|
/*
|
|
|
|
|
* traing corups format, split by tab, sentences is seperated by blank row
|
|
|
|
|
*
|
|
|
|
|
! PUN S
|
|
|
|
|
Tokyo NNP S_LOCATION
|
|
|
|
|
and CC S
|
|
|
|
|
New NNP B_LOCATION
|
|
|
|
|
York NNP E_LOCATION
|
|
|
|
|
are VBP S
|
|
|
|
|
major JJ S
|
|
|
|
|
financial JJ S
|
|
|
|
|
centers NNS S
|
|
|
|
|
. PUN S
|
|
|
|
|
*/
|
2018-09-14 11:49:52 +00:00
|
|
|
TrainingCorpusFileName = @"C:\Users\haipi\Documents\Projects\BotSharp\Data\CRF\eng.1k.training",
|
|
|
|
|
TemplateFileName = @"C:\Users\haipi\Documents\Projects\BotSharp\Data\CRF\template.en",
|
|
|
|
|
ModelFileName = @"C:\Users\haipi\Documents\Projects\BotSharp\Data\CRF\ner_model"
|
2018-09-04 02:05:57 +00:00
|
|
|
});
|
2018-09-14 11:49:52 +00:00
|
|
|
|
|
|
|
|
Assert.IsTrue(result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object rdLocker = new object();
|
|
|
|
|
|
|
|
|
|
[TestMethod]
|
|
|
|
|
public void TestDecode()
|
|
|
|
|
{
|
|
|
|
|
var decoder = new CRFDecoder();
|
|
|
|
|
var options = new DecoderOptions
|
|
|
|
|
{
|
2018-09-14 12:23:37 +00:00
|
|
|
/*
|
|
|
|
|
* input data format
|
|
|
|
|
*
|
|
|
|
|
In IN
|
|
|
|
|
its PRP$
|
|
|
|
|
sixth JJ
|
|
|
|
|
edition NN
|
|
|
|
|
, PUN
|
|
|
|
|
the DT
|
|
|
|
|
Beijing NNP
|
|
|
|
|
. PUN
|
|
|
|
|
*/
|
2018-09-14 11:49:52 +00:00
|
|
|
InputFileName = @"C:\Users\haipi\Documents\Projects\BotSharp\Data\CRF\test.txt",
|
|
|
|
|
ModelFileName = @"C:\Users\haipi\Documents\Projects\BotSharp\Data\CRF\ner_model"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var sr = new StreamReader(options.InputFileName);
|
|
|
|
|
|
|
|
|
|
//Load encoded model from file
|
|
|
|
|
decoder.LoadModel(options.ModelFileName);
|
|
|
|
|
|
|
|
|
|
var parallelOption = new ParallelOptions();
|
|
|
|
|
parallelOption.MaxDegreeOfParallelism = options.Thread;
|
|
|
|
|
Parallel.For(0, options.Thread, parallelOption, t =>
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
//Create decoder tagger instance. If the running environment is multi-threads, each thread needs a separated instance
|
|
|
|
|
var tagger = decoder.CreateTagger(options.NBest, options.MaxWord);
|
|
|
|
|
tagger.set_vlevel(options.ProbLevel);
|
|
|
|
|
|
|
|
|
|
//Initialize result
|
|
|
|
|
var crf_out = new crf_seg_out[options.NBest];
|
|
|
|
|
for (var i = 0; i < options.NBest; i++)
|
|
|
|
|
{
|
|
|
|
|
crf_out[i] = new crf_seg_out(tagger.crf_max_word_num);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var inbuf = new List<List<string>>();
|
2018-09-14 12:23:37 +00:00
|
|
|
|
|
|
|
|
inbuf.Add(new List<string>
|
|
|
|
|
{
|
|
|
|
|
"' PUN",
|
|
|
|
|
"' POS",
|
|
|
|
|
"Duchy NNP",
|
|
|
|
|
"of IN",
|
|
|
|
|
"Lithuania NNP"
|
|
|
|
|
});
|
|
|
|
|
|
2018-09-14 11:49:52 +00:00
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
lock (rdLocker)
|
|
|
|
|
{
|
|
|
|
|
if (ReadRecord(inbuf, sr) == false)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Call CRFSharp wrapper to predict given string's tags
|
2018-09-14 12:23:37 +00:00
|
|
|
decoder.Segment((CRFTermOut[])crf_out, (DecoderTagger)tagger, inbuf);
|
2018-09-14 11:49:52 +00:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sr.Close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool ReadRecord(List<List<string>> inbuf, StreamReader sr)
|
|
|
|
|
{
|
|
|
|
|
inbuf.Clear();
|
|
|
|
|
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
var strLine = sr.ReadLine();
|
|
|
|
|
if (strLine == null)
|
|
|
|
|
{
|
|
|
|
|
//At the end of current file
|
|
|
|
|
if (inbuf.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
strLine = strLine.Trim();
|
|
|
|
|
if (strLine.Length == 0)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Read feature set for each record
|
|
|
|
|
var items = strLine.Split(new char[] { '\t' });
|
|
|
|
|
inbuf.Add(new List<string>());
|
|
|
|
|
for (int index = 0; index < items.Length; index++)
|
|
|
|
|
{
|
|
|
|
|
var item = items[index];
|
|
|
|
|
inbuf[inbuf.Count - 1].Add(item);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-09-04 02:05:57 +00:00
|
|
|
}
|
|
|
|
|
}
|