我希望能够“解析”所有单词并获得最常用单词的排名(忽略常用单词)以发现趋势.
我怎样才能做到这一点?我有可以使用的程序吗?
编辑如果没有第三方解决方案,如果我们只能继续讨论微软技术,那就太棒了.干杯.
解决方法
你很幸运,因为你不必担心完美.实际上解析自然语言以确定“一个单词”究竟是什么可能非常困难,但坦率地说,你可能并不关心“灯泡”是否具有与“灯泡”相同的语义.因为你特别想要寻找常用词(现在,稍后会更多),有趣的词恰好是那些容易识别的词,因为它们出现了很多.
所以,进一步打破这个问题.你想要一个单词列表.首先获取包含文本的字符串:
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 举报,一经查实,本站将立刻删除。