Example #1
0
        public List <Cluster> Clustering(List <SimilarityRow> rows, int threshold)
        {
            if (threshold == 0)
            {
                threshold = THRESHOLD;
            }

            List <Cluster> clusters = new List <Cluster>();
            int            size     = rows.Count();

            //пока есть нераспределенные документы
            while (size > 0)
            {
                //ищем строку с максимальной суммой
                int           maxSumSimilarity = rows.Max(y => y.GetSumSimilarity());
                SimilarityRow maxRow           = rows.Find(x => x.GetSumSimilarity() == maxSumSimilarity);

                Cluster cluster = new Cluster();
                foreach (var entry in maxRow.Similarity)
                {
                    //если коэффициент схожести больше заданного порогового значения - добавляем документ в кластер
                    if (entry.Value >= threshold)
                    {
                        cluster.Docs.Add(entry.Key);
                    }
                }

                //кластер не пустой
                if (cluster.Docs.Count != 0)
                {
                    clusters.Add(cluster);
                }

                //удаляем документы, которые попали в кластер
                DeleteRows(rows, cluster.Docs);

                size = rows.Count();
            }

            return(clusters);
        }
Example #2
0
        public List <SimilarityRow> MakeSimilarityRows(List <Doc> docs, int termCount)
        {
            var rows = new List <SimilarityRow>();

            if (termCount == 0)
            {
                termCount = TERM_COUNT;
            }
            //получим список термов для каждого документа
            var doc2Terms      = GetDocumentShingle(docs, termCount);
            var doc2Similarity = new Dictionary <string, int>();
            //на случай, если ключевых слов меньше, чем задано
            var minSize = doc2Terms.Values.Min(x => x.Count);

            //if (minSize < termCount)
            //{
            //    termCount = minSize;
            //    foreach (var e in doc2Terms)
            //    {
            //        List<String> lst = e.Value;
            //        if (lst.Count() > termCount)
            //        {
            //            lst = lst.GetRange(0, termCount);
            //            doc2Terms.Add(e.Key, lst);
            //        }
            //    }
            //}
            for (var i = 0; i < docs.Count(); i++)
            {
                var doc = docs[i];
                var row = new SimilarityRow();
                row.Doc = doc;
                //список термов для данного документа
                var terms = doc2Terms[row.Doc.DocIndex];
                var arrX  = Initionalize(termCount);
                //сравнение с другими документами
                for (var j = 0; j < docs.Count(); j++)
                {
                    //ид документа
                    var doc2 = docs[j];
                    //набор термов для документа, с которым сравниваем
                    var terms2 = doc2Terms[doc2.DocIndex];
                    //схожесть одинаковых документов можно не считать. всегда = 100
                    if (row.Doc.Equals(doc2))
                    {
                        //сам с собой можно не считать. всегда 100
                        row.Similarity.Add(doc2, 100);
                        continue;
                    }

                    //уже считали раньше
                    if (doc2Similarity.ContainsKey(GetUniqueKey(i, j)))
                    {
                        row.Similarity.Add(doc2, doc2Similarity[GetUniqueKey(i, j)]);
                        continue;
                    }

                    var arrY = new int[termCount];
                    //если i-е слово из N - списка присутствует в документе,
                    //то значением i - го элемента образа документа считается 1, в противном случае — 0.
                    foreach (var term in terms)
                    {
                        arrY[terms.IndexOf(term)] = terms2.Contains(term) ? 1 : 0;
                    }
                    if (arrY.Length < termCount)
                    {
                        for (var k = arrY.Length; k < termCount; k++)
                        {
                            arrY[k] = 0;
                        }
                    }
                    //считаем коэффициент схожести
                    var coeff = GetSimilarityCoefficient(arrX, arrY);
                    //добавляем в матрицу
                    row.Similarity.Add(doc2, coeff);
                    doc2Similarity.Add(GetUniqueKey(i, j), coeff);
                }

                rows.Add(row);
            }

            return(rows);
        }
Example #3
0
        public List <SimilarityRow> MakeSimilarityRows(List <Doc> docs, int shingleLength)
        {
            var rows = new List <SimilarityRow>();

            //получим список шинглов для каждого документа
            var doc2Terms      = GetDocumentShingle(docs, shingleLength);
            var doc2similarity = new Dictionary <string, int>();

            for (var i = 0; i < docs.Count(); i++)
            {
                var doc = docs[i];
                var row = new SimilarityRow
                {
                    Doc = doc
                };
                //список шинглов для данного документа
                var shingles1 = doc2Terms[row.Doc.DocIndex];

                //сравнение с другими документами
                for (var j = 0; j < docs.Count(); j++)
                {
                    //ид документа
                    var doc2 = docs[j];

                    if (!row.Similarity.ContainsKey(doc2))
                    {
                        //схожесть одинаковых документов можно не считать. всегда = 100
                        if (row.Doc.Equals(doc2))
                        {
                            //сам с собой можно не считать. всегда 100
                            row.Similarity.Add(doc2, 100);
                            continue;
                        }

                        //уже считали раньше
                        if (doc2similarity.ContainsKey(GetUniqueKey(i, j)))
                        {
                            row.Similarity.Add(doc2, doc2similarity[GetUniqueKey(i, j)]);
                            continue;
                        }

                        //набор шинглов для документа, с которым сравниваем
                        var shingles2 = doc2Terms[doc2.DocIndex];
                        var same      = 0;
                        for (var k = 0; k < shingles1.Count(); k++)
                        {
                            for (var l = 0; l < shingles2.Count(); l++)
                            {
                                if (shingles1[k].Equals(shingles2[l]))
                                {
                                    same++;
                                }
                            }
                        }
                        double s     = same * 2;
                        double count = shingles1.Count() + shingles2.Count();
                        var    res   = s / count;
                        var    coeff = (int)Math.Round(res * 100);
                        //добавляем в матрицу
                        doc2similarity.Add(GetUniqueKey(i, j), coeff);

                        row.Similarity.Add(doc2, coeff);
                    }
                }

                rows.Add(row);
            }

            return(rows);
        }