我目前正在学习Go并且正在取得很大进展。我这样做的一种方法是将项目和原型从先前语言移植到新语言。
现在我正忙着用语言检测器"我不久前在Python中做了原型。在这个模块中,我生成一个ngram频率表,然后我计算给定文本和已知语料库之间的差异。
这允许通过返回给定ngram表的两个向量表示的余弦来有效地确定哪个语料库是最佳匹配。好极了。数学式
我有一个用Go编写的原型,它与普通的ascii字符完美配合,但我非常希望能够使用unicode多字节支持。这就是我正在努力的地方。
以下是我正在处理的问题的简短示例:http://play.golang.org/p/2bnAjZX3r0
我只发布了生成逻辑的表,因为一切都已经正常工作了。
正如您通过运行代码段所看到的那样,第一个文本可以很好地工作并构建一个准确的表格。第二个文本是德语,里面有几个双字节字符。由于我构建ngram序列的方式,并且由于这些特定符文由两个字节组成,因此出现了2个ngram,其中第一个字节被截断。
有人可能会发布更有效的解决方案,或者至少引导我解决问题吗?我几乎肯定我正在分析这个问题。
我计划开源这个软件包并使用Martini将其作为服务实现,从而提供一个简单的API,人们可以用它来进行简单的语言计算。
一如既往,谢谢!
答案 0 :(得分:1)
如果我理解正确,您希望chars
函数中的Parse
保留字符串中的最后n
个字符。由于您对Unicode字符而不是UTF-8表示感兴趣,因此您可能会发现将其作为[]rune
切片进行管理更容易,并且只有在准备好将ngram添加到字符串时才转换回字符串。表。这样,您的逻辑就不需要特殊情况下的非ASCII字符。
以下是对您执行上述操作的示例程序的简单修改:http://play.golang.org/p/QMYoSlaGSv
答案 1 :(得分:1)
通过保持符文的循环缓冲区,您可以最小化分配。另请注意,从映射中读取新键会返回零值(对于int为0),这意味着代码中的未知键检查是多余的。
func Parse(text string, n int) map[string]int {
chars := make([]rune, 2 * n)
table := make(map[string]int)
k := 0
for _, chars[k] = range strings.Join(strings.Fields(text), " ") + " " {
chars[n + k] = chars[k]
k = (k + 1) % n
table[string(chars[k:k+n])]++
}
return table
}