Beispiel #1
0
        internal List <Term> Similars(Term term, int count = 1)
        {
            if (count <= 0)
            {
                throw new ArgumentException("Количество возращаемых значений должно быть положительным");
            }
            List <Term> result = new List <Term>();

            if (term.rank == 0)
            {
                //При нулевом ранге терма (т.е. терм - это буква), confidence считаем исходя из наличия соответствующей буквы в алфавите
                var word = DB.GetWordBySymbol(term.text);
                if (word == null)
                {
                    return(result);
                }
                term.id         = word.Id;
                term.confidence = (term.id == 0 ? 0 : 1);
                term.Identified = true;
                result.Add(term);
            }
            else
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();
                //Если ранг терма больше нуля, то confidence считаем по набору дочерних элементов
                int[] childs = term
                               .Childs
                               .Distinct(new DAL.TermComparer())
                               .SelectMany(c => Similars(term: c, count: 1))
                               .Where(c => c.id != 0)
                               .Select(c => c.id)
                               .ToArray();
                sw.Stop(); Debug.WriteLine($"Similars->{term.ToString()}.childs [{childs.Length}]: {sw.Elapsed.TotalSeconds}");
                sw.Restart(); //!!!
                List <Word> parents = DB.GetParents(childs).Distinct().ToList();
                sw.Stop(); Debug.WriteLine($"Similars->{term.ToString()}.parents [{parents.Count}]: {sw.Elapsed.TotalSeconds}");
                sw.Restart(); //!!!
                List <Term> context = parents.Select(p => DB.ToTerm(p)).ToList();
                sw.Stop(); Debug.WriteLine($"Similars->{term.ToString()}.context [{context.Count}]: {sw.Elapsed.TotalSeconds}");
                //Поиск ближайшего родителя, т.е. родителя с максимумом сonfidence
                sw.Restart(); //!!!
                context.AsParallel().ForAll(p => p.confidence = Confidence.Compare(term, p));
                context.Sort(new Comparison <Term>((t1, t2) => Math.Sign(t2.confidence - t1.confidence)));
                result = context.Take(count).ToList();
            }
            return(result);
        }
Beispiel #2
0
        /// <summary>
        /// Метрика схожести зависящая от количества совпадающих эелементов вне зависимости от их порядка.
        /// Итоговое значение делится на длину слова b (отсюда в названии Right), т.о. метрика тем больше,
        /// чем короче слово b
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        private static float SoftOverlappingRight(DAL.Term a, DAL.Term b)
        {
            float count = a.Childs.Sum(c => b.Childs.Max(bc => Confidence.Compare(c, bc)));

            return(count / b.Count);
        }
Beispiel #3
0
        private static float SoftOverlappingLeft(int[] a, int[] b)
        {
            float count = a.Sum(c => b.Max(bc => Confidence.Compare(bc, c)));

            return(count / a.Length);
        }