微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 关键字排序算法

我有超过1000个调查,其中许多包含开放式回复.

我希望能够“解析”所有单词并获得最常用单词的排名(忽略常用单词)以发现趋势.

我怎样才能做到这一点?我有可以使用的程序吗?

编辑如果没有第三方解决方案,如果我们只能继续讨论微软技术,那就太棒了.干杯.

解决方法

分而治之.将您的问题分解为许多小问题并解决每个问题.

一个问题:将一个段落变成一个单词列表.

你很幸运,因为你不必担心完美.实际上解析自然语言以确定“一个单词”究竟是什么可能非常困难,但坦率地说,你可能并不关心“灯泡”是否具有与“灯泡”相同的语义.因为你特别想要寻找常用词(现在,稍后会更多),有趣的词恰好是那些容易识别的词,因为它们出现了很多.

所以,进一步打破这个问题.你想要一个单词列表.首先获取包含文本的字符串:

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

太棒了,你有一个字符串.现在把它变成一个单词数组.因为你可能想把“Frog”和“frog”算作同一个单词,所以要把所有东西都小写.怎么做那一切?根据空格,换行符,制表符和标点符号拆分小写字符串:

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);
}

而且你已经完成了.

现在,这真的是你感兴趣的吗?我认为寻找不寻常的单词或单词对可能更有趣.如果“游艇”和“赛车”这两个词汇出现在一起很多,那并不奇怪.如果“番茄”和“番茄酱”在一起出现很多,那就不足为奇了.如果“番茄”和“赛车”开始一起出现,那么可能会有一些值得注意的事情发生.

这需要更深入的分析;阅读贝叶斯定理,如果这是你感兴趣的那种东西.

另请注意,这会跟踪单词的原始计数,而不是它们的频率 – 它们出现在每千个单词中的次数.这可能也是一个有趣的衡量指标:不仅仅是这个词出现了多少次,一段时间,而是它显示为文本百分比的次数.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