Алгоритм сортировки ключевых слов - PullRequest
3 голосов
/ 20 мая 2010

У меня более 1000 опросов, многие из которых содержат открытые ответы.

Я бы хотел иметь возможность «анализировать» все слова и получать ранжирование наиболее употребляемых слов (без учета общих слов), чтобы определить тенденцию.

Как я могу это сделать? Есть ли программа, которую я могу использовать?

РЕДАКТИРОВАТЬ Если стороннее решение недоступно, было бы здорово, если бы мы могли продолжить обсуждение только технологий Microsoft. Приветствия.

Ответы [ 4 ]

9 голосов
/ 20 мая 2010

Разделяй и властвуй. Разделите вашу проблему на множество мелких проблем и решите каждую из них.

Первая проблема: превратить абзац в список слов.

Вам повезло, потому что вам не нужно беспокоиться о том, чтобы быть совершенным. На самом деле синтаксический анализ естественных языков, чтобы точно определить, что такое «слово», может быть очень трудным, но, честно говоря, вам, вероятно, все равно, имеет ли «лампочка» ту же семантику, что и «лампочка». Так как вы, в частности, ищете общие слова (сейчас, об этом позже), именно те, которые легко идентифицировать, потому что они часто встречаются.

Итак, разбери эту проблему дальше. Вы хотите список слов. Начните с получения строки с текстом:

StreamReader streamReader = new StreamReader(@"c:\survey.txt");
string source = streamReader.ReadToEnd();

Отлично, у вас есть строка. Теперь превратите это в массив слов. Поскольку вы, вероятно, хотите считать слова «лягушка» и «лягушка» одним словом, сделайте все строчными. Как все это сделать? Разбить строчную строку на основе пробелов, переносов, знаков табуляции и пунктуации:

char[] punctuation = new char[] {' ', '\n', '\r', '\t', '(', ')', '"'};
string[] tokens = source.ToLower().Split(punctuation, true); 

Теперь рассмотрим вывод. Это было ужасно Мы забываем обо всем. Точки и запятые и двоеточия и точки с запятой и так далее. Выясните, какая пунктуация вас интересует, и добавьте ее в список.

Является ли ToLower правильным решением? Что насчет ToLowerInvariant? Есть моменты, когда вы хотите подчеркнуть это; это не один из них. Тот факт, что ToLower не обязательно канонизирует турецкую строчную букву I таким образом, что последовательные обходы, вряд ли отбросит вашу сводную статистику. Мы не собираемся здесь заострять точность. Если кто-то говорит «роскошная яхта», а кто-то говорит «роскошная яхта», первое может быть одним словом, если вы забудете разбить на дефисы. Какая разница? В любом случае, слова с переносами слов вряд ли будут в вашей первой десятке.

Следующая задача: подсчитать все вхождения каждого слова:

var firstPass = new Dictionary<string, int>();
foreach(string token in tokens)
{
    if (!firstPass.ContainsKey(token))
        firstPass[token] = 1;
    else
        ++firstPass[token];
} 

Отлично. Теперь у нас есть словарь, который отображает слова в целые числа. Проблема в том, что это задом наперед. То, что вы хотите знать, это то, что все слова имеют одинаковое количество вхождений. Словарь представляет собой последовательность пар ключ / значение, поэтому сгруппируйте его:

var groups = from pair in firstPass
             group pair.Key by pair.Value;

Хорошо, теперь у нас есть последовательность групп слов, каждая из которых связана со своим количеством появлений. Заказать. Помните, что ключом группы является значение словаря, количество:

var sorted = from group in groups
             orderby group.Key
             select group;

А вы хотите первую сотню, скажем:

foreach(var g in sorted.Take(100))
{
  Console.WriteLine("Words with count {0}:", g.Key);
  foreach(var w in g)
    Console.WriteLine(w);
}

И все готово.

Теперь, это действительно то, что вас интересует? Я думаю, что было бы более интересно искать необычные слова или пары слов. Если слова «яхта» и «гонки» появляются вместе много, не удивительно. Если «помидор» и «кетчуп» часто появляются вместе, неудивительно. Если «помидоры» и «гонки» начинают появляться вместе, то, возможно, происходит что-то примечательное.

Это требует гораздо более глубокого анализа; прочитайте теорему Байеса, если это то, что вас интересует.

Также обратите внимание, что при этом отслеживается необработанный счетчик слов, а не их частота - количество раз, которое они появляются на тысячу слов . Это также может быть интересной метрикой для измерения: не только сколько раз это слово появлялось, точка, но сколько раз оно появлялось в процентах от текста.

4 голосов
/ 20 мая 2010

NLTK содержит тонны полезных для работы с естественным языком.

Ознакомьтесь с этой статьей (по ссылке с сайта NLTK) для примера построения постоянного, доступного по сети распределения частот. Даже если это не совсем то, что вы ищете, это может помочь вам понять, как подойти к вашей проблеме.

UPDATE

Re: технологии MS, вы можете запускать NLTK в .NET, используя IronPython. См. этот связанный вопрос SO .

0 голосов
/ 21 мая 2010

Вы можете создать индекс текста lucene с пользовательским списком стоп-слов, который будет пропускать общие слова. Откройте индекс Lucene с помощью Luke, и он покажет вам главные термины в индексе.

При индексировании можно активировать основание, чтобы слова были сгруппированы в их корневую форму. Это поможет вам объединить разные формы одного и того же слова (множественное число, разные времена и т. Д.). То есть «вопрос, вопрос, вопрос» и т. Д. Будут отображаться как «вопрос». Это нельзя сделать ни одним другим методом.

0 голосов
/ 20 мая 2010

SharpNLP - это нативная библиотека .NET для выполнения НЛП. Я не знаю, как это соотносится с NLTK, так как я никогда не слышал об этом, пока не начал гуглить.

...