如何标记马拉雅拉姆语?

时间:2013-10-22 10:42:22

标签: python unicode nltk

ഇതുഒരുസ്ടലംമാണ്  

itu oru stalam anu

这是一个Unicode字符串,意思是这是一个地方

import nltk
nltk.wordpunct_tokenize('ഇതുഒരുസ്ഥാലമാണ് '.decode('utf8'))

不适合我。

nltk.word_tokenize('ഇതുഒരുസ്ഥാലമാണ് '.decode('utf8'))

也不起作用 其他例子

"കണ്ടില്ല "  = കണ്ടു +ഇല്ല,
"വലിയൊരു"  = വലിയ + ഒരു

右分裂:

ഇത്  ഒരു സ്ഥാലം ആണ് 

输出:

[u'\u0d07\u0d24\u0d4d\u0d12\u0d30\u0d41\u0d38\u0d4d\u0d25\u0d32\u0d02\u0d06\u0d23\u0d4d']

我只需要拆分单词,如另一个例子中所示。其他示例部分用于测试。问题不在于Unicode。它具有语言形态。为此,您需要使用形态分析仪
看看这篇论文。 http://link.springer.com/chapter/10.1007%2F978-3-642-27872-3_38

6 个答案:

答案 0 :(得分:19)

在维基百科(http://en.wikipedia.org/wiki/Malayalam)的语言速成课程之后,您的问题中存在一些问题以及您为所需输出请求的工具。

配置任务

首先,OP将形态分析,分割和标记化的任务混为一谈。通常对土耳其语/马拉雅拉姆语等集体语言有很好的区别(见http://en.wikipedia.org/wiki/Agglutinative_language)。

Agglutinative NLP和最佳做法

接下来,我认为tokenizer不适用于马拉雅拉姆语,这是一种凝聚性语言。作为NLP中研究最多的集体语言之一,土耳其人在“标记化”方面采用了不同的策略,他们发现需要一个完整的形态分析器(见http://www.denizyuret.com/2006/11/turkish-resources.html,www.andrew.cmu.edu /用户/ KO /下载/ lrec.pdf)。

Word Boundaries

标记化被定义为从表面文本中识别出语义上有意义的单位(LMU)(参见Why do I need a tokenizer for each language?)并且不同的语言需要不同的标记化器来识别不同语言的单词边界。不同的人已经找到了解决单词边界不同的问题但总结在NLP中,人们订阅了以下内容:

  1. Agglutinative Languages 需要使用某种语言模型训练的完整形态分析器。在确定什么是token时,通常只有一层,而且在语素层面,因此NLP社区为各自的形态分析工具开发了不同的语言模型。

  2. 具有指定字边界的Polysynthetic语言可以选择两层tokenization,系统可以先识别出一个孤立的单词,然后必要时进行形态分析获得更精细的谷物代币。粗粒度标记器可以使用某个分隔符(例如NLTK的word_tokenizepunct_tokenize使用空格/标点符号来分割字符串)。然后,对于语素水平的细粒度分析,人们通常会使用一些有限状态机将单词分成语素(例如德语http://canoo.net/services/WordformationRules/Derivation/To-N/N-To-N/Pre+Suffig.html

  3. 没有指定单词边界的Polysynthetic Langauges 通常需要分段器首先在标记之间添加空格,因为正字法不区分单词边界(例如在中文https://code.google.com/p/mini-segmenter/中)。然后,如果需要,可以从定界标记进行语素分析以产生更精细的谷物标记(例如http://mecab.googlecode.com/svn/trunk/mecab/doc/index.html)。通常,这种更精细的谷物代币与POS标签捆绑在一起。

  4. 对于OP的请求/问题的简要回答,OP使用了错误的工具来完成任务

    • 要为马拉雅拉姆输出tokens,必须使用形态分析器,NLTK中的简单粗粒度标记器不起作用。
    • NLTK的标记化程序用于使用指定的单词边界(例如英语/欧洲语言)对多语言语言进行标记,因此并不是标记化器不适用于马拉雅拉姆语,它并不意味着标记化的集合语言。
    • 为了实现输出,需要为语言构建一个完整的形态分析器,并且有人建立了它(aclweb.org/anthology//O/O12/O12-1028.pdf),OP应该联系该论文的作者,如果他/她对该工具感兴趣。
    • 如果没有使用语言模型构建形态分析器,我鼓励OP首先找到将语言分割为语言语素的常用分隔符,然后执行简单的re.split()以实现基线标记化。

答案 1 :(得分:4)

标记器确实是正确的工具;当然这就是NLTK所称的。形态分析器(如您链接的文章中所述)用于将单词分解为较小的部分(语素)。但是在您的示例代码中,您尝试使用适合英语的标记器:它识别空格分隔的单词和标点符号。由于马拉雅拉姆显然没有用空格或其他任何东西来表示单词边界,所以你需要一种不同的方法。

因此,NLTK没有为马拉雅拉姆提供任何检测词边界的东西。不过,它可能提供了很容易构建一个体面的工具。

显而易见的方法是尝试字典查找:尝试将输入分解为字典中的字符串。但它会比听起来更难:你需要一个非常大字典,你仍然需要以某种方式处理未知单词,而且由于马拉雅拉姆语具有非平凡的形态,你可能需要一个形态分析器将变形的单词与字典进行匹配。假设您可以使用字典存储或生成每个单词表单,您可以使用类似于here(已经由@amp提及)的算法将输入划分为一系列单词。

更好的选择是使用可以猜测单词边界位置的统计算法。我不知道NLTK中有这样一个模块,但对中文有相当多的工作。如果它值得你的麻烦,你可以找到一个合适的算法,并训练它在马拉雅拉姆语。

简而言之:NLTK标记器仅适用于英文的排版风格。你可以训练一个合适的工具来使用马拉雅拉姆语,但据我所知,NLTK不包括这样的工具。

PS。 NLTK确实带有几种统计标记化工具;可以训练PunctSentenceTokenizer使用无监督学习算法识别句子边界(意味着您不需要在训练数据中标记边界)。遗憾的是,the algorithm专门针对缩写问题,因此无法适应字边界检测。

答案 2 :(得分:3)

也许Viterbi algorithm可以提供帮助吗?

对另一个SO问题(以及另一个高投票答案)的回答可能会有所帮助:https://stackoverflow.com/a/481773/583834

答案 3 :(得分:3)

您的空间似乎是unicode字符u'\u0d41'。因此,您应该使用str.split()正常拆分。

import sys
reload(sys)
sys.setdefaultencoding("utf-8")

x = 'ഇതുഒരുസ്ഥാലമാണ്'.decode('utf8')
y = x.split(u'\u0d41')
print " ".join(y)

[OUT]:

ഇത ഒര സ്ഥാലമാണ്`

答案 4 :(得分:1)

我尝试了以下内容:

# encoding=utf-8

import nltk
cheese = nltk.wordpunct_tokenize('ഇതുഒരുസ്ഥാലമാണ്'.decode('utf8'))
for var in cheese:
    print var.encode('utf8'),

作为输出,我得到以下内容:

ഇത ു ഒര ു സ ് ഥ ാ ലമ ാ ണ ്

这是否与您想要的输出接近,我在这里有点黑暗,因为如果不理解语言就很难做到这一点。

答案 5 :(得分:0)

形态分析示例

from mlmorph import Analyser
analyser = Analyser()
analyser.analyse("കേരളത്തിന്റെ")

给予

[('കേരളം<np><genitive>', 179)]

url:mlmorph

如果您使用 anaconda ,则: 在anaconda提示符下安装git

conda install -c anaconda git

然后使用以下命令克隆文件

git clone https://gitlab.com/smc/mlmorph.git