Пример #1
0
        /// <summary>
        /// Строит n-грамную модель.
        /// </summary>
        /// <param name="inputFile">Входной файл корпуса.</param>
        /// <param name="reader">Объект для чтения корпуса.</param>
        private void BuildNGrammModel(string inputFile, ICorporaReader reader)
        {
            reader.Open(inputFile);
            nGramm = new TagNGramm();
            int nGrammSize = 3;

            foreach (var sentense in reader.ReadSentences(int.MaxValue))
            {
                //предлоги в корпусе не имеют падежа, а союзы не имеют типа
                //чтобы добавить эту информацию, воспользуемся модифицированным словарём
                foreach (var lexem in sentense)
                {
                    if (serviceTags.ContainsKey(lexem.Word.ToLower()))
                    {
                        lexem.Tag = serviceTags[lexem.Word];
                    }
                }
                if (sentense.Count > 0 && sentense.Count(a => a.Tag == Tag.NoWord ||
                                                         a.Tag == Tag.Unfixed) == 0)
                {
                    foreach (var ngamm in sentense.BuildNGramms(nGrammSize))
                    {
                        nGramm.AddNGramm(ngamm);
                    }
                }
            }
            reader.Close();
        }
Пример #2
0
 /// <summary>
 /// Трунирует модель классов энтропии.
 /// </summary>
 /// <param name="inputFile">Входной файл словаря.</param>
 /// <param name="reader">Объект для чтения корпуса.</param>
 private void BuildEntropyClassModel(string inputFile, ICorporaReader reader)
 {
     entClass = new DawgEntropyClassModel();
     reader.Open(inputFile);
     serviceTags = new Dictionary <string, Tag>();
     foreach (WordForm lexem in reader.ReadDictionary(long.MaxValue))
     {
         if ((lexem.Tag & (Tag.Conjunction | Tag.Particle | Tag.Preposition)) != 0)
         {
             Tag outTag = Tag.NoWord;
             serviceTags.TryGetValue(lexem.Word.ToLower(), out outTag);
             serviceTags[lexem.Word.ToLower()] = outTag | lexem.Tag;
         }
         entClass.AddLexem(lexem);
     }
     ((DawgEntropyClassModel)entClass).Build();
     reader.Close();
 }
Пример #3
0
 /// <summary>
 /// Тренирует модель полностью, включая модель классов энтропии и n-граммную модель.
 /// </summary>
 /// <param name="dictionary">Словарь.</param>
 /// <param name="nGrammCorpora">Корпус для n-граммной модели.</param>
 /// <param name="trainingCorpora">Корпус для обучения модели.</param>
 /// <param name="reader">Объект, осуществляющий чтение корпуса.</param>
 /// <param name="sentCount">Количество предложений для чтения.</param>
 /// <param name="concurrent">Установить <c>true</c>, если необходимо выполнить параллельно. </param>
 /// <param name="callBack">Фукнция для печати прогресса.</param>
 public void TrainFull(string dictionary, string nGrammCorpora, string trainingCorpora,
                       ICorporaReader reader, int sentCount, bool concurrent,
                       Action <string> callBack = null)
 {
     if (callBack == null)
     {
         callBack = (s) => { }
     }
     ;
     callBack("Начато построение модели классов энтропии.");
     BuildEntropyClassModel(dictionary, reader);
     callBack("Построение модели классов энтропии заврешено.");
     callBack("Начато построение n-граммной модели.");
     BuildNGrammModel(nGrammCorpora, reader);
     callBack("Построение n-грамнной модели завершено.");
     callBack("Начато обучение классификаторов.");
     TrainFull(trainingCorpora, reader, sentCount, concurrent);
     callBack("Обучение Завершено.");
 }
