public bool ProcessTrainingSample(SentenceData sample) { n_learn_samples++; for (int iword = 1; iword < sample.CountWords() - 1; ++iword) { WordData token = sample.GetWord(iword); string wordform = token.GetWord().ToLower(); if (wordform.Contains(" ")) { // кратные пробелы сокращаем до одинарных System.Text.RegularExpressions.Regex rx = new System.Text.RegularExpressions.Regex("[ ]{2,}"); wordform = rx.Replace(wordform, " "); } string lemma = gren.GetEntryName(token.GetEntryID()); if (IsUnknownLexem(lemma) || IsNumword(lemma)) { continue; } int POS_tag = tags.MatchTags(token, gren); table.Store(POS_tag, wordform, lemma); n_learn_wordforms++; } return(true); }
public bool ProcessSample(SampleData sample) { n_learn_samples++; for (int iword = 1; iword < sample.morphology.Count - 1; ++iword) { SolarixGrammarEngineNET.SyntaxTreeNode token = sample.morphology[iword]; string wordform = token.GetWord().ToLower(); if (wordform.Contains(" ")) { System.Text.RegularExpressions.Regex rx = new System.Text.RegularExpressions.Regex("[ ]{2,}"); wordform = rx.Replace(wordform, " "); } string lemma = gren.GetEntryName(token.GetEntryID()); if (IsUnknownLexem(lemma) || IsNumword(lemma)) { continue; } int POS_tag = tags.MatchTags(token, gren); table.Store(POS_tag, wordform, lemma); n_learn_wordforms++; } return(true); }
public bool ProcessSample(string line) { n_learn_samples++; // Морфологический разбор using (SolarixGrammarEngineNET.AnalysisResults tokens = gren.AnalyzeMorphology(line, LanguageID, SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags.SOL_GREN_COMPLETE_ONLY)) { List <string> sfx = new List <string>(); List <int> sfx_index = new List <int>(); List <string> sfx_lemma = new List <string>(); List <int> sfx_lemma_index = new List <int>(); int last_word_index = tokens.Count - 1; for (int iword = 0; iword < tokens.Count; ++iword) { string word = tokens[iword].GetWord().ToLower(); string suffix = GetTokenSuffix(iword, last_word_index, tokens[iword]); sfx.Add(suffix); int index = MatchSuffix(suffix, true); sfx_index.Add(index); int ekey = tokens[iword].GetEntryID(); string ename = gren.GetEntryName(ekey); string lemma; if (IsUnknownLexem(ename)) { lemma = word; } else { lemma = ename.ToLower(); } sfx_lemma.Add(GetSuffix(lemma)); sfx_lemma_index.Add(MatchSuffix(GetSuffix(lemma), true)); } for (int iword = 1; iword < tokens.Count - 1; ++iword) { string tag1 = TagLabel(-1, sfx_index[iword - 1]); string tag2 = TagLabel(0, sfx_index[iword]); string tag3 = TagLabel(1, sfx_index[iword + 1]); string res = ResultLabel(sfx_lemma_index[iword]); WriteTrain(tag1, tag2, tag3, res); } } return(true); }
string GetTokenVersionLemma(int version_index, SolarixGrammarEngineNET.SyntaxTreeNode token) { string lemma = string.Empty; int ekey = token.GetVersionEntryID(version_index); string ename = gren.GetEntryName(ekey); if (IsUnknownLexem(ename)) { lemma = token.GetWord().ToLower(); } else { lemma = ename.ToLower(); } return(lemma); }
public bool ProcessSample(string line) { // Морфологический разбор using (SolarixGrammarEngineNET.AnalysisResults tokens = gren.AnalyzeMorphology(line, LanguageID, SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags.SOL_GREN_COMPLETE_ONLY)) { int last_word_index = tokens.Count - 1; for (int i = 0; i < tokens.Count; ++i) { SolarixGrammarEngineNET.SyntaxTreeNode token = tokens[i]; int suffix_id1 = GetTokenSuffix(i, last_word_index, token); int nver = token.VersionCount(); for (int j = 0; j < nver; ++j) { int ver_ekey = token.GetVersionEntryID(j); string ename = gren.GetEntryName(ver_ekey); int suffix_id2 = GetFormSuffix(i, last_word_index, ename); } } } using (SolarixGrammarEngineNET.AnalysisResults projs = gren.AnalyzeMorphology(line, LanguageID, SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags.SOL_GREN_TOKENIZE_ONLY)) { int last_word_index = projs.Count - 1; for (int i = 0; i < projs.Count; ++i) { SolarixGrammarEngineNET.SyntaxTreeNode token = projs[i]; int suffix_id1 = GetTokenSuffix(i, last_word_index, token); int nver = token.VersionCount(); for (int j = 0; j < nver; ++j) { int ver_ekey = token.GetVersionEntryID(j); string ename = gren.GetEntryName(ver_ekey); int suffix_id2 = GetFormSuffix(i, last_word_index, ename); } } } return(true); }
private static string TermToString(SolarixGrammarEngineNET.GrammarEngine2 gren, SolarixGrammarEngineNET.SyntaxTreeNode term) { int id_entry = term.GetEntryID(); if (gren.GetEntryName(id_entry) == "???") { return(term.GetWord()); } string res_word = gren.RestoreCasing(id_entry, term.GetWord()); return(res_word); }
public string GetContextPoint(SolarixGrammarEngineNET.GrammarEngine2 gren) { System.Text.StringBuilder b = new StringBuilder(); if (!string.IsNullOrEmpty(lexem)) { b.AppendFormat("\"{0}\"", lexem); } else { if (id_class != -1) { b.AppendFormat("{0}:*", gren.GetClassName(id_class)); } else { int pos = gren.GetEntryClass(id_entry); b.AppendFormat("{0}:{1}", gren.GetClassName(pos), gren.GetEntryName(id_entry)); } b.Append("{"); // выводим список координатных пар foreach (SolarixGrammarEngineNET.CoordPair p in pairs) { string CoordName = gren.GetCoordName(p.CoordID); if (gren.CountCoordStates(p.CoordID) == 0) { if (p.StateID == 1) { b.AppendFormat(" {0}", CoordName); } else { b.AppendFormat(" ~{0}", CoordName); } } else { string StateName = gren.GetCoordStateName(p.CoordID, p.StateID); b.AppendFormat(" {0}:{1}", CoordName, StateName); } } b.Append(" }"); } return(b.ToString()); }
private void ProcessTree(SolarixGrammarEngineNET.SyntaxTreeNode node) { string word1 = node.GetWord().ToUpper(); int e1 = node.GetEntryID(); int c1 = gren.GetEntryClass(e1); if ( c1 == SolarixGrammarEngineNET.GrammarEngineAPI.VERB_ru || c1 == SolarixGrammarEngineNET.GrammarEngineAPI.INFINITIVE_ru || c1 == SolarixGrammarEngineNET.GrammarEngineAPI.IMPERSONAL_VERB_ru ) { string ename1 = gren.GetEntryName(e1); System.Text.StringBuilder b = new System.Text.StringBuilder(); b.AppendFormat("{0}", ename1); if (node.leafs.Count > 0) { b.Append("("); for (int ileaf = 0; ileaf < node.leafs.Count; ++ileaf) { SolarixGrammarEngineNET.SyntaxTreeNode leaf = node.leafs[ileaf]; string s = GetNodeNonterminal(leaf); if (!string.IsNullOrEmpty(s)) { b.AppendFormat(" {0}", s); } } b.Append(" )"); } string str = b.ToString(); int f = 0; if (verb_pattern.TryGetValue(str, out f)) { verb_pattern[str] = f + 1; } else { verb_pattern.Add(str, 1); } } for (int ileaf = 0; ileaf < node.leafs.Count; ++ileaf) { SolarixGrammarEngineNET.SyntaxTreeNode leaf = node.leafs[ileaf]; int e2 = leaf.GetEntryID(); int c2 = gren.GetEntryClass(e2); if (c2 != SolarixGrammarEngineNET.GrammarEngineAPI.PUNCTUATION_class) { string word2 = leaf.GetWord().ToUpper(); string w2 = string.Format("{0}+{1}", word1, word2); int f = 0; if (biword.TryGetValue(w2, out f)) { biword[w2] = f + 1; } else { biword.Add(w2, 1); } } ProcessTree(leaf); } return; }
public bool ProcessSample(string line) { n_learn_samples++; // чтобы получить все возможные теги, надо для каждого слова получить все возможные распознавания. using (SolarixGrammarEngineNET.AnalysisResults projs = gren.AnalyzeMorphology(line, LanguageID, SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags.SOL_GREN_TOKENIZE_ONLY)) { int last_word_index = projs.Count - 1; for (int iword = 0; iword < projs.Count; ++iword) { for (int iproj = 0; iproj < projs[iword].VersionCount(); ++iproj) { string lemma = string.Empty; int ekey = projs[iword].GetVersionEntryID(iproj); string ename = gren.GetEntryName(ekey); if (IsUnknownLexem(ename)) { lemma = projs[iword].GetWord().ToLower(); } else { lemma = ename.ToLower(); } string sfx = GetTokenSuffix(iword, last_word_index, lemma); int id_lemma = MatchSuffix(sfx, true); } } } // Морфологический разбор using (SolarixGrammarEngineNET.AnalysisResults tokens = gren.AnalyzeMorphology(line, LanguageID, SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags.SOL_GREN_COMPLETE_ONLY)) { List <string> sfx = new List <string>(); List <int> sfx_index = new List <int>(); List <string> sfx_lemma = new List <string>(); List <int> sfx_lemma_index = new List <int>(); int last_word_index = tokens.Count - 1; for (int iword = 0; iword < tokens.Count; ++iword) { string word = tokens[iword].GetWord().ToLower(); string suffix = GetTokenSuffix(iword, last_word_index, tokens[iword]); sfx.Add(suffix); int index = MatchSuffix(suffix, true); sfx_index.Add(index); int ekey = tokens[iword].GetEntryID(); string ename = gren.GetEntryName(ekey); string lemma; if (IsUnknownLexem(ename)) { lemma = word; } else { lemma = ename.ToLower(); } string lemma_suffix = GetTokenSuffix(iword, last_word_index, lemma); sfx_lemma.Add(lemma_suffix); sfx_lemma_index.Add(MatchSuffix(lemma_suffix, true)); } for (int iword = 1; iword < tokens.Count - 1; ++iword) { string tag1 = LemmaLabel(-1, sfx_lemma_index[iword - 1]); // для Витерби // features как контекст +/-1 слово вокруг текущего string tag2 = TagLabel(-1, sfx_index[iword - 1]); string tag3 = TagLabel(0, sfx_index[iword]); string tag4 = TagLabel(1, sfx_index[iword + 1]); string res = ResultLabel(sfx_lemma_index[iword]); WriteTrain(tag1, tag2, tag3, tag4, res); } } return(true); }
public void Store() { using (System.IO.StreamWriter wr = new System.IO.StreamWriter("edge_lens.txt")) { foreach (var x in edge_len2count.OrderBy(z => z.Key)) { wr.WriteLine("{0};{1}", x.Key, x.Value); } } int n_assoc2 = 0; using (System.IO.StreamWriter wr = new System.IO.StreamWriter("distance2.sql")) { wr.WriteLine("DELETE FROM assoc2_corpus_stat;"); foreach (var w2 in distance_matrix.OrderByDescending(z => z.Value.id_entry1).ThenByDescending(z => z.Value.N)) { string word1 = gren.GetEntryName(w2.Key.id_entry1); string word2 = gren.GetEntryName(w2.Key.id_entry2); double M = ((double)w2.Key.sum_distance) / ((double)w2.Key.N); double D = ((double)w2.Key.sum_distance2) / ((double)w2.Key.N) - M * M; wr.WriteLine("INSERT INTO assoc2_corpus_stat( id_entry1, id_entry2, word1, word2, M, D, N ) VALUES ( {5}, {6}, '{0}', '{1}', {2}, {3}, {4} );", EscapeSQL(word1), EscapeSQL(word2), M.ToString("0.####").Replace(",", "."), System.Math.Sqrt(D).ToString("0.####").Replace(",", "."), w2.Key.N, w2.Key.id_entry1, w2.Key.id_entry2); n_assoc2++; if ((n_assoc2 % 100) == 0) { wr.WriteLine("GO"); } } } System.Console.WriteLine("Total number of biword associations: {0}", n_assoc2); using (System.IO.StreamWriter wr = new System.IO.StreamWriter("stat.sql")) { wr.WriteLine("DELETE FROM wordform_corpus_stat;"); wr.WriteLine("DELETE FROM wordentry_corpus_stat;"); foreach (var x in wordform_stat) { wr.WriteLine("INSERT INTO wordform_corpus_stat( id_entry, word, freq ) VALUES ( {0}, '{1}', {2} );", x.Key.id_entry, x.Key.wordform.Replace("'", "''"), x.Value); } foreach (var x in wordentry_stat) { wr.WriteLine("INSERT INTO wordentry_corpus_stat( id_entry, freq ) VALUES ( {0}, {1} );", x.Key, x.Value); } } using (System.IO.StreamWriter wr = new System.IO.StreamWriter("wordentry.stat.txt")) { foreach (var x in wordentry_stat.OrderByDescending(z => z.Value)) { wr.WriteLine("{0};{1};{2}", x.Key, gren.GetEntryName(x.Key), x.Value); } } using (System.IO.StreamWriter wr = new System.IO.StreamWriter("wordentry.stat2.txt")) { foreach (var x in wordentry_stat.OrderByDescending(z => z.Value)) { wr.WriteLine("[{0}]", gren.GetEntryName(x.Key)); } } using (System.IO.StreamWriter wr = new System.IO.StreamWriter("lemma_sematags.txt")) { foreach (var x in wordentry_stat.Where(z => z.Value >= MIN_SEMATAG_FREQ).OrderByDescending(z => z.Value)) { string lemma = gren.GetEntryName(x.Key); if (!char.IsPunctuation(lemma[0]) && lemma != "???" && lemma != "unknownentry" && lemma != "number_") { wr.WriteLine("{0}\t{1}", lemma, x.Key); } } } using (System.IO.StreamWriter wr = new System.IO.StreamWriter("dublicated_samples.txt")) { foreach (var k in sample2count.Where(z => z.Value > 1)) { wr.WriteLine("{0}", k.Key); } } return; }
static void Main(string[] args) { string dictionary_path = @"e:\MVoice\lem\bin-windows\dictionary.xml"; // путь к словарной базе string samples_path = @"E:\MVoice\lem\Слова\rus\SENT5.plain.txt"; // путь к файлу со списком предложений (одно предложение на одной строке) int NSAMPLE = 20000; // сколько предложений максимум обработать int START_INDEX = 0; // порядковый номер первого обрабатываемого предложений в исходном файле int MAXARGS = 20; // beam size bool append_result = false; // если леммы надо добавлять к существующему файлу, а не формировать файл с нуля string save_path = null; // путь к файлу, куда будут записаны леммы int source_format = 0; // 0 - token per line, 1 - sentence per line bool output_lemmas = true; // в результат записывать леммы с приведением к нижнему регистру bool output_suffix = false; bool output_words = false; // в результат записывать исходные слова с приведением к нижнему регистру int suffix_len = 0; int min_sentence_length = 0; // фильтр по минимальной длине предложений int max_sentence_length = int.MaxValue; // фильтр по максимальной длине предложений bool reject_unknown = false; // отбрасывать предложения с несловарными токенами bool emit_eol = false; // добавлять в выходной файл токены <EOL> для маркировки конца предложения int eol_count = 0; // кол-во вставляемых <EOL>, гарантированно перекрывающее размер окна в word2vec List <System.Text.RegularExpressions.Regex> rx_stop = new List <System.Text.RegularExpressions.Regex>(); for (int i = 0; i < args.Length; ++i) { if (args[i] == "-dict") { ++i; dictionary_path = args[i]; } else if (args[i] == "-samples") { ++i; samples_path = args[i]; } else if (args[i] == "-source_format") { ++i; source_format = int.Parse(args[i]); } else if (args[i] == "-append") { // Добавлять в конец существующего файла append_result = true; } else if (args[i] == "-emit_eol") { ++i; eol_count = int.Parse(args[i]); if (eol_count > 0) { emit_eol = true; } } else if (args[i] == "-result") { // Способ обработки токенов: // lemma => лемматизация // suffix => усечение до псевдосуффикса длиной -suffix_len // raw => исходные слова ++i; output_lemmas = false; output_suffix = false; output_words = false; if (args[i] == "suffix") { output_suffix = true; } else if (args[i] == "lemma") { output_lemmas = true; } else if (args[i] == "raw") { output_words = true; } else { throw new ApplicationException(string.Format("Unknown result format: {0}", args[i])); } } else if (args[i] == "-save") { // Путь к файлу, куда будут записываться результаты обработки ++i; save_path = args[i]; } else if (args[i] == "-nsample") { // кол-во обрабатываемых предложений, начиная с -start_index ++i; NSAMPLE = int.Parse(args[i]); } else if (args[i] == "-min_sent_len") { // Обрабатывать только предложения, содержащие не менее NNN токенов ++i; min_sentence_length = int.Parse(args[i]); } else if (args[i] == "-max_sent_len") { // Обрабатывать только предложения, содержащие не более NNN токенов ++i; max_sentence_length = int.Parse(args[i]); } else if (args[i] == "-suffix_len") { ++i; suffix_len = int.Parse(args[i]); } else if (args[i] == "-start_index") { // Начинать обработку с предложения с указанным индексом ++i; START_INDEX = int.Parse(args[i]); } else if (args[i] == "-reject_unknown") { reject_unknown = true; } else if (args[i] == "-rx_stop") { ++i; using (System.IO.StreamReader rdr = new System.IO.StreamReader(args[i])) { while (!rdr.EndOfStream) { string line = rdr.ReadLine(); if (line == null) { break; } line = line.Trim(); if (line.Length > 0) { rx_stop.Add(new System.Text.RegularExpressions.Regex(line)); } } } } else { throw new ApplicationException(string.Format("Unknown option {0}", args[i])); } } Samples sources = null; if (source_format == 1) { sources = new Samples1(samples_path); } else { sources = new Samples2(samples_path); } sources.SetMinSentenceLen(min_sentence_length); sources.SetMaxSentenceLen(max_sentence_length); if (output_suffix || output_words) { sources.SetTokenDelimiter('|'); } SolarixGrammarEngineNET.GrammarEngine2 gren = null; gren = new SolarixGrammarEngineNET.GrammarEngine2(); if (output_lemmas) { gren.Load(dictionary_path, true); } int counter = -1; int n_processed = 1; int MAX_COUNT = NSAMPLE; int LanguageID = SolarixGrammarEngineNET.GrammarEngineAPI.RUSSIAN_LANGUAGE; int Constraints = 120000 | (MAXARGS << 22); // 2 мин и 20 альтернатив SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags Flags = SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags.SOL_GREN_MODEL_ONLY | SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags.SOL_GREN_MODEL; // сколько всего предложений Console.WriteLine("Counting lines in source file {0}...", samples_path); int n_total_lines = sources.TotalCount(); Console.WriteLine("Total number of lines={0}", n_total_lines.ToString("N0", new System.Globalization.CultureInfo("en-US"))); System.IO.StreamWriter wrt = new System.IO.StreamWriter(save_path, append_result, new UTF8Encoding(false)); sources.Start(); while (true) { string sample = sources.Next(); if (sample == null) { break; } sample = sample.Trim(); counter++; if (counter < START_INDEX) { continue; } if (n_processed >= MAX_COUNT) { break; } bool contains_insane_chars = false; foreach (char c in sample) { if (c < 32) { contains_insane_chars = true; break; } } if (contains_insane_chars) { System.Text.StringBuilder b = new StringBuilder(sample.Length); foreach (char c in sample) { if (c >= 32) { b.Append(c); } } sample = b.ToString(); } n_processed++; if (sample.Length == 0) { continue; } if (rx_stop.Count > 0) { bool reject_this_sample = false; foreach (var rx in rx_stop) { if (rx.Match(sample).Success) { reject_this_sample = true; break; } } if (reject_this_sample) { continue; } } if (output_lemmas) { using (SolarixGrammarEngineNET.AnalysisResults tokens = gren.AnalyzeMorphology(sample, LanguageID, Flags, Constraints)) { for (int i = 1; i < tokens.Count - 1; ++i) { if (char.IsPunctuation(tokens[i].GetWord()[0])) { continue; } int id_entry = tokens[i].GetEntryID(); string lemma = gren.GetEntryName(id_entry); if (lemma == "???" || lemma.Equals("UNKNOWNENTRY", StringComparison.InvariantCultureIgnoreCase) || lemma.Equals("number_", StringComparison.InvariantCultureIgnoreCase)) { lemma = tokens[i].GetWord(); } lemma = lemma.ToLower(); wrt.Write(" {0}", lemma); } } } else if (output_words) { string[] tokens = sample.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); foreach (string token in tokens) { if (token.Length >= 1 && char.IsPunctuation(token[0])) { continue; } string norma = token.ToLower(); wrt.Write(" {0}", norma); } } else if (output_suffix) { string[] tokens = sample.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); foreach (string token in tokens) { if (token.Length == 0 || (token.Length == 1 && char.IsPunctuation(token[0]))) { continue; } string suffix = token; int num; if (int.TryParse(token, out num)) { suffix = token.Substring(token.Length - 1); } else if (token.Length > suffix_len + 1) { suffix = "~" + token.Substring(token.Length - suffix_len); } wrt.Write(" {0}", suffix.ToLower()); } } if (emit_eol) { for (int k = 0; k < eol_count; ++k) { wrt.Write(" <EOL>"); } } Console.WriteLine("[{1}/{2}] {0}", sample, counter, n_total_lines); wrt.Flush(); } wrt.Close(); return; }
public void Store() { using (System.IO.StreamWriter wr = new System.IO.StreamWriter("kb_verb_prepos.txt")) { string prev_word1 = string.Empty; foreach (var x in verb_prepos.OrderByDescending(z => z.Key.id_entry1).ThenByDescending(z => z.Value)) { string word1 = gren.GetEntryName(x.Key.id_entry1); string word2 = gren.GetEntryName(x.Key.id_entry2); if (word1 != "???") { if (prev_word1 != word1) { wr.WriteLine("\n\n"); } prev_word1 = word1; wr.WriteLine("{0} {1} = {2}", word1, word2, x.Value); } } } using (System.IO.StreamWriter wr = new System.IO.StreamWriter("kb_prepos_noun.txt")) { string prev_word1 = string.Empty; foreach (var x in prepos_noun.OrderByDescending(z => z.Key.id_entry1).ThenByDescending(z => z.Value)) { string word1 = gren.GetEntryName(x.Key.id_entry1); string word2 = gren.GetEntryName(x.Key.id_entry2); if (word2 != "???") { if (prev_word1 != word1) { wr.WriteLine("\n\n"); } prev_word1 = word1; wr.WriteLine("{0} {1} = {2}", word1, word2, x.Value); } } } using (System.IO.StreamWriter wr = new System.IO.StreamWriter("kb_adj_noun.txt")) { string prev_word1 = string.Empty; foreach (var x in adj_noun.OrderByDescending(z => z.Key.id_entry1).ThenByDescending(z => z.Value)) { string word1 = gren.GetEntryName(x.Key.id_entry1); string word2 = gren.GetEntryName(x.Key.id_entry2); if (word1 != "???" && word2 != "???") { if (prev_word1 != word1) { wr.WriteLine("\n\n"); } prev_word1 = word1; wr.WriteLine("{0} {1} = {2}", word1, word2, x.Value); } } } return; }
public bool ProcessSample(string line) { n_learn_samples++; if (tokens_file == null) { tokens_file = new System.IO.StreamWriter(tokens_file_path); } // чтобы получить все возможные теги, надо для каждого слова получить все возможные распознавания. using (SolarixGrammarEngineNET.AnalysisResults projs = gren.AnalyzeMorphology(line, LanguageID, SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags.SOL_GREN_TOKENIZE_ONLY)) { int last_word_index = projs.Count - 1; for (int iword = 0; iword < projs.Count; ++iword) { for (int iproj = 0; iproj < projs[iword].VersionCount(); ++iproj) { string lemma = string.Empty; int ekey = projs[iword].GetVersionEntryID(iproj); string ename = gren.GetEntryName(ekey); if (IsUnknownLexem(ename)) { lemma = projs[iword].GetWord().ToLower(); } else { lemma = ename.ToLower(); } string sfx1 = GetTokenSuffix(iword, last_word_index, lemma); int id1 = MatchSuffix(sfx1, true); string sfx2 = GetTokenLemmaSuffix(iword, last_word_index, lemma); int id2 = MatchSuffix(sfx2, true); } } } // Морфологический разбор using (SolarixGrammarEngineNET.AnalysisResults tokens = gren.AnalyzeMorphology(line, LanguageID, SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags.SOL_GREN_COMPLETE_ONLY)) { test_samples.Add(line); test_sample_token_counts.Add(tokens.Count); List <string> sfx = new List <string>(); List <int> sfx_index = new List <int>(); List <string> sfx_lemma = new List <string>(); List <int> sfx_lemma_index = new List <int>(); int last_word_index = tokens.Count - 1; for (int iword = 0; iword < tokens.Count; ++iword) { string word = tokens[iword].GetWord().ToLower(); if (iword > 0 && iword < tokens.Count - 1) { tokens_file.Write("{0}", word); // все допустимые варианты лемматизации int nlemma = 0; for (int j = 0; j < tokens[iword].VersionCount(); ++j) { int id_entry = tokens[iword].GetVersionEntryID(j); string ename2 = gren.GetEntryName(id_entry); if (IsUnknownLexem(ename2)) // не будем учитывать ошибки лемматизации для не-словарных лексем. { continue; } tokens_file.Write("\t{0}", ename2); nlemma++; } if (nlemma == 0) { tokens_file.Write("\t{0}", word); } tokens_file.WriteLine(""); } string suffix = GetTokenSuffix(iword, last_word_index, tokens[iword]); sfx.Add(suffix); int index = MatchSuffix(suffix, true); sfx_index.Add(index); int ekey = tokens[iword].GetEntryID(); string ename = gren.GetEntryName(ekey); string lemma; if (IsUnknownLexem(ename)) { lemma = word; } else { lemma = ename.ToLower(); } string lemma_suffix = GetTokenLemmaSuffix(iword, last_word_index, lemma); sfx_lemma.Add(lemma_suffix); sfx_lemma_index.Add(MatchSuffix(lemma_suffix, true)); } tokens_file.WriteLine(""); for (int iword = 1; iword < tokens.Count - 1; ++iword) { string res = ResultLabel(sfx_lemma_index[iword]); //string tag0 = LemmaLabel( -1, sfx_lemma_index[iword - 1] ); // для Витерби в MEMM if (iword > 1 && iword < tokens.Count - 2) { string tag1 = TagLabel(-2, sfx_index[iword - 2]); string tag2 = TagLabel(-1, sfx_index[iword - 1]); string tag3 = TagLabel(0, sfx_index[iword]); string tag4 = TagLabel(1, sfx_index[iword + 1]); string tag5 = TagLabel(2, sfx_index[iword + 2]); WriteTrain(tag1, tag2, tag3, tag4, tag5, res); WriteTest(tag1, tag2, tag3, tag4, tag5, res); } else { string tag2 = TagLabel(-1, sfx_index[iword - 1]); string tag3 = TagLabel(0, sfx_index[iword]); string tag4 = TagLabel(1, sfx_index[iword + 1]); WriteTrain(tag2, tag3, tag4, res); WriteTest(tag2, tag3, tag4, res); } } WriteTestEOS(); } return(true); }
static void Execute( string[] args ) { string dictionary_path = @"e:\MVoice\lem\bin-windows\dictionary.xml"; // путь к словарной базе string samples_path = @"E:\MVoice\lem\Слова\rus\SENT5.plain.txt"; // путь к файлу со списком предложений (одно предложение на одной строке) int NSAMPLE = 20000; // сколько предложений максимум обработать int START_INDEX = 0; // порядковый номер первого обрабатываемого предложений в исходном файле int MAXARGS = 20; // beam size bool append_result = false; // если леммы надо добавлять к существующему файлу, а не формировать файл с нуля string save_path = null; // путь к файлу, куда будут записаны леммы int source_format = 0; // 0 - token per line, 1 - sentence per line bool output_lemmas = true; // в результат записывать леммы с приведением к нижнему регистру bool output_suffix = false; bool output_words = false; // в результат записывать исходные слова с приведением к нижнему регистру int suffix_len = 0; int min_sentence_length = 0; // фильтр по минимальной длине предложений int max_sentence_length = int.MaxValue; // фильтр по максимальной длине предложений bool reject_unknown = false; // отбрасывать предложения с несловарными токенами bool emit_eol = false; // добавлять в выходной файл токены <EOL> для маркировки конца предложения int eol_count = 0; // кол-во вставляемых <EOL>, гарантированно перекрывающее размер окна в word2vec List<System.Text.RegularExpressions.Regex> rx_stop = new List<System.Text.RegularExpressions.Regex>(); for( int i = 0; i < args.Length; ++i ) { if( args[i] == "-dict" ) { ++i; dictionary_path = args[i]; } else if( args[i] == "-samples" ) { ++i; samples_path = args[i]; } else if( args[i] == "-source_format" ) { ++i; source_format = int.Parse( args[i] ); } else if( args[i] == "-append" ) { // Добавлять в конец существующего файла append_result = true; } else if( args[i] == "-emit_eol" ) { ++i; eol_count = int.Parse( args[i] ); if( eol_count > 0 ) emit_eol = true; } else if( args[i] == "-result" ) { // Способ обработки токенов: // lemma => лемматизация // suffix => усечение до псевдосуффикса длиной -suffix_len // raw => исходные слова ++i; output_lemmas = false; output_suffix = false; output_words = false; if( args[i] == "suffix" ) { output_suffix = true; } else if( args[i] == "lemma" ) { output_lemmas = true; } else if( args[i] == "raw" ) { output_words = true; } else throw new ApplicationException( string.Format( "Unknown result format: {0}", args[i] ) ); } else if( args[i] == "-save" ) { // Путь к файлу, куда будут записываться результаты обработки ++i; save_path = args[i]; } else if( args[i] == "-nsample" ) { // кол-во обрабатываемых предложений, начиная с -start_index ++i; NSAMPLE = int.Parse( args[i] ); } else if( args[i] == "-min_sent_len" ) { // Обрабатывать только предложения, содержащие не менее NNN токенов ++i; min_sentence_length = int.Parse( args[i] ); } else if( args[i] == "-max_sent_len" ) { // Обрабатывать только предложения, содержащие не более NNN токенов ++i; max_sentence_length = int.Parse( args[i] ); } else if( args[i] == "-suffix_len" ) { ++i; suffix_len = int.Parse( args[i] ); } else if( args[i] == "-start_index" ) { // Начинать обработку с предложения с указанным индексом ++i; START_INDEX = int.Parse( args[i] ); } else if( args[i] == "-reject_unknown" ) { reject_unknown = true; } else if( args[i] == "-rx_stop" ) { ++i; using( System.IO.StreamReader rdr = new System.IO.StreamReader( args[i] ) ) { while( !rdr.EndOfStream ) { string line = rdr.ReadLine(); if( line == null ) break; line = line.Trim(); if( line.Length > 0 ) { rx_stop.Add( new System.Text.RegularExpressions.Regex( line ) ); } } } } else throw new ApplicationException( string.Format( "Unknown option {0}", args[i] ) ); } Samples sources = null; if( source_format == 1 ) sources = new Samples1( samples_path ); else sources = new Samples2( samples_path ); sources.SetMinSentenceLen( min_sentence_length ); sources.SetMaxSentenceLen( max_sentence_length ); if( output_suffix || output_words ) sources.SetTokenDelimiter( '|' ); SolarixGrammarEngineNET.GrammarEngine2 gren = null; gren = new SolarixGrammarEngineNET.GrammarEngine2(); if( output_lemmas ) { gren.Load( dictionary_path, true ); } int counter = -1; int n_processed = 1; int MAX_COUNT = NSAMPLE; int LanguageID = SolarixGrammarEngineNET.GrammarEngineAPI.RUSSIAN_LANGUAGE; int Constraints = 120000 | ( MAXARGS << 22 ); // 2 мин и 20 альтернатив SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags Flags = SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags.SOL_GREN_MODEL_ONLY | SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags.SOL_GREN_MODEL; // сколько всего предложений Console.WriteLine( "Counting lines in source file {0}...", samples_path ); int n_total_lines = sources.TotalCount(); Console.WriteLine( "Total number of lines={0}", n_total_lines.ToString( "N0", new System.Globalization.CultureInfo( "en-US" ) ) ); System.IO.StreamWriter wrt = new System.IO.StreamWriter( save_path, append_result, new UTF8Encoding( false ) ); sources.Start(); while( true ) { string sample = sources.Next(); if( sample == null ) break; sample = sample.Trim(); counter++; if( counter < START_INDEX ) continue; if( n_processed >= MAX_COUNT ) break; bool contains_insane_chars = false; foreach( char c in sample ) if( c < 32 ) { contains_insane_chars = true; break; } if( contains_insane_chars ) { System.Text.StringBuilder b = new StringBuilder( sample.Length ); foreach( char c in sample ) if( c >= 32 ) b.Append( c ); sample = b.ToString(); } n_processed++; if( sample.Length == 0 ) continue; if( rx_stop.Count > 0 ) { bool reject_this_sample = false; foreach( var rx in rx_stop ) if( rx.Match( sample ).Success ) { reject_this_sample = true; break; } if( reject_this_sample ) continue; } if( output_lemmas ) { using( SolarixGrammarEngineNET.AnalysisResults tokens = gren.AnalyzeMorphology( sample, LanguageID, Flags, Constraints ) ) { for( int i = 1; i < tokens.Count - 1; ++i ) { if( char.IsPunctuation( tokens[i].GetWord()[0] ) ) continue; int id_entry = tokens[i].GetEntryID(); string lemma = gren.GetEntryName( id_entry ); if( lemma == "???" || lemma.Equals( "UNKNOWNENTRY", StringComparison.InvariantCultureIgnoreCase ) || lemma.Equals( "number_", StringComparison.InvariantCultureIgnoreCase ) ) lemma = tokens[i].GetWord(); lemma = lemma.ToLower(); wrt.Write( " {0}", lemma ); } } } else if( output_words ) { string[] tokens = sample.Split( "|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries ); foreach( string token in tokens ) { if( token.Length >= 1 && char.IsPunctuation( token[0] ) ) continue; string norma = token.ToLower(); wrt.Write( " {0}", norma ); } } else if( output_suffix ) { string[] tokens = sample.Split( "|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries ); foreach( string token in tokens ) { if( token.Length == 0 || ( token.Length == 1 && char.IsPunctuation( token[0] ) ) ) continue; string suffix = token; int num; if( int.TryParse( token, out num ) ) suffix = token.Substring( token.Length - 1 ); else if( token.Length > suffix_len + 1 ) suffix = "~" + token.Substring( token.Length - suffix_len ); wrt.Write( " {0}", suffix.ToLower() ); } } if( emit_eol ) for( int k = 0; k < eol_count; ++k ) wrt.Write( " <EOL>" ); Console.WriteLine( "[{1}/{2}] {0}", sample, counter, n_total_lines ); wrt.Flush(); } wrt.Close(); return; }
public FootPrintToken(SolarixGrammarEngineNET.GrammarEngine2 gren, SolarixGrammarEngineNET.SyntaxTreeNode root) { Contract.Ensures(!string.IsNullOrEmpty(this.word)); Contract.Ensures(this.node != null); Contract.Ensures(this.tags != null); this.word = root.GetWord(); this.tags = new List <string>(); this.node = root; this.tags.Add(root.GetWord().ToLower()); if (root.GetWord().Equals("не", StringComparison.OrdinalIgnoreCase)) { this.tags.Add("neg"); } int part_of_speech = gren.GetEntryClass(root.GetEntryID()); switch (part_of_speech) { case SolarixGrammarEngineNET.GrammarEngineAPI.NUM_WORD_CLASS: this.tags.Add("num"); break; // числительное цифрами case SolarixGrammarEngineNET.GrammarEngineAPI.NUMBER_CLASS_ru: this.tags.Add("num"); break; // числительное словом case SolarixGrammarEngineNET.GrammarEngineAPI.CONJ_ru: this.tags.Add("conj"); break; // союз case SolarixGrammarEngineNET.GrammarEngineAPI.PRONOUN_ru: this.tags.Add("pr"); break; // местоимение Я case SolarixGrammarEngineNET.GrammarEngineAPI.NOUN_ru: this.tags.Add("n"); break; case SolarixGrammarEngineNET.GrammarEngineAPI.ADJ_ru: this.tags.Add("adj"); break; case SolarixGrammarEngineNET.GrammarEngineAPI.VERB_ru: this.tags.Add("v"); break; case SolarixGrammarEngineNET.GrammarEngineAPI.INFINITIVE_ru: this.tags.Add("v"); this.tags.Add("inf"); break; case SolarixGrammarEngineNET.GrammarEngineAPI.GERUND_2_ru: this.tags.AddRange("adv adv_v".Split(' ')); break; case SolarixGrammarEngineNET.GrammarEngineAPI.ADVERB_ru: { this.tags.Add("adv"); if (StringExtender.InCI(word, "очень крайне наиболее наименее чрезвычайно почти".Split())) // модификаторы наречий и прилагательных { this.tags.Add("a_modif"); } string adv_cat = AdverbCategory.GetQuestionWordForAdverb(word); if (!string.IsNullOrEmpty(adv_cat)) { this.tags.Add("adv_" + adv_cat); } break; } case SolarixGrammarEngineNET.GrammarEngineAPI.PREPOS_ru: this.tags.Add("p"); break; case SolarixGrammarEngineNET.GrammarEngineAPI.PRONOUN2_ru: this.tags.Add("pr"); break; default: this.tags.Add("x"); break; } foreach (var p in root.GetPairs()) { if (p.CoordID == SolarixGrammarEngineNET.GrammarEngineAPI.CASE_ru) { switch (p.StateID) { case SolarixGrammarEngineNET.GrammarEngineAPI.NOMINATIVE_CASE_ru: this.tags.Add("nom"); break; case SolarixGrammarEngineNET.GrammarEngineAPI.GENITIVE_CASE_ru: this.tags.Add("gen"); break; case SolarixGrammarEngineNET.GrammarEngineAPI.ACCUSATIVE_CASE_ru: this.tags.Add("acc"); break; case SolarixGrammarEngineNET.GrammarEngineAPI.DATIVE_CASE_ru: this.tags.Add("dat"); break; case SolarixGrammarEngineNET.GrammarEngineAPI.PREPOSITIVE_CASE_ru: this.tags.Add("prep"); break; case SolarixGrammarEngineNET.GrammarEngineAPI.PARTITIVE_CASE_ru: this.tags.Add("part"); break; case SolarixGrammarEngineNET.GrammarEngineAPI.LOCATIVE_CASE_ru: this.tags.Add("loc"); break; case SolarixGrammarEngineNET.GrammarEngineAPI.INSTRUMENTAL_CASE_ru: this.tags.Add("instr"); break; } } if (p.CoordID == SolarixGrammarEngineNET.GrammarEngineAPI.NUMBER_ru) { switch (p.StateID) { case SolarixGrammarEngineNET.GrammarEngineAPI.SINGULAR_NUMBER_ru: this.tags.Add("sing"); break; case SolarixGrammarEngineNET.GrammarEngineAPI.PLURAL_NUMBER_ru: this.tags.Add("pl"); break; } } if (p.CoordID == SolarixGrammarEngineNET.GrammarEngineAPI.TENSE_ru) { switch (p.StateID) { case SolarixGrammarEngineNET.GrammarEngineAPI.PAST_ru: this.tags.Add("past"); break; case SolarixGrammarEngineNET.GrammarEngineAPI.PRESENT_ru: this.tags.Add("pres"); break; case SolarixGrammarEngineNET.GrammarEngineAPI.FUTURE_ru: this.tags.Add("future"); break; } } if (p.CoordID == SolarixGrammarEngineNET.GrammarEngineAPI.FORM_ru) { switch (p.StateID) { case SolarixGrammarEngineNET.GrammarEngineAPI.ANIMATIVE_FORM_ru: this.tags.Add("anim"); break; case SolarixGrammarEngineNET.GrammarEngineAPI.INANIMATIVE_FORM_ru: this.tags.Add("inanim"); break; } } if (p.CoordID == SolarixGrammarEngineNET.GrammarEngineAPI.GENDER_ru) { switch (p.StateID) { case SolarixGrammarEngineNET.GrammarEngineAPI.MASCULINE_GENDER_ru: this.tags.Add("masc"); break; case SolarixGrammarEngineNET.GrammarEngineAPI.FEMININE_GENDER_ru: this.tags.Add("fem"); break; case SolarixGrammarEngineNET.GrammarEngineAPI.NEUTRAL_GENDER_ru: this.tags.Add("neut"); break; } } if (p.CoordID == SolarixGrammarEngineNET.GrammarEngineAPI.PERSON_ru) { switch (p.StateID) { case SolarixGrammarEngineNET.GrammarEngineAPI.PERSON_1_ru: this.tags.Add("1"); break; case SolarixGrammarEngineNET.GrammarEngineAPI.PERSON_2_ru: this.tags.Add("2"); break; case SolarixGrammarEngineNET.GrammarEngineAPI.PERSON_3_ru: this.tags.Add("3"); break; } } if (p.CoordID == SolarixGrammarEngineNET.GrammarEngineAPI.VERB_FORM_ru) { switch (p.StateID) { case SolarixGrammarEngineNET.GrammarEngineAPI.VB_INF_ru: this.tags.Add("vf1"); break; case SolarixGrammarEngineNET.GrammarEngineAPI.VB_ORDER_ru: this.tags.Add("imper"); break; } } if (p.CoordID == SolarixGrammarEngineNET.GrammarEngineAPI.MODAL_ru) { switch (p.StateID) { case 1: this.tags.Add("mod"); break; } } } // Пометим связочные глаголы string lemma = gren.GetEntryName(root.GetEntryID()); if (copula_verbs.Contains(lemma)) { this.tags.Add("copula"); } }