Load() public méthode

Connect to the dictionary database using the information in XML configuration file
public Load ( string DictionaryXmlPath, bool LazyLexicon ) : void
DictionaryXmlPath string Configuration file path (read about it: http://www.solarix.ru/for_developers/docs/russian-grammatical-dictionary-configuration.shtml)
LazyLexicon bool Word entries are loaded by demand if true
Résultat void
 public void LoadDictionary(string filepath)
 {
     gren = new SolarixGrammarEngineNET.GrammarEngine2();
     gren.Load(filepath, false);
     Init();
     return;
 }
    public static string tmp_folder    = "."; // папка для генерируемых временных файлов - логи, датасеты.

    static void Main(string[] args)
    {
        List <string> model_params = new List <string>();

        if (args.Length > 0)
        {
            for (int i = 0; i < args.Length; ++i)
            {
                if (args[i] == "-dict")
                {
                    // Путь к файлу с конфигурацией словарной базы.
                    dictionary_path = args[i + 1];
                    ++i;
                }
                else if (args[i] == "-tmp")
                {
                    // Временный каталог для сохранения датасетов.
                    tmp_folder = args[i + 1];
                    ++i;
                }
                else if (args[i] == "-corpus")
                {
                    // Путь к бинарному корпусу в формате Solarix.
                    string corpus_path = args[i + 1];
                    corpora.Add(new SolarixBinaryCorpusReader(corpus_path));
                    ++i;
                }
                else if (args[i] == "-conllu_corpus")
                {
                    // Путь к корпусу в формате ConllU
                    string corpus_path = args[i + 1];
                    corpora.Add(new ConlluCorpusReader(corpus_path));
                    ++i;
                }
                else if (args[i] == "-nsample")
                {
                    NSAMPLE = int.Parse(args[i + 1]);
                    ++i;
                }
                else if (args[i] == "-minsentlen")
                {
                    MIN_SENT_LEN = int.Parse(args[i + 1]);
                    ++i;
                }
                else if (args[i] == "-suffix_len")
                {
                    SUFFIX_LEN = int.Parse(args[i + 1]);
                    ++i;
                }
                else if (args[i] == "-context_span")
                {
                    // полуразмер контекста - число слов вправо или влево от текущего слова.
                    CONTEXT_SPAN = int.Parse(args[i + 1]);
                    ++i;
                }
                else if (args[i] == "-params")
                {
                    string[] px = args[i + 1].Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                    model_params.AddRange(px);
                    ++i;
                }
                else
                {
                    throw new ApplicationException(string.Format("Unknown option [{0}] in command line", args[i]));
                }
            }
        }

        Console.WriteLine("Loading dictionary from {0}...", dictionary_path);
        SolarixGrammarEngineNET.GrammarEngine2 gren;
        gren = new SolarixGrammarEngineNET.GrammarEngine2();
        gren.Load(dictionary_path, true);

        Build_LemmByPostags(gren, model_params);

        return;
    }
 public void LoadDictionary(string filepath)
 {
     gren = new SolarixGrammarEngineNET.GrammarEngine2();
     gren.Load(filepath, false); // для скорости парсинга загружаем лексикон в память
     return;
 }
    static void Main(string[] args)
    {
        string        result_folder    = @"f:\tmp";
        List <string> parsed_sentences = new List <string>();

        int    MAX_SAMPLE       = int.MaxValue;
        int    MAX_LEN          = int.MaxValue;
        string dictionary_path  = "";
        string syntax_templates = "";

        string[] filters = { "3" };

        #region Command_Line_Options
        for (int i = 0; i < args.Length; ++i)
        {
            if (args[i] == "-parsing")
            {
                parsed_sentences.Add(args[i + 1]);
                i++;
            }
            else if (args[i] == "-dict")
            {
                dictionary_path = args[i + 1];
                i++;
            }
            else if (args[i] == "-templates")
            {
                syntax_templates = args[i + 1];
                i++;
            }
            else if (args[i] == "-output")
            {
                result_folder = args[i + 1];
                i++;
            }
            else if (args[i] == "-max_samples")
            {
                MAX_SAMPLE = int.Parse(args[i + 1]);
                i++;
            }
            else if (args[i] == "-skip")
            {
                nb_skip = int.Parse(args[i + 1]);
                i++;
            }
            else if (args[i] == "-max_len")
            {
                MAX_LEN = int.Parse(args[i + 1]);
                i++;
            }
            else if (args[i] == "-filter")
            {
                filters = args[i + 1].Split(',');
                i++;
            }
            else
            {
                throw new ApplicationException(string.Format("Unknown option {0}", args[i]));
            }
        }
        #endregion Command_Line_Options

        preprocessor = new Preprocessor();
        if (!string.IsNullOrEmpty(syntax_templates))
        {
            syntax_checker.LoadTemplates(syntax_templates);
        }

        Console.WriteLine("Loading dictionary {0}", dictionary_path);
        SolarixGrammarEngineNET.GrammarEngine2 gren = new SolarixGrammarEngineNET.GrammarEngine2();
        gren.Load(dictionary_path, true);

        // Файл для сохранения отобранных предложений-фактов.
        wrt_samples = new System.IO.StreamWriter(System.IO.Path.Combine(result_folder, "facts.txt"));

        // Предложения, которые не прошли детальную проверку синтаксической структуры
        wrt_skipped = new System.IO.StreamWriter(System.IO.Path.Combine(result_folder, "skipped.txt"));

        // Фильтр для предиката, с возможными значениями "3", "2s" и "1s"
        string filter_verb = filters.Where(z => "3 1s 2s".Split(' ').Contains(z)).FirstOrDefault();

        // Фильтр типа предложения. Допустимые значение - пустое или "q"
        string filter_sent = (filters.Where(z => "q".Split(' ').Contains(z)).FirstOrDefault()) ?? "";


        DateTime start_time = DateTime.Now;

        #region Processing_All_Files
        foreach (string mask in parsed_sentences)
        {
            string[] files = null;
            if (System.IO.Directory.Exists(mask))
            {
                files = System.IO.Directory.GetFiles(mask, "*.parsing.txt");
            }
            else if (mask.IndexOfAny("*?".ToCharArray()) != -1)
            {
                files = System.IO.Directory.GetFiles(System.IO.Path.GetDirectoryName(mask), System.IO.Path.GetFileName(mask));
            }
            else
            {
                files = new string[1] {
                    mask
                };
            }

            Console.WriteLine("Number of parsing files={0}", files.Length);

            foreach (string file in files)
            {
                if (sample_count >= MAX_SAMPLE)
                {
                    break;
                }

                Console.WriteLine("Processing {0}...", file);

                using (Sentences src = new Sentences(file))
                {
                    while (src.Next() && sample_count < MAX_SAMPLE)
                    {
                        Sentence sent = src.GetFetched();
                        sample_count++;

                        if (sent.root == null)
                        {
                            continue;
                        }

                        if (sample_count > 0 && (sample_count % 10000) == 0)
                        {
                            Console.Write("{0} samples extracted\r", sample_count);
                        }

                        if (sample_count >= nb_skip)
                        {
                            //Console.WriteLine("DEBUG [{0}] {1}", sample_count, sent.GetText());
                            ProcessSentence(gren, sent, MAX_LEN, filter_verb, filter_sent);
                        }
                    }
                }
            }
        }
        #endregion Processing_All_Files


        wrt_samples.Close();
        wrt_skipped.Close();

        return;
    }
Exemple #5
0
    public static string tmp_folder = ".";          // папка для генерируемых временных файлов - логи, датасеты.

    static void Main(string[] args)
    {
        List <string> model_params = new List <string>();

        try
        {
            if (args.Length > 0)
            {
                for (int i = 0; i < args.Length; ++i)
                {
                    if (args[i] == "-dict")
                    {
                        // Путь к файлу с конфигурацией словарной базы.
                        dictionary_path = args[i + 1];
                        ++i;
                    }
                    else if (args[i] == "-tmp")
                    {
                        // Временный каталог для сохранения датасетов.
                        tmp_folder = args[i + 1];
                        ++i;
                    }
                    else if (args[i] == "-autocorpus")
                    {
                        // В датасет добавляем слова, которые имеют только один лемматизации.
                        corpora.Add(new AutoLemmaCorpusGenerator());
                    }
                    else if (args[i] == "-corpus")
                    {
                        // Путь к бинарному корпусу в формате Solarix.
                        string corpus_path = args[i + 1];
                        corpora.Add(new SolarixBinaryCorpusReader(corpus_path));
                        ++i;
                    }
                    else if (args[i] == "-ud_corpus")
                    {
                        // Путь к корпусу в формате Universal Dependencies
                        string corpus_path = args[i + 1];
                        corpora.Add(new UniversalDependenciesCorpusReader(corpus_path));
                        ++i;
                    }
                    else if (args[i] == "-dme_corpus")
                    {
                        // Путь к корпусу в формате Dialog MorphEval
                        string corpus_path = args[i + 1];
                        corpora.Add(new DialogMorphEvalCorpus(corpus_path));
                        ++i;
                    }
                    else if (args[i] == "-nsample")
                    {
                        if (!int.TryParse(args[i + 1], out NSAMPLE))
                        {
                            throw new ApplicationException("Integer argument expected for -nsample");
                        }
                        i++;
                    }
                    else if (args[i] == "-minsentlen")
                    {
                        MIN_SENT_LEN = int.Parse(args[i + 1]);
                        ++i;
                    }
                    else if (args[i] == "-params")
                    {
                        string[] px = args[i + 1].Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                        model_params.AddRange(px);
                        ++i;
                    }
                    else
                    {
                        throw new ApplicationException(string.Format("Unknown option [{0}] in command line", args[i]));
                    }
                }
            }

            Console.WriteLine("Loading dictionary from {0}...", dictionary_path);
            SolarixGrammarEngineNET.GrammarEngine2 gren;
            gren = new SolarixGrammarEngineNET.GrammarEngine2();
            gren.Load(dictionary_path, true);

            Build_LemmByPostags(gren, model_params);
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: {0}", ex.Message);
        }

        return;
    }
    static void Main(string[] args)
    {
        string parsed_sentences = @"F:\Corpus\parsing\ru\SENT4.parsing.txt";
        string result_path = @"f:\tmp\negative3.dat";
        string dict_path = @"e:\MVoice\lem\bin-windows64\dictionary.xml";

        // Загрузим морфологический словарь, он нам понадобится для смены падежей слов.
        SolarixGrammarEngineNET.GrammarEngine2 gren = new SolarixGrammarEngineNET.GrammarEngine2();
        gren.Load(dict_path, true);


        string[] files = null;
        if (System.IO.Directory.Exists(parsed_sentences))
            files = System.IO.Directory.GetFiles(parsed_sentences, "*.parsing.txt");
        else
            files = new string[1] { parsed_sentences };

        List<TreeTemplate> templates = new List<TreeTemplate>();
        templates.Add(new TreeTemplate("[class:ГЛАГОЛ]( <PREPOS_ADJUNCT>[class:ПРЕДЛОГ].<OBJECT>[class:МЕСТОИМЕНИЕ,СУЩЕСТВИТЕЛЬНОЕ,ПРИЛАГАТЕЛЬНОЕ] )"));

        sample_count = 0;

        using (wrt = new System.IO.StreamWriter(result_path))
        {
            foreach (string file in files)
            {
                Console.WriteLine("Processing {0}...", file);

                using (Sentences src = new Sentences(file))
                {
                    while (src.Next())
                    {
                        Sentence sent = src.GetFetched();
                        if (sent.root != null)
                        {
                            #region AdjNounAdjNoun

                            for (int i1 = 0; i1 < sent.Tokens.Count; ++i1)
                            {
                                if (sent.Tokens[i1].part_of_speech == "СУЩЕСТВИТЕЛЬНОЕ")
                                {
                                    SNode node1 = sent.Nodes.Where(z => z.index == i1).First();
                                    if (node1.edge_types.Count > 0)
                                    {
                                        int edge1 = -1;

                                        for (int j1 = 0; j1 < node1.edge_types.Count; ++j1)
                                        {
                                            if (node1.edge_types[j1] == "ATTRIBUTE")
                                            {
                                                if (sent.Tokens[node1.children[j1].index].part_of_speech == "ПРИЛАГАТЕЛЬНОЕ")
                                                {
                                                    edge1 = j1;
                                                    break;
                                                }
                                            }
                                        }

                                        if (edge1 != -1)
                                        {
                                            // Нашли первое существительное с атрибутирующим прилагательным.
                                            int noun_ie1 = gren.FindEntry(sent.Tokens[i1].word, gren.FindPartOfSpeech(sent.Tokens[i1].part_of_speech));

                                            SToken adj1 = sent.Tokens[node1.children[edge1].index];
                                            adj1.word = adj1.word.ToLower();


                                            for (int i2 = i1 + 2; i2 < sent.Tokens.Count; ++i2)
                                            {
                                                if (sent.Tokens[i2].part_of_speech == "СУЩЕСТВИТЕЛЬНОЕ")
                                                {
                                                    int noun_ie2 = gren.FindEntry(sent.Tokens[i2].word, gren.FindPartOfSpeech(sent.Tokens[i2].part_of_speech));

                                                    if (noun_ie1 != noun_ie2)
                                                    {
                                                        int gender1 = gren.GetEntryAttrState(noun_ie1, SolarixGrammarEngineNET.GrammarEngineAPI.GENDER_ru);
                                                        int gender2 = gren.GetEntryAttrState(noun_ie2, SolarixGrammarEngineNET.GrammarEngineAPI.GENDER_ru);
                                                        if (gender1 == gender2)
                                                        {
                                                            string number1 = sent.Tokens[i1].tags.Where(z => z.StartsWith("ЧИСЛО:")).First().Split(':')[1];
                                                            string number2 = sent.Tokens[i2].tags.Where(z => z.StartsWith("ЧИСЛО:")).First().Split(':')[1];

                                                            if (number1 == number2)
                                                            {
                                                                SNode node2 = sent.Nodes.Where(z => z.index == i2).First();
                                                                if (node2.edge_types.Count > 0)
                                                                {
                                                                    int edge2 = -1;

                                                                    for (int j2 = 0; j2 < node2.edge_types.Count; ++j2)
                                                                    {
                                                                        if (node2.edge_types[j2] == "ATTRIBUTE")
                                                                        {
                                                                            if (sent.Tokens[node2.children[j2].index].part_of_speech == "ПРИЛАГАТЕЛЬНОЕ")
                                                                            {
                                                                                edge2 = j2;
                                                                                break;
                                                                            }
                                                                        }
                                                                    }

                                                                    if (edge2 != -1)
                                                                    {
                                                                        // Нашли второе существительное с атрибутирующим прилагательным.
                                                                        SToken adj2 = sent.Tokens[node2.children[edge2].index];
                                                                        adj2.word = adj2.word.ToLower();


                                                                        // Сгенерируем предложение, в котором эти прилагательные поменяны местами.
                                                                        List<SToken> tokens2 = new List<SToken>();
                                                                        foreach (SToken t in sent.Tokens)
                                                                        {
                                                                            if (t.index == adj1.index)
                                                                            {
                                                                                tokens2.Add(adj2);
                                                                            }
                                                                            else if (t.index == adj2.index)
                                                                            {
                                                                                tokens2.Add(adj1);
                                                                            }
                                                                            else
                                                                            {
                                                                                tokens2.Add(t);
                                                                            }
                                                                        }

                                                                        StoreSample(sent, tokens2);
                                                                    }
                                                                    else
                                                                    {
                                                                        // у второго существительного нет атрибутирующего прилагательного.
                                                                        // перенесем прилагательное от первого ко второму существительному.

                                                                        List<SToken> tokens2 = new List<SToken>();
                                                                        foreach (SToken t in sent.Tokens)
                                                                        {
                                                                            if (t.index == adj1.index)
                                                                            {
                                                                                continue;
                                                                            }
                                                                            else if (t.index == i2)
                                                                            {
                                                                                tokens2.Add(adj1);
                                                                                tokens2.Add(sent.Tokens[i2]);
                                                                            }
                                                                            else
                                                                            {
                                                                                tokens2.Add(t);
                                                                            }
                                                                        }

                                                                        StoreSample(sent, tokens2);

                                                                    }

                                                                }

                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                            #endregion AdjNounAdjNoun


                            #region NounNoun
                            // Ищем два существительных, связанных в конструкцию родительного дополнения:
                            // "восход солнца"
                            // Генерируем предложение с перестановкой слов и сменой падежей:
                            // "солнце восхода"
                            foreach (SNode n1 in sent.Nodes)
                            {
                                SToken t1 = sent.Tokens[n1.index]; // восход
                                if (t1.part_of_speech == "СУЩЕСТВИТЕЛЬНОЕ")
                                {
                                    if (n1.children.Count > 0)
                                    {
                                        int gen_edge_index = n1.edge_types.IndexOf("RIGHT_GENITIVE_OBJECT");
                                        if (gen_edge_index != -1)
                                        {
                                            SToken t2 = sent.Tokens[n1.children[gen_edge_index].index]; // солнца

                                            if (gen_edge_index != -1 && t2.part_of_speech == "СУЩЕСТВИТЕЛЬНОЕ")
                                            {
                                                List<SToken> tokens2 = new List<SToken>();
                                                bool t12_ok = true;
                                                foreach (SToken t in sent.Tokens)
                                                {
                                                    if (t.index == t1.index)
                                                    {
                                                        // сюда вставляем слово "солнца" и меняем его падеж на падеж слова t
                                                        string t_case = t.tags.Where(z => z.StartsWith("ПАДЕЖ:")).First().Split(':')[1];
                                                        string t_number = t2.tags.Where(z => z.StartsWith("ЧИСЛО:")).First().Split(':')[1];
                                                        int ie_t2 = gren.FindEntry(t2.lemma, gren.FindPartOfSpeech(t2.part_of_speech));
                                                        if (ie_t2 != -1)
                                                        {
                                                            List<int> coords = new List<int>();
                                                            List<int> states = new List<int>();
                                                            coords.Add(SolarixGrammarEngineNET.GrammarEngineAPI.CASE_ru);
                                                            states.Add(gren.FindState(SolarixGrammarEngineNET.GrammarEngineAPI.CASE_ru, t_case));
                                                            coords.Add(SolarixGrammarEngineNET.GrammarEngineAPI.NUMBER_ru);
                                                            states.Add(gren.FindState(SolarixGrammarEngineNET.GrammarEngineAPI.NUMBER_ru, t_number));
                                                            List<string> forms = gren.GenerateWordforms(ie_t2, coords, states);
                                                            if (forms.Count > 0)
                                                            {
                                                                string new_word = gren.RestoreCasing(ie_t2, forms[0]);
                                                                SToken new_t = new SToken();
                                                                new_t.index = t.index;
                                                                new_t.word = new_word;
                                                                new_t.lemma = t.lemma;
                                                                new_t.part_of_speech = t1.part_of_speech;
                                                                tokens2.Add(new_t);
                                                            }
                                                            else
                                                            {
                                                                t12_ok = false;
                                                            }
                                                        }
                                                        else
                                                        {
                                                            t12_ok = false;
                                                        }
                                                    }
                                                    else if (t.index == t2.index)
                                                    {
                                                        // сюда вставляем слово "восход" и меняем его падеж на родительный
                                                        string t_number = t1.tags.Where(z => z.StartsWith("ЧИСЛО:")).First().Split(':')[1];
                                                        int ie_t1 = gren.FindEntry(t1.lemma, gren.FindPartOfSpeech(t1.part_of_speech));
                                                        if (ie_t1 != -1)
                                                        {
                                                            List<int> coords = new List<int>();
                                                            List<int> states = new List<int>();
                                                            coords.Add(SolarixGrammarEngineNET.GrammarEngineAPI.CASE_ru);
                                                            states.Add(SolarixGrammarEngineNET.GrammarEngineAPI.GENITIVE_CASE_ru);
                                                            coords.Add(SolarixGrammarEngineNET.GrammarEngineAPI.NUMBER_ru);
                                                            states.Add(gren.FindState(SolarixGrammarEngineNET.GrammarEngineAPI.NUMBER_ru, t_number));
                                                            List<string> forms = gren.GenerateWordforms(ie_t1, coords, states);
                                                            if (forms.Count > 0)
                                                            {
                                                                string new_word = gren.RestoreCasing(ie_t1, forms[0]);
                                                                SToken new_t = new SToken();
                                                                new_t.index = t.index;
                                                                new_t.word = new_word;
                                                                new_t.lemma = t.lemma;
                                                                new_t.part_of_speech = t.part_of_speech;
                                                                tokens2.Add(new_t);
                                                            }
                                                            else
                                                            {
                                                                t12_ok = false;
                                                            }
                                                        }
                                                        else
                                                        {
                                                            t12_ok = false;
                                                        }

                                                    }
                                                    else
                                                    {
                                                        tokens2.Add(t);
                                                    }
                                                }

                                                if (t12_ok)
                                                {
                                                    StoreSample(sent, tokens2);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            #endregion NounNoun


                            #region PrepObject
                            // Ищем предлог.
                            foreach (SToken token_prepos in sent.Tokens)
                            {
                                if (token_prepos.part_of_speech == "ПРЕДЛОГ")
                                {
                                    // Нашли предлог. Теперь перенесем его в другую позицию.
                                    List<Tuple<SToken, float>> tokens2 = sent.Tokens.Where(z => z.index != token_prepos.index).Select(z => new Tuple<SToken, float>(z, z.index)).ToList();

                                    foreach (var t2 in tokens2.Where(z => z.Item1.index != token_prepos.index + 1))
                                    {
                                        // Ставим предлог в позицию ПЕРЕД токеном t2 и генерируем предложение.
                                        List<Tuple<SToken, float>> tokens3 = new List<Tuple<SToken, float>>();
                                        tokens3.AddRange(tokens2);
                                        tokens3.Add(new Tuple<SToken, float>(token_prepos, t2.Item2 - 0.5f));

                                        StoreSample(sent, tokens3.OrderBy(z => z.Item2).Select(z => z.Item1).ToList());
                                    }
                                }
                            }
                            #endregion PrepObject


                            /*
                                                        foreach (TreeTemplate t in templates)
                                                        {
                                                            if (t.Match(sent))
                                                            {
                                                            }
                                                        }
                            */
                        }
                    }
                }
            }
        }

        Console.WriteLine("\nsample_count={0}", sample_count);

        return;
    }
    static void Main(string[] args)
    {
        string parsed_sentences = @"F:\Corpus\parsing\ru\SENT4.parsing.txt";
        string result_path      = @"f:\tmp\negative3.dat";
        string dict_path        = @"e:\MVoice\lem\bin-windows64\dictionary.xml";

        // Загрузим морфологический словарь, он нам понадобится для смены падежей слов.
        SolarixGrammarEngineNET.GrammarEngine2 gren = new SolarixGrammarEngineNET.GrammarEngine2();
        gren.Load(dict_path, true);


        string[] files = null;
        if (System.IO.Directory.Exists(parsed_sentences))
        {
            files = System.IO.Directory.GetFiles(parsed_sentences, "*.parsing.txt");
        }
        else
        {
            files = new string[1] {
                parsed_sentences
            }
        };

        List <TreeTemplate> templates = new List <TreeTemplate>();

        templates.Add(new TreeTemplate("[class:ГЛАГОЛ]( <PREPOS_ADJUNCT>[class:ПРЕДЛОГ].<OBJECT>[class:МЕСТОИМЕНИЕ,СУЩЕСТВИТЕЛЬНОЕ,ПРИЛАГАТЕЛЬНОЕ] )"));

        sample_count = 0;

        using (wrt = new System.IO.StreamWriter(result_path))
        {
            foreach (string file in files)
            {
                Console.WriteLine("Processing {0}...", file);

                using (Sentences src = new Sentences(file))
                {
                    while (src.Next())
                    {
                        Sentence sent = src.GetFetched();
                        if (sent.root != null)
                        {
                            #region AdjNounAdjNoun

                            for (int i1 = 0; i1 < sent.Tokens.Count; ++i1)
                            {
                                if (sent.Tokens[i1].part_of_speech == "СУЩЕСТВИТЕЛЬНОЕ")
                                {
                                    SNode node1 = sent.Nodes.Where(z => z.index == i1).First();
                                    if (node1.edge_types.Count > 0)
                                    {
                                        int edge1 = -1;

                                        for (int j1 = 0; j1 < node1.edge_types.Count; ++j1)
                                        {
                                            if (node1.edge_types[j1] == "ATTRIBUTE")
                                            {
                                                if (sent.Tokens[node1.children[j1].index].part_of_speech == "ПРИЛАГАТЕЛЬНОЕ")
                                                {
                                                    edge1 = j1;
                                                    break;
                                                }
                                            }
                                        }

                                        if (edge1 != -1)
                                        {
                                            // Нашли первое существительное с атрибутирующим прилагательным.
                                            int noun_ie1 = gren.FindEntry(sent.Tokens[i1].word, gren.FindPartOfSpeech(sent.Tokens[i1].part_of_speech));

                                            SToken adj1 = sent.Tokens[node1.children[edge1].index];
                                            adj1.word = adj1.word.ToLower();


                                            for (int i2 = i1 + 2; i2 < sent.Tokens.Count; ++i2)
                                            {
                                                if (sent.Tokens[i2].part_of_speech == "СУЩЕСТВИТЕЛЬНОЕ")
                                                {
                                                    int noun_ie2 = gren.FindEntry(sent.Tokens[i2].word, gren.FindPartOfSpeech(sent.Tokens[i2].part_of_speech));

                                                    if (noun_ie1 != noun_ie2)
                                                    {
                                                        int gender1 = gren.GetEntryAttrState(noun_ie1, SolarixGrammarEngineNET.GrammarEngineAPI.GENDER_ru);
                                                        int gender2 = gren.GetEntryAttrState(noun_ie2, SolarixGrammarEngineNET.GrammarEngineAPI.GENDER_ru);
                                                        if (gender1 == gender2)
                                                        {
                                                            string number1 = sent.Tokens[i1].tags.Where(z => z.StartsWith("ЧИСЛО:")).First().Split(':')[1];
                                                            string number2 = sent.Tokens[i2].tags.Where(z => z.StartsWith("ЧИСЛО:")).First().Split(':')[1];

                                                            if (number1 == number2)
                                                            {
                                                                SNode node2 = sent.Nodes.Where(z => z.index == i2).First();
                                                                if (node2.edge_types.Count > 0)
                                                                {
                                                                    int edge2 = -1;

                                                                    for (int j2 = 0; j2 < node2.edge_types.Count; ++j2)
                                                                    {
                                                                        if (node2.edge_types[j2] == "ATTRIBUTE")
                                                                        {
                                                                            if (sent.Tokens[node2.children[j2].index].part_of_speech == "ПРИЛАГАТЕЛЬНОЕ")
                                                                            {
                                                                                edge2 = j2;
                                                                                break;
                                                                            }
                                                                        }
                                                                    }

                                                                    if (edge2 != -1)
                                                                    {
                                                                        // Нашли второе существительное с атрибутирующим прилагательным.
                                                                        SToken adj2 = sent.Tokens[node2.children[edge2].index];
                                                                        adj2.word = adj2.word.ToLower();


                                                                        // Сгенерируем предложение, в котором эти прилагательные поменяны местами.
                                                                        List <SToken> tokens2 = new List <SToken>();
                                                                        foreach (SToken t in sent.Tokens)
                                                                        {
                                                                            if (t.index == adj1.index)
                                                                            {
                                                                                tokens2.Add(adj2);
                                                                            }
                                                                            else if (t.index == adj2.index)
                                                                            {
                                                                                tokens2.Add(adj1);
                                                                            }
                                                                            else
                                                                            {
                                                                                tokens2.Add(t);
                                                                            }
                                                                        }

                                                                        StoreSample(sent, tokens2);
                                                                    }
                                                                    else
                                                                    {
                                                                        // у второго существительного нет атрибутирующего прилагательного.
                                                                        // перенесем прилагательное от первого ко второму существительному.

                                                                        List <SToken> tokens2 = new List <SToken>();
                                                                        foreach (SToken t in sent.Tokens)
                                                                        {
                                                                            if (t.index == adj1.index)
                                                                            {
                                                                                continue;
                                                                            }
                                                                            else if (t.index == i2)
                                                                            {
                                                                                tokens2.Add(adj1);
                                                                                tokens2.Add(sent.Tokens[i2]);
                                                                            }
                                                                            else
                                                                            {
                                                                                tokens2.Add(t);
                                                                            }
                                                                        }

                                                                        StoreSample(sent, tokens2);
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                            #endregion AdjNounAdjNoun


                            #region NounNoun
                            // Ищем два существительных, связанных в конструкцию родительного дополнения:
                            // "восход солнца"
                            // Генерируем предложение с перестановкой слов и сменой падежей:
                            // "солнце восхода"
                            foreach (SNode n1 in sent.Nodes)
                            {
                                SToken t1 = sent.Tokens[n1.index]; // восход
                                if (t1.part_of_speech == "СУЩЕСТВИТЕЛЬНОЕ")
                                {
                                    if (n1.children.Count > 0)
                                    {
                                        int gen_edge_index = n1.edge_types.IndexOf("RIGHT_GENITIVE_OBJECT");
                                        if (gen_edge_index != -1)
                                        {
                                            SToken t2 = sent.Tokens[n1.children[gen_edge_index].index]; // солнца

                                            if (gen_edge_index != -1 && t2.part_of_speech == "СУЩЕСТВИТЕЛЬНОЕ")
                                            {
                                                List <SToken> tokens2 = new List <SToken>();
                                                bool          t12_ok  = true;
                                                foreach (SToken t in sent.Tokens)
                                                {
                                                    if (t.index == t1.index)
                                                    {
                                                        // сюда вставляем слово "солнца" и меняем его падеж на падеж слова t
                                                        string t_case   = t.tags.Where(z => z.StartsWith("ПАДЕЖ:")).First().Split(':')[1];
                                                        string t_number = t2.tags.Where(z => z.StartsWith("ЧИСЛО:")).First().Split(':')[1];
                                                        int    ie_t2    = gren.FindEntry(t2.lemma, gren.FindPartOfSpeech(t2.part_of_speech));
                                                        if (ie_t2 != -1)
                                                        {
                                                            List <int> coords = new List <int>();
                                                            List <int> states = new List <int>();
                                                            coords.Add(SolarixGrammarEngineNET.GrammarEngineAPI.CASE_ru);
                                                            states.Add(gren.FindState(SolarixGrammarEngineNET.GrammarEngineAPI.CASE_ru, t_case));
                                                            coords.Add(SolarixGrammarEngineNET.GrammarEngineAPI.NUMBER_ru);
                                                            states.Add(gren.FindState(SolarixGrammarEngineNET.GrammarEngineAPI.NUMBER_ru, t_number));
                                                            List <string> forms = gren.GenerateWordforms(ie_t2, coords, states);
                                                            if (forms.Count > 0)
                                                            {
                                                                string new_word = gren.RestoreCasing(ie_t2, forms[0]);
                                                                SToken new_t    = new SToken();
                                                                new_t.index          = t.index;
                                                                new_t.word           = new_word;
                                                                new_t.lemma          = t.lemma;
                                                                new_t.part_of_speech = t1.part_of_speech;
                                                                tokens2.Add(new_t);
                                                            }
                                                            else
                                                            {
                                                                t12_ok = false;
                                                            }
                                                        }
                                                        else
                                                        {
                                                            t12_ok = false;
                                                        }
                                                    }
                                                    else if (t.index == t2.index)
                                                    {
                                                        // сюда вставляем слово "восход" и меняем его падеж на родительный
                                                        string t_number = t1.tags.Where(z => z.StartsWith("ЧИСЛО:")).First().Split(':')[1];
                                                        int    ie_t1    = gren.FindEntry(t1.lemma, gren.FindPartOfSpeech(t1.part_of_speech));
                                                        if (ie_t1 != -1)
                                                        {
                                                            List <int> coords = new List <int>();
                                                            List <int> states = new List <int>();
                                                            coords.Add(SolarixGrammarEngineNET.GrammarEngineAPI.CASE_ru);
                                                            states.Add(SolarixGrammarEngineNET.GrammarEngineAPI.GENITIVE_CASE_ru);
                                                            coords.Add(SolarixGrammarEngineNET.GrammarEngineAPI.NUMBER_ru);
                                                            states.Add(gren.FindState(SolarixGrammarEngineNET.GrammarEngineAPI.NUMBER_ru, t_number));
                                                            List <string> forms = gren.GenerateWordforms(ie_t1, coords, states);
                                                            if (forms.Count > 0)
                                                            {
                                                                string new_word = gren.RestoreCasing(ie_t1, forms[0]);
                                                                SToken new_t    = new SToken();
                                                                new_t.index          = t.index;
                                                                new_t.word           = new_word;
                                                                new_t.lemma          = t.lemma;
                                                                new_t.part_of_speech = t.part_of_speech;
                                                                tokens2.Add(new_t);
                                                            }
                                                            else
                                                            {
                                                                t12_ok = false;
                                                            }
                                                        }
                                                        else
                                                        {
                                                            t12_ok = false;
                                                        }
                                                    }
                                                    else
                                                    {
                                                        tokens2.Add(t);
                                                    }
                                                }

                                                if (t12_ok)
                                                {
                                                    StoreSample(sent, tokens2);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            #endregion NounNoun


                            #region PrepObject
                            // Ищем предлог.
                            foreach (SToken token_prepos in sent.Tokens)
                            {
                                if (token_prepos.part_of_speech == "ПРЕДЛОГ")
                                {
                                    // Нашли предлог. Теперь перенесем его в другую позицию.
                                    List <Tuple <SToken, float> > tokens2 = sent.Tokens.Where(z => z.index != token_prepos.index).Select(z => new Tuple <SToken, float>(z, z.index)).ToList();

                                    foreach (var t2 in tokens2.Where(z => z.Item1.index != token_prepos.index + 1))
                                    {
                                        // Ставим предлог в позицию ПЕРЕД токеном t2 и генерируем предложение.
                                        List <Tuple <SToken, float> > tokens3 = new List <Tuple <SToken, float> >();
                                        tokens3.AddRange(tokens2);
                                        tokens3.Add(new Tuple <SToken, float>(token_prepos, t2.Item2 - 0.5f));

                                        StoreSample(sent, tokens3.OrderBy(z => z.Item2).Select(z => z.Item1).ToList());
                                    }
                                }
                            }
                            #endregion PrepObject


                            /*
                             *                          foreach (TreeTemplate t in templates)
                             *                          {
                             *                              if (t.Match(sent))
                             *                              {
                             *                              }
                             *                          }
                             */
                        }
                    }
                }
            }
        }

        Console.WriteLine("\nsample_count={0}", sample_count);

        return;
    }
}
Exemple #8
0
    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;
    }
Exemple #9
0
    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);
    }
Exemple #10
0
    static void Main(string[] args)
    {
        string corpus_path = "";
        string dict_path   = "";
        string data_folder = "";

        for (int iarg = 0; iarg < args.Length; ++iarg)
        {
            string cmd = args[iarg].Substring(1);
            if (cmd == "corpus")
            {
                corpus_path = args[iarg + 1];
                iarg++;
            }
            else if (cmd == "dict")
            {
                dict_path = args[iarg + 1];
                iarg++;
            }
            else if (cmd == "workdir")
            {
                data_folder = args[iarg + 1];
                iarg++;
            }
            else if (cmd == "window")
            {
                window = int.Parse(args[iarg + 1]);
                iarg++;
            }
            else if (cmd == "emit_shingles")
            {
                emit_shingles = bool.Parse(args[iarg + 1]);
                iarg++;
            }
            else if (cmd == "emit_morphtags")
            {
                emit_morphtags = bool.Parse(args[iarg + 1]);
                iarg++;
            }
            else
            {
                throw new ApplicationException($"Unknown option [{args[iarg]}]");
            }
        }



        string train_path       = System.IO.Path.Combine(data_folder, "chunker_train.dat");
        string test_path        = System.IO.Path.Combine(data_folder, "chunker_test.dat");
        string test_result_path = System.IO.Path.Combine(data_folder, "chunker_eval.txt");

        Console.WriteLine("Loading dictionary from {0}...", dict_path);
        SolarixGrammarEngineNET.GrammarEngine2 gren;
        gren = new SolarixGrammarEngineNET.GrammarEngine2();
        gren.Load(dict_path, true);

        int counter   = 0;
        int MAX_COUNT = 10000000;

        string[] bin_corpora = System.IO.Directory.GetFiles(System.IO.Path.GetDirectoryName(corpus_path), System.IO.Path.GetFileName(corpus_path));

        System.IO.StreamWriter wrt_train = new System.IO.StreamWriter(train_path);
        System.IO.StreamWriter wrt_test  = new System.IO.StreamWriter(test_path);

        foreach (string path1 in bin_corpora)
        {
            Console.WriteLine("Reading corpus {0}...", path1);

            IntPtr hCorpus = SolarixGrammarEngineNET.GrammarEngine.sol_OpenCorpusStorage8(gren.GetEngineHandle(), path1, false);
            if (hCorpus == IntPtr.Zero)
            {
                throw new ApplicationException(string.Format("Can not open corpus {0}", path1));
            }

            while (true)
            {
                IntPtr hSample1 = SolarixGrammarEngineNET.GrammarEngine.sol_LoadSyntaxTree(gren.GetEngineHandle(), hCorpus);
                if (hSample1 == IntPtr.Zero)
                {
                    break;
                }

                IntPtr hSample2 = SolarixGrammarEngineNET.GrammarEngine.sol_LoadSyntaxTree(gren.GetEngineHandle(), hCorpus);
                IntPtr hSample3 = SolarixGrammarEngineNET.GrammarEngine.sol_LoadSyntaxTree(gren.GetEngineHandle(), hCorpus);

                if (counter >= MAX_COUNT)
                {
                    break;
                }

                string sample       = SolarixGrammarEngineNET.GrammarEngine.sol_GetSentenceW(hSample1);
                var    morphology   = new SolarixGrammarEngineNET.AnalysisResults(gren, SolarixGrammarEngineNET.GrammarEngine.sol_GetTreeHandle(hSample1), false);
                var    tokenization = new SolarixGrammarEngineNET.AnalysisResults(gren, SolarixGrammarEngineNET.GrammarEngine.sol_GetTreeHandle(hSample2), false);
                var    syntax_tree  = new SolarixGrammarEngineNET.AnalysisResults(gren, SolarixGrammarEngineNET.GrammarEngine.sol_GetTreeHandle(hSample3), false);

                counter++;
                Console.WriteLine("0.{1}: {0}", sample, counter);

                bool test_sample = false, train_sample = true;
                if ((counter % 10) == 0)
                {
                    test_sample  = true;
                    train_sample = false;
                }

                if (syntax_tree.Count == 3)
                {
                    System.IO.StreamWriter wrt = train_sample ? wrt_train : wrt_test;


                    // Получаем список слов с прикрепленными к ним номерами чанков.
                    Dictionary <int /*word_index*/, int /*chunk_index*/> labels = new Dictionary <int, int>();
                    FindChunks(syntax_tree, labels);

                    // Вставим специальный чанк для фиктивного слова слева от первого, чтобы первое слово
                    // автоматом пометилось как начало чанка.
                    labels[-1] = -1;

                    for (int i = 1; i < morphology.Count - 1; ++i)
                    {
                        int label = 0;

                        int word_index = i - 1;

                        // Если слово начинает новый чанк, то есть слева было слово из другого чанка,
                        // то метка будет 1.
                        try
                        {
                            if (labels[word_index - 1] != labels[word_index])
                            {
                                label = 1;
                            }
                        }
                        catch (KeyNotFoundException ex)
                        {
                            Console.WriteLine("Missing word {0} in syntax tree for sample {1}", morphology[i].GetWord(), sample);
                        }


                        string features = GetFeatures(gren, morphology, i);
                        wrt.WriteLine("{0}\t{1}", label, features);
                    }

                    wrt.WriteLine("");
                    wrt.Flush();
                }

                SolarixGrammarEngineNET.GrammarEngine.sol_FreeSyntaxTree(hSample1);
                SolarixGrammarEngineNET.GrammarEngine.sol_FreeSyntaxTree(hSample2);
                SolarixGrammarEngineNET.GrammarEngine.sol_FreeSyntaxTree(hSample3);
            }

            SolarixGrammarEngineNET.GrammarEngine.sol_CloseCorpusStorage(gren.GetEngineHandle(), hCorpus);
        }

        wrt_train.Close();
        wrt_test.Close();


        // Сохраним информацию о кодировке фич, чтобы потом в C++ коде формировать данные для разбора.
        string codebook_path = System.IO.Path.Combine(data_folder, "chunker.codebook");

        Console.WriteLine("Writing feature codebook to {0}", codebook_path);
        if (System.IO.File.Exists(codebook_path))
        {
            System.IO.File.Delete(codebook_path);
        }

        using (System.IO.BinaryWriter wr = new System.IO.BinaryWriter(System.IO.File.OpenWrite(codebook_path)))
        {
            wr.Write(0);

            wr.Write(window);
            wr.Write(shingle_len);
            wr.Write(emit_shingles);
            wr.Write(emit_morphtags);

            wr.Write(shingle2index.Count);
            foreach (var k in shingle2index)
            {
                byte[] l8 = System.Text.Encoding.UTF8.GetBytes(k.Key);
                wr.Write(l8.Length);
                wr.Write(l8);
                wr.Write(k.Value);
            }
        }


        Console.WriteLine("Start training with CRFSuite on {0}...", train_path);
        System.Diagnostics.Process p = new System.Diagnostics.Process();
        p.StartInfo.Arguments = train_path + " " + data_folder;
        p.StartInfo.FileName  = string.Format("{0}\\chunker_train.cmd", System.IO.Directory.GetCurrentDirectory());

        Console.WriteLine("Executing {0} {1}", p.StartInfo.FileName, p.StartInfo.Arguments);
        bool r = false;

        r = p.Start();
        p.WaitForExit();

        // Оценка точности
        p = new System.Diagnostics.Process();
        p.StartInfo.Arguments = test_path + " " + test_result_path + " " + data_folder;
        p.StartInfo.FileName  = string.Format("{0}\\chunker_test.cmd", System.IO.Directory.GetCurrentDirectory());

        Console.WriteLine("Executing {0} {1}", p.StartInfo.FileName, p.StartInfo.Arguments);
        r = p.Start();
        p.WaitForExit();

        int nb_instance_errors = 0;
        int nb_word_errors     = 0;
        int nb_instances       = 0;
        int nb_words           = 0;

        using (System.IO.StreamReader rdr = new System.IO.StreamReader(test_result_path))
        {
            bool instance_ok = true;
            while (!rdr.EndOfStream)
            {
                string line = rdr.ReadLine();
                if (line == null)
                {
                    break;
                }

                if (line == "")
                {
                    nb_instances++;
                    if (!instance_ok)
                    {
                        nb_instance_errors++;
                    }

                    instance_ok = true;
                }
                else
                {
                    nb_words++;
                    string[] tx = line.Split('\t');
                    if (tx[0] != tx[1])
                    {
                        instance_ok = false;
                        nb_word_errors++;
                    }
                }
            }
        }

        Console.WriteLine("Per word accuracy={0}", ((float)(nb_words - nb_word_errors)) / nb_words);
        Console.WriteLine("Per instance accuracy={0}", ((float)(nb_instances - nb_instance_errors)) / nb_instances);

        return;
    }
Exemple #11
0
    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;
    }