2018-08-16 22:27:50 +00:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
2018-08-17 20:49:29 +00:00
|
|
|
|
using System.Linq;
|
2018-08-16 22:27:50 +00:00
|
|
|
|
using System.Text;
|
|
|
|
|
|
using BotSharp.NLP.Tokenize;
|
|
|
|
|
|
|
|
|
|
|
|
namespace BotSharp.NLP.Tag
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// N-Gramm taggers are based on a simple statistical algorithm:
|
|
|
|
|
|
/// for each token, assign the tag that is most likely for that particular token.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class NGramTagger : ITagger
|
|
|
|
|
|
{
|
2018-08-17 22:22:05 +00:00
|
|
|
|
private List<NGramFreq> _contextMapping { get; set; }
|
2018-08-16 22:27:50 +00:00
|
|
|
|
|
|
|
|
|
|
public void Tag(Sentence sentence, TagOptions options)
|
|
|
|
|
|
{
|
2018-08-17 20:49:29 +00:00
|
|
|
|
// need training to generate model
|
2018-08-17 22:22:05 +00:00
|
|
|
|
if(_contextMapping == null)
|
2018-08-17 20:49:29 +00:00
|
|
|
|
{
|
2018-08-17 22:22:05 +00:00
|
|
|
|
Train(options.Corpus, options);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Train(List<Sentence> sentences, TagOptions options)
|
|
|
|
|
|
{
|
|
|
|
|
|
_contextMapping = new List<NGramFreq>();
|
2018-08-17 20:49:29 +00:00
|
|
|
|
|
2018-08-17 22:22:05 +00:00
|
|
|
|
for (int idx = 0; idx < options.Corpus.Count; idx++)
|
|
|
|
|
|
{
|
|
|
|
|
|
var sent = options.Corpus[idx];
|
2018-08-17 20:49:29 +00:00
|
|
|
|
|
2018-08-17 22:22:05 +00:00
|
|
|
|
for (int ngram = 1; ngram < options.NGram; ngram++)
|
2018-08-17 20:49:29 +00:00
|
|
|
|
{
|
2018-08-17 22:22:05 +00:00
|
|
|
|
sent.Words.Insert(0, new Token { Text = "NIL", Pos = options.Tag, Start = (ngram - 1) * 3 });
|
|
|
|
|
|
}
|
2018-08-17 20:49:29 +00:00
|
|
|
|
|
2018-08-17 22:22:05 +00:00
|
|
|
|
int pos = options.NGram - 1;
|
|
|
|
|
|
for (pos = 1; pos < sent.Words.Count; pos++)
|
|
|
|
|
|
{
|
|
|
|
|
|
var freq = new NGramFreq
|
2018-08-17 20:49:29 +00:00
|
|
|
|
{
|
2018-08-17 22:22:05 +00:00
|
|
|
|
PrecedingTokens = new List<Token> { sent.Words[pos - 1] },
|
|
|
|
|
|
Token = sent.Words[pos],
|
|
|
|
|
|
Count = 0
|
|
|
|
|
|
};
|
2018-08-17 20:49:29 +00:00
|
|
|
|
|
2018-08-17 22:22:05 +00:00
|
|
|
|
_contextMapping.Add(freq);
|
|
|
|
|
|
}
|
2018-08-17 20:49:29 +00:00
|
|
|
|
}
|
2018-08-16 22:27:50 +00:00
|
|
|
|
|
2018-08-17 22:22:05 +00:00
|
|
|
|
/*var results = (from c in cache
|
|
|
|
|
|
group c by c.Item1 into g
|
|
|
|
|
|
select new { g.Key, Count = g.Count() }).ToList();*/
|
2018-08-16 22:27:50 +00:00
|
|
|
|
}
|
2018-08-17 20:49:29 +00:00
|
|
|
|
|
|
|
|
|
|
private class NGramFreq
|
|
|
|
|
|
{
|
2018-08-17 22:22:05 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Tokens prior current token
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public List<Token> PrecedingTokens { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Current token tag
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public Token Token { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Occurence frequency
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public int Count { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
public string Context
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return $"{PrecedingTokens.First().Pos} {Token.Text} {Token.Pos}";
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2018-08-17 20:49:29 +00:00
|
|
|
|
}
|
2018-08-16 22:27:50 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|