基本上我有一个字典,其中包含我的词汇表中的所有单词作为键,并且所有单词都以0作为值。
要将文档处理成一个单词表示,我用相应的IEqualityComparer复制该字典,然后检查字典是否包含文档中的每个单词并增加它的密钥。
要获得单词表示的数组,我只需使用ToArray方法。
这似乎工作正常,但我只是被告知字典不能保证相同的键顺序,因此结果数组可能代表不同顺序的单词,使其无用。
我目前解决此问题的想法是将单词字典的所有键复制到ArrayList中,创建适当大小的数组,然后使用数组列表的indexOf方法填充数组。
所以我的问题是,有没有更好的方法来解决这个问题,我看起来有点粗糙......而且由于IEqualityComparer,我不会有问题吗?
答案 0 :(得分:4)
让我看看我是否理解这个问题。您有两个文档D1和D2,每个文档包含从已知词汇表{W1,W2 ... Wn}中提取的单词序列。您希望获得两个映射,指示每个文档中每个单词的出现次数。所以对于D1,你可能有
W1 --> 0
W2 --> 1
W3 --> 4
表示D1可能是“W3 W2 W3 W3 W3”。也许D2是“W2 W1 W2”,所以它的映射是
W1 --> 1
W2 --> 2
W3 --> 0
您希望同时采用两个映射并确定向量[0,1,4]和[1,2,0],然后计算这些向量之间的角度,以确定两个文档的相似或不同。
您的问题是字典不保证以任何特定顺序枚举键/值对。
好的,所以订购它们。
vector1 = (from pair in map1 orderby pair.Key select pair.Value).ToArray();
vector2 = (from pair in map2 orderby pair.Key select pair.Value).ToArray();
你已经完成了。
这会解决您的问题,还是我误解了这种情况?
答案 1 :(得分:2)
如果我理解正确,您希望按字频拆分文档。
您可以获取文档并在其上运行正则表达式以拆分单词:
var words=Regex
.Matches(input,@"\w+")
.Cast<Match>()
.Where(m=>m.Success)
.Select(m=>m.Value);
制作频率图:
var map=words.GroupBy(w=>w).Select(g=>new{word=g.Key,freqency=g.Count()});
如果这很重要,GroupBy方法有一些重载允许你提供另一个IEqualityComparer。
阅读您的评论,创建相应的频率序列:
map.Select(a=>a.frequency)
此序列的顺序与上面的序列map
完全相同。
这有什么帮助吗?
答案 2 :(得分:1)
表示键/值的集合 密钥可访问的对 或指数。
答案 3 :(得分:0)
这样的东西可能会起作用,虽然它绝对是丑陋的,我相信它与你的建议相似。 GetWordCount()完成工作。
类WordCounter {
public Dictionary dictionary = new Dictionary();
public void CountWords(string text) { if (text != null && text != string.Empty) { text = text.ToLower(); string[] words = text.Split(' '); if (dictionary.ContainsKey(words[0])) { if (text.Length > words[0].Length) { text = text.Substring(words[0].Length + 1); CountWords(text); } } else { int count = words.Count( delegate(string s) { if (s == words[0]) { return true; } else { return false; } }); dictionary.Add(words[0], count); if (text.Length > words[0].Length) { text = text.Substring(words[0].Length + 1); CountWords(text); } } } } public int[] GetWordCount(string text) { CountWords(text); return dictionary.Values.ToArray<int>(); } }
答案 4 :(得分:0)
这会对您有所帮助:
SortedDictionary<string, int> dic = new SortedDictionary<string, int>();
for (int i = 0; i < 10; i++)
{
if (dic.ContainsKey("Word" + i))
dic["Word" + i]++;
else
dic.Add("Word" + i, 0);
}
//to get the array of words:
List<string> wordsList = new List<string>(dic.Keys);
string[] wordsArr = wordsList.ToArray();
//to get the array of values
List<int> valuesList = new List<int>(dic.Values);
int[] valuesArr = valuesList.ToArray();
答案 5 :(得分:0)
如果您要做的只是计算余弦相似度,则无需将数据转换为20,000个长度的数组,尤其是考虑到数据可能很稀疏,大多数条目为零。
处理文件时,将文件输出数据存储到键入字词的字典中。然后计算点积和幅度,迭代完整单词列表中的单词,在每个文件ouptut数据中查找单词,如果存在则使用找到的值,如果不存在,则使用零。