public void FinishLearning()
    {
        wrt_train.Close();
        wrt_test.Close();
        wrt_test2.Close();

        using (System.IO.StreamWriter wrt = new System.IO.StreamWriter("rnnsharp_tags.txt"))
        {
            for (int i = 0; i < tags.Count(); ++i)
            {
                wrt.WriteLine("{1}", i, tags.GetIdByIndex(i));
            }
        }


        string cmd = string.Format("{0}\\rnnsharp_train.cmd", System.IO.Directory.GetCurrentDirectory());

        System.Diagnostics.Process p = new System.Diagnostics.Process();
        p.StartInfo.Arguments = null;
        p.StartInfo.FileName  = cmd;

        Console.WriteLine("Executing {0}", p.StartInfo.FileName);

        bool r = p.Start();

        p.WaitForExit();

        return;
    }
Пример #2
0
    public void Check(
        string line,
        ref int total_word_count,
        ref int error_count_no_filter,
        ref int error_count_with_model
        )
    {
        // Морфологический разбор
        using (SolarixGrammarEngineNET.AnalysisResults tokens = gren.AnalyzeMorphology(line, LanguageID, SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags.SOL_GREN_COMPLETE_ONLY))
        {
            List <List <int> > word2tags     = new List <List <int> >();
            List <int>         selected_tags = new List <int>();

            // Токенизация без использования синтаксических правил
            using (SolarixGrammarEngineNET.AnalysisResults projs = gren.AnalyzeMorphology(line, LanguageID,
                                                                                          SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags.SOL_GREN_TOKENIZE_ONLY /*| SolarixGrammarEngineNET.GrammarEngine.SOL_GREN_DISABLE_FILTERS*/))
            {
                if (tokens.Count != projs.Count)
                {
                    return;
                }

                // Преобразуем все проекции каждого слова в варианты распознавания тегов

                List <int> tag_set = new List <int>();

                int start_tag = -1, end_tag = -1;

                //List<string> words = new List<string>();
                bool unmatched_tag = false;

                List <int> suffices        = new List <int>();
                int        last_word_index = tokens.Count - 1;

                for (int i = 0; i < tokens.Count; ++i)
                {
                    SolarixGrammarEngineNET.SyntaxTreeNode token = tokens[i];
                    string word = token.GetWord().ToLower();
                    //   words.Add(word);

                    int suffix_id = GetTokenSuffix(i, last_word_index, token);
                    suffices.Add(suffix_id);


                    SolarixGrammarEngineNET.SyntaxTreeNode proj = projs[i];
                    List <int> wt = new List <int>();
                    for (int j = 0; j < proj.VersionCount(); ++j)
                    {
                        int id_tag = tags.GetIndexById(tags.MatchTags(proj, j, gren));
                        if (id_tag != -1)
                        {
                            if (!wt.Contains(id_tag))
                            {
                                wt.Add(id_tag);
                            }

                            if (!tag_set.Contains(id_tag))
                            {
                                tag_set.Add(id_tag);
                            }
                        }

                        if (i == 0)
                        {
                            start_tag = id_tag;
                        }
                        else if (i == tokens.Count - 1)
                        {
                            end_tag = id_tag;
                        }
                    }

                    if (wt.Count == 0)
                    {
                        // ни один тег не подошел, это ошибка кодовой книги.
                        unmatched_tag = true;
                    }

                    word2tags.Add(wt);
                    selected_tags.Add(wt[0]);
                }

                if (unmatched_tag)
                {
                    return;
                }

                // -----------------------------------------
                // Посчитаем ошибки до применения модели
                // -----------------------------------------
                int n_err = 0;

                for (int iword = 1; iword < tokens.Count - 1; ++iword)
                {
                    SolarixGrammarEngineNET.SyntaxTreeNode token = tokens[iword];
                    int ekey1     = token.GetEntryID();
                    int id_class1 = gren.GetEntryClass(ekey1);

                    int tag = selected_tags[iword];
                    if (tag != -1)
                    {
                        TagMatcher m = tags[tags.GetIdByIndex(tag)];
                        if (!m.MatchPartOfSpeech(id_class1))
                        {
                            n_err++;
                        }
                    }
                }

                error_count_no_filter += n_err;
                total_word_count      += (tokens.Count - 2);

                int Nword  = tokens.Count; // кол-во последовательных шагов - число слов, включая левую и правую границы
                int Nstate = tag_set.Count;

                // Viterbi trellis

                // вероятности для состояний
                double[,] V = new double[Nword, Nstate];
                for (int t = 0; t < Nword; ++t)
                {
                    for (int s = 0; s < Nstate; ++s)
                    {
                        V[t, s] = 0.0;
                    }
                }

                // backpointers для отслеживания лучшего пути
                int[,] BACKPOINTER = new int[Nword, Nstate];
                for (int t = 0; t < Nword; ++t)
                {
                    for (int s = 0; s < Nstate; ++s)
                    {
                        BACKPOINTER[t, s] = -1; // возможно, надо как-то инициализировать дефолтный путь на случай, если найти лучший не получится - то есть надо проставить от начального до конечного.
                    }
                }
                V[0, tag_set.IndexOf(start_tag)] = 1.0; // начальное состояние - стартуем из этого состояния.

                for (int t = 1; t < Nword; ++t)
                {
                    // проставляем вероятность получения состояний на шаге t, исходя из значений на предыдущем шаге.

                    for (int s2 = 0; s2 < Nstate; ++s2) // состояния на шаге t
                    {
                        double max_v           = 0.0;
                        int    best_prev_state = 0;

                        int id_tag2 = tag_set[s2];

                        double b = 0.0;

                        Dictionary <int, double> bx;
                        if (PB.TryGetValue(id_tag2, out bx))
                        {
                            bx.TryGetValue(suffices[t], out b);
                        }

                        for (int s1 = 0; s1 < Nstate; ++s1) // состояния на шаге t-1
                        {
                            int id_tag1 = tag_set[s1];

                            double vt = V[t - 1, s1] * PA[id_tag1, id_tag2] * b;

                            if (vt > max_v)
                            {
                                max_v           = vt;
                                best_prev_state = s1;
                            }
                        }

                        V[t, s2]           = max_v;
                        BACKPOINTER[t, s2] = best_prev_state;
                    }
                }

                // обратный ход по состояниям, указанным в BACKPOINTER.

                int best_state = tag_set.IndexOf(end_tag);

                for (int t = Nword - 1; t > 0; --t)
                {
                    int best_prev_state = BACKPOINTER[t, best_state];

                    int selected_tag = tag_set[best_prev_state];

                    // Делаем вариант распознавания, давший этот токен, первым в списке.
                    // ATT: грубые ошибки выбора тега не допускаем, то есть разрешаем только те теги, которые были
                    // получены при распознавании слова.
                    if (word2tags[t - 1].Contains(selected_tag))
                    {
                        selected_tags[t - 1] = selected_tag;
                    }
                    else
                    {
                        // ... грубая ошибка выбора тега.
                    }

                    best_state = best_prev_state;
                }


                // Теперь проверяем количество ошибок в выборе частей речи.
                for (int iword = 1; iword < tokens.Count - 1; ++iword)
                {
                    SolarixGrammarEngineNET.SyntaxTreeNode token = tokens[iword];
                    int ekey1     = token.GetEntryID();
                    int id_class1 = gren.GetEntryClass(ekey1);

                    int tag = selected_tags[iword];
                    if (tag != -1)
                    {
                        TagMatcher m = tags[tags.GetIdByIndex(tag)];
                        if (!m.MatchPartOfSpeech(id_class1))
                        {
                            error_count_with_model++;
                        }
                    }
                }
            }
        }

        return;
    }