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); } 而且你已经完成了. 现在,这真的是你感兴趣的吗?我认为寻找不寻常的单词或单词对可能更有趣.如果“游艇”和“赛车”这两个词汇出现在一起很多,那并不奇怪.如果“番茄”和“番茄酱”在一起出现很多,那就不足为奇了.如果“番茄”和“赛车”开始一起出现,那么可能会有一些值得注意的事情发生. 这需要更深入的分析;阅读贝叶斯定理,如果这是你感兴趣的那种东西. 另请注意,这会跟踪单词的原始计数,而不是它们的频率 – 它们出现在每千个单词中的次数.这可能也是一个有趣的衡量指标:不仅仅是这个词出现了多少次,一段时间,而是它显示为文本百分比的次数. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |