public AnalysisResults AnalyzeMorphology(string phrase, int id_language, SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags flags, int constraints) { IntPtr hPack = GrammarEngine.sol_MorphologyAnalysis(_hEngine, phrase, flags, 0, constraints, id_language); AnalysisResults res = new AnalysisResults(this, hPack); return(res); }
public AnalysisResults AnalyzeSyntax(string phrase, int id_language, SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags morph_flags, SolarixGrammarEngineNET.GrammarEngine.SyntaxFlags syntax_flags, int constraints) { IntPtr hPack = GrammarEngine.sol_SyntaxAnalysis(_hEngine, phrase, morph_flags, syntax_flags, constraints, id_language); AnalysisResults res = new AnalysisResults(this, hPack); return(res); }
public string NormalizePhrase(string phrase) { try { Console.WriteLine("NormalizePhrase phrase={0}", phrase); LoadDict(); SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags morph_flags = SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags.SOL_GREN_COMPLETE_ONLY; SolarixGrammarEngineNET.GrammarEngine.SyntaxFlags syntax_flags = SolarixGrammarEngineNET.GrammarEngine.SyntaxFlags.DEFAULT; int MaxAlt = 30; int constraints = 600000 | (MaxAlt << 22); int id_language = SolarixGrammarEngineNET.GrammarEngineAPI.RUSSIAN_LANGUAGE; SolarixGrammarEngineNET.AnalysisResults linkages = gren.AnalyzeSyntax(phrase, id_language, morph_flags, syntax_flags, constraints); string normal_phrase = gren.NormalizePhrase(linkages); Console.WriteLine("normal_phrase={0}", normal_phrase); return(normal_phrase); } catch (Exception ex) { Console.WriteLine("Error: {0}", ex.Message); return(phrase); } }
static void ProcessSentence2(string phrase, SolarixGrammarEngineNET.GrammarEngine2 gren, int max_len) { nb_processed += 1; if (nb_skip != 0 && nb_processed < nb_skip) { return; } if (phrase.Length > 2) { bool used = false; string terminator = ""; if (IsSentenceTerminator(phrase.Last())) { terminator = new string(phrase.Last(), 1); // Удалим финальные символы типа . или ! int finalizers = 1; for (int i = phrase.Length - 2; i > 0; --i) { if (IsSentenceTerminator(phrase[i])) { finalizers++; } } phrase = phrase.Substring(0, phrase.Length - finalizers); } if (!processed_phrases.Contains(phrase)) { processed_phrases.Add(phrase); string phrase2 = Preprocess(phrase, gren); // Выполним оценку синтаксического качества предложения, чтобы отсеять мусор. int id_language = SolarixGrammarEngineNET.GrammarEngineAPI.RUSSIAN_LANGUAGE; SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags morph_flags = SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags.SOL_GREN_COMPLETE_ONLY | SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags.SOL_GREN_MODEL; SolarixGrammarEngineNET.GrammarEngine.SyntaxFlags syntax_flags = SolarixGrammarEngineNET.GrammarEngine.SyntaxFlags.DEFAULT; int MaxAlt = 40; int constraints = 600000 | (MaxAlt << 22); using (SolarixGrammarEngineNET.AnalysisResults linkages = gren.AnalyzeSyntax(phrase2, id_language, morph_flags, syntax_flags, constraints)) { if (linkages.Count == 3) { SolarixGrammarEngineNET.SyntaxTreeNode root = linkages[1]; List <SolarixGrammarEngineNET.SyntaxTreeNode> terms = GetTerms(root).OrderBy(z => z.GetWordPosition()).ToList(); int score = linkages.Score; bool good = false; if (score >= -4) { good = true; if (!syntax_checker.IsEmpty()) { FootPrint footprint = new FootPrint(gren, terms); // Проверим синтаксическую структуру фразы, чтобы отсеять разговорную некондицию. good = syntax_checker.IsGoodSyntax(footprint); } } if (good) { used = true; WriteSample(phrase + terminator); wrt_samples.Flush(); } else { SkippedSample(phrase); } } } } } Console.Write("{0} processed, {1} stored\r", nb_processed, nb_stored); 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; }
static int Main(string[] args) { List <string> input_files = new List <string>(); string output_file = null; string dictionary_xml = ""; string from_person = ""; string to_person = ""; #region Command_Line_Options for (int i = 0; i < args.Length; ++i) { if (args[i] == "-input_file") { input_files.Add(args[i + 1]); i++; } else if (args[i] == "-output_file") { output_file = args[i + 1]; i++; } else if (args[i] == "-dict") { dictionary_xml = args[i + 1]; i++; } else if (args[i] == "-from_person") { from_person = args[i + 1]; i++; } else if (args[i] == "-to_person") { to_person = args[i + 1]; i++; } else { throw new ApplicationException(string.Format("Unknown option {0}", args[i])); } } if (string.IsNullOrEmpty(from_person)) { Console.WriteLine("'from_person' parameter can not be empty"); return(1); } if (string.IsNullOrEmpty(to_person)) { Console.WriteLine("'to_person' parameter can not be empty"); return(1); } #endregion Command_Line_Options // Загружаем грамматический словарь Console.WriteLine("Loading dictionary {0}", dictionary_xml); SolarixGrammarEngineNET.GrammarEngine2 gren = new SolarixGrammarEngineNET.GrammarEngine2(); gren.Load(dictionary_xml, true); int id_language = SolarixGrammarEngineNET.GrammarEngineAPI.RUSSIAN_LANGUAGE; SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags morph_flags = SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags.SOL_GREN_COMPLETE_ONLY | SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags.SOL_GREN_MODEL; SolarixGrammarEngineNET.GrammarEngine.SyntaxFlags syntax_flags = SolarixGrammarEngineNET.GrammarEngine.SyntaxFlags.DEFAULT; int MaxAlt = 40; int constraints = 600000 | (MaxAlt << 22); using (System.IO.StreamWriter wrt = new System.IO.StreamWriter(output_file)) { int nb_samples = 0; foreach (string input_path in input_files) { Console.WriteLine("Processing {0}", input_path); using (System.IO.StreamReader rdr = new System.IO.StreamReader(input_path)) { while (!rdr.EndOfStream) { string line0 = rdr.ReadLine(); if (line0 == null) { break; } string line = line0.Trim(); string phrase2 = line; using (SolarixGrammarEngineNET.AnalysisResults linkages = gren.AnalyzeSyntax(phrase2, id_language, morph_flags, syntax_flags, constraints)) { if (linkages.Count == 3) { SolarixGrammarEngineNET.SyntaxTreeNode root = linkages[1]; List <SolarixGrammarEngineNET.SyntaxTreeNode> terms = GetTerms(root).OrderBy(z => z.GetWordPosition()).ToList(); if (from_person == "1s") { // Ищем подлежащее-местоимение "я" или проверяем, что глагол стоит в первом лице. bool is_good_sample = false; if (IsVerb_1s(gren, root)) { is_good_sample = true; } if (!is_good_sample) { for (int ichild = 0; ichild < root.leafs.Count; ++ichild) { if (root.GetLinkType(ichild) == SolarixGrammarEngineNET.GrammarEngineAPI.SUBJECT_link) { SolarixGrammarEngineNET.SyntaxTreeNode sbj = root.leafs[ichild]; if (IsPronoun_1s_nom(gren, sbj)) { is_good_sample = true; break; } } } } if (is_good_sample) { // Не должно быть местоимений в других падежах, чтобы не получалось: // Я тебя съем ! ты тебя съешь ! foreach (var term in terms) { if (GetPOS(gren, term) == SolarixGrammarEngineNET.GrammarEngineAPI.PRONOUN_ru && !IsPronoun_1s_nom(gren, term)) { is_good_sample = false; break; } } } if (is_good_sample) { List <string> src_words = new List <string>(); List <string> res_words = new List <string>(); foreach (var term in terms) { src_words.Add(term.GetWord()); if (IsPronoun_1s_nom(gren, term)) { string new_word = ChangePronounTo(gren, term, to_person); res_words.Add(new_word); } else if (IsVerb_1s(gren, term)) { string new_word = ChangeVerbTo(gren, term, to_person); res_words.Add(new_word); } else { res_words.Add(term.GetWord()); } } int nb_empty = res_words.Count(z => string.IsNullOrEmpty(z)); if (nb_empty == 0) { string src_str = string.Join(" ", src_words); string res_str = string.Join(" ", res_words); wrt.WriteLine("{0}\t{1}", src_str, res_str); wrt.Flush(); nb_samples++; if ((nb_samples % 10) == 0) { Console.Write("{0} samples stored\r", nb_samples); } } } } } } } } Console.WriteLine(); } } return(0); }