Python - 字母频率统计与翻译

7 投票
4 回答
3535 浏览
提问于 2025-04-15 19:05

我现在用的是Python 3.1,不过如果需要的话我可以降级。

我有一个ASCII文件,里面有一个短故事,这个故事是用一种字母表可以用大写或小写ASCII表示的语言写的。我想要:

1) 尽量检测出文件的编码,并得到一些信心指标(这个指标会根据文件的长度而变化,对吧?)

2) 自动翻译整个内容,使用一些免费的在线服务或者库。

另外一个问题是:如果文本是用一种需要两个或更多字节来表示一个字母的语言写的,而字节顺序标记又没有帮助我该怎么办?

最后,我该如何处理标点符号和其他字符,比如空格?这些字符出现的频率会比某些字母高,对吧?还有,标点符号和字符有时会混在一起,比如可能有两种表示逗号的方式,或者看起来像“a”的字符也可能有两种表示方式等等。

是的,我看过Joel Spolsky关于Unicode的文章。请帮我解决至少其中的一些问题。

谢谢!

附言:这不是作业,而是为了自我学习。我更喜欢使用一个开源且易于阅读的字母频率库,而不是一个封闭的、效率高但难以理解的库。

4 个回答

2

如果你有一个ASCII文件,我可以百分之百确定它是用ASCII编码的。除此之外,你可以试试chardet这个工具。不过,仅仅知道编码并不一定能告诉你它是什么语言。

至于多字节编码,处理它的唯一可靠方法就是希望里面有拉丁字母的字符,然后看看哪一对字符中有NULL。否则就当它是UTF-8,除非你知道其他的编码(比如Shift-JIS、GB2312等)。

哦,还有UTF-8。UTF-8,UTF-8,UTF-8。我觉得我说得还不够多。如果我还没说清楚……就是UTF-8。

2

字符频率的计算其实很简单

我刚注意到你在用Python3.1,这样做起来更容易了

>>> from collections import Counter
>>> Counter("Μεταλλικα")
Counter({'α': 2, 'λ': 2, 'τ': 1, 'ε': 1, 'ι': 1, 'κ': 1, 'Μ': 1})

对于旧版本的Python:

>>> from collections import defaultdict
>>> letter_freq=defaultdict(int)
>>> unistring = "Μεταλλικα"
>>> for uc in unistring: letter_freq[uc]+=1
... 
>>> letter_freq
defaultdict(<class 'int'>, {'τ': 1, 'α': 2, 'ε': 1, 'ι': 1, 'λ': 2, 'κ': 1, 'Μ': 1})
3

基本上,要实现这个应用程序,有三个主要任务:

  • 1a) 确定输入文本的字符编码
  • 1b) 确定输入文本的语言
  • 2) 通过某个在线服务的API将文本翻译

对于1a,你可以看看 decodeh.py,除了这个脚本本身,它还提供了很多关于字符集和编码的有用资源。还有CharDet,在其他回答中提到的,也值得考虑。

一旦知道了字符编码,正如你所建议的,可以通过计算文本的字符频率来解决1b),然后将其与已知的频率进行匹配。虽然这个方法简单,但通常能提供不错的准确率,不过在短文本或特定模式的文本上可能效果不佳;比如说,一段提到公制单位的法语文本,字母M、K和C的比例会异常高。

另一种类似的方法是使用二元组(两个字母的组合)和三元组(三个字母的组合),以及不同语言的频率分布参考表。

其他语言检测方法涉及对文本进行分词,也就是考虑文本中的单词。自然语言处理(NLP)资源包括各种语言中使用频率最高的单词表。这些单词通常是冠词、物主形容词、副词等。

另一种语言检测的解决方案是依赖在线翻译服务来帮我们搞定。重要的是要给翻译服务提供它能理解的字符编码,提供语言信息可能是多余的。

最后,像许多实际的自然语言处理应用一样,你可以选择实现多种解决方案。通过使用策略设计模式,可以按特定顺序应用多个过滤器/分类器/步骤,并根据情况在不同的点退出这个逻辑。例如,如果简单的字符/二元组频率将文本匹配到英语(有小偏差),那么可以就此停止。否则,如果猜测的语言是法语或德语,就进行另一个测试,等等。

撰写回答