Пример #4
0
        /// <summary>
        /// Трунирует модель целиком.
        /// </summary>
        /// <param name="corporaFile">Файл корпуса.</param>
        /// <param name="reader">Объект для чтения корпуса.</param>
        /// <param name="sentCount">Количество предложений.</param>
        /// <param name="concurrent">Установить <c>true</c>, если необходимо выполнить параллельно. </param>
        private void TrainFull(string corporaFile, ICorporaReader reader, int sentCount,
                               bool concurrent)
        {
            reader.Open(corporaFile);
            punctuation        = new List <string>();
            sentenceDelimiters = new List <string>();
            reader.Open(corporaFile);
            //читаем заданное количество предложений
            foreach (var sentence in reader.ReadSentences(sentCount))
            {
                //предлоги в корпусе не имеют падежа, а союзы не имеют типа
                //чтобы добавить эту информацию, воспользуемся модифицированным словарём
                foreach (var lexem in sentence)
                {
                    if (serviceTags.ContainsKey(lexem.Word.ToLower()))
                    {
                        lexem.Tag = serviceTags[lexem.Word];
                    }
                }
                //запишем все знаки пунктуации, которые встретим
                foreach (var punc in sentence.Where(a => (a.Tag & Tag.Punctuation) != 0 &&
                                                    !a.Word.Any((c) => char.IsLetter(c)) && !punctuation.Contains(a.Word)))
                {
                    punctuation.Add(punc.Word);
                }
                WordForm last = sentence.Last();
                if ((last.Tag & Tag.Punctuation) != 0 && !sentenceDelimiters.Contains(last.Word))
                {
                    sentenceDelimiters.Add(last.Word);
                }
                if (sentence.Count(lexem => lexem.Tag == Tag.NoWord || lexem.Tag == Tag.Unfixed) == 0)
                {
                    //строим все возможные окна длины 7
                    foreach (var window in Utils.BuildAllWindows(sentence, 7))
                    {
                        Tag tag = window.Skip(3).First().Tag; //тэг разгадываемого слова
                        foreach (var group in groups)         //для каждой группы
                        {
                            group.AddVector(window.ToVector(nGramm, entClass), tag);
                        }
                    }
                }
            }
            if (concurrent) //обучаем параллельно
            {
                Parallel.ForEach(groups, (group) => { group.Train(true); });
            }
            else
            {
                foreach (var group in groups)
                {
                    group.Train(false);
                }
            }
            string pattern = @"(-?\d+(?:\.\d+)?|";

            foreach (var sign in punctuation)
            {
                pattern += Regex.Escape(sign) + "+|";
            }
            pattern              = pattern + @"\s+)";
            this.lexemPattern    = new Regex(pattern);
            this.sentencePattern = new Regex(@"(\.+|!|\?)");
            reader.Close();
        }
Пример #5
0
        /// <summary>
        /// Запускает процесс обучения модели.
        /// </summary>
        /// <param name="corporaFile">Исходный файл корпуса.</param>
        /// <param name="sentCount">Количество предложений, которые будут прочитаны.</param>
        /// <param name="concurrent"><c>true</c>, если обучение должно происходить
        /// параллельно (для такого варианта может понадобиться больше памяти, но
        /// процесс займёт меньше времени).</param>
        /// <remarks>Может занять очень много времени и использовать большое
        /// количество памяти.</remarks>
        public void Train(string corporaFile, ICorporaReader reader, int sentCount, bool concurrent)
        {
            punctuation        = new List <string>();
            sentenceDelimiters = new List <string>();
            reader.Open(corporaFile);
            //читаем заданное количество предложений
            int i = 0;

            foreach (var sentence in reader.ReadSentences(sentCount))
            {
                //запишем все знаки пунктуации, которые встретим
                foreach (var punc in sentence.Where(a => (a.Tag & Tag.Punctuation) != 0 &&
                                                    !punctuation.Contains(a.Word)))
                {
                    punctuation.Add(punc.Word);
                }
                WordForm last = sentence.Last();
                if ((last.Tag & Tag.Punctuation) != 0 && !sentenceDelimiters.Contains(last.Word))
                {
                    sentenceDelimiters.Add(last.Word);
                }
                if (sentence.Count(lexem => lexem.Tag == Tag.NoWord) == 0)
                {
#if DEBUG
                    i++;
                    Console.Write(string.Format("\rПредложений прочитано: {0}", i));
#endif
                    //строим все возможные окна длины 7
                    foreach (var window in Utils.BuildAllWindows(sentence, 7))
                    {
                        Tag tag = window.Skip(3).First().Tag; //тэг разгадываемого слова
                        foreach (var group in groups)         //для каждой группы
                        {
                            group.AddVector(window.ToVector(nGramm, entClass), tag);
                        }
                    }
                }
            }
            if (concurrent) //обучаем параллельно
            {
                Parallel.ForEach <TagGroup>(groups, (group) => { group.Train(true); });
            }
            else
            {
                //обучаем последовательно
                i = 0;
                foreach (var group in groups)
                {
                    group.Train(false);
#if DEBUG
                    Console.WriteLine("Закончено обучение группы " + i);
#endif
                    i++;
                }
            }
            string pattern = @"(-?\d+(?:\.\d+)?|";
            foreach (var sign in punctuation)
            {
                pattern += Regex.Escape(sign) + "+|";
            }
            pattern              = pattern + @"\s+)";
            this.lexemPattern    = new Regex(pattern);
            this.sentencePattern = new Regex(@"(\.+|!|\?)");
            reader.Close();
        }