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

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

4

6 回答 6

20

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

合并任务

首先,OP 将形态分析、分割和标记化的任务混为一谈。通常有一个很好的区别,特别是对于像土耳其语/马拉雅拉姆语这样的粘着性语言(参见http://en.wikipedia.org/wiki/Agglutinative_language)。

凝集 NLP 和最佳实践

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

词边界

标记化被定义为从表面文本中识别具有语言意义的单元 (LMU)(请参阅为什么我需要为每种语言使用标记器?)并且不同的语言将需要不同的标记器来识别不同语言的单词边界。不同的人有不同的方法来寻找不同的词边界,但总的来说,在 NLP 中人们已经订阅了以下内容:

  1. 凝集语言需要使用某种语言模型训练的完整形态分析器。在识别什么是词素级别时通常只有一个层次,token因此 NLP 社区为他们各自的词素分析工具开发了不同的语言模型。

  2. 具有指定单词边界的多合成语言可以选择两层tokenization,其中系统可以首先识别一个孤立的单词,然后在必要时进行形态分析以获得更细粒度的标记。粗粒度标记器可以使用某些分隔符(例如 NLTKword_tokenizepunct_tokenize使用空格/标点符号表示英语)拆分字符串。然后为了在词素级别进行更细粒度的分析,人们通常会使用一些有限状态机将单词分成词素(例如在德语中http://canoo.net/services/WordformationRules/Derivation/To-N/N-To-N /前+后缀.html )

  3. 没有指定单词边界的多合成语言通常需要首先在标记之间添加空格,因为正字法不区分单词边界(例如中文https://code.google.com/p/mini-segmenter/)。然后从分隔的标记中,如有必要,可以进行词素分析以产生更细粒度的标记(例如http://mecab.googlecode.com/svn/trunk/mecab/doc/index.html)。通常,这种更精细的令牌与 POS 标签相关联。

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

  • 要输出tokens马拉雅拉姆语,形态分析器是必要的,NLTK 中的简单粗粒度标记器不起作用。
  • NLTK 的分词器旨在对具有指定单词边界的多合成语言(例如英语/欧洲语言)进行分词,因此并不是分词器不适用于马拉雅拉姆语,它只是不打算对凝聚性语言进行分词。
  • 为了实现输出,需要为该语言构建一个完整的形态分析器,并且有人已经构建了它(aclweb.org/anthology//O/O12/O12-1028.pdf‎),OP 应该联系作者如果他/她对该工具感兴趣,请提交论文。
  • 除了使用语言模型构建形态分析器之外,我鼓励 OP 首先找出将单词拆分为语言中的语素的常见分隔符,然后执行简单re.split()的操作以实现基线标记器。
于 2013-10-30T12:36:06.063 回答
4

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

所以 NLTK 没有提供任何检测马拉雅拉姆语单词边界的东西。不过,它可能会提供相当容易构建体面的工具。

显而易见的方法是尝试字典查找:尝试将输入分解为字典中的字符串。但这比听起来要难:您需要一个非常大的字典,您仍然必须以某种方式处理未知单词,并且由于马拉雅拉姆语具有非平凡的形态,您可能需要一个形态分析器来匹配屈折词词典。假设您可以使用字典存储或生成每个单词形式,您可以使用此处描述的算法(@amp 已经提到)将输入划分为单词序列。

更好的选择是使用可以猜测单词边界位置的统计算法。我不知道 NLTK 中有这样的模块,但在这方面已经为中文做了很多工作。如果值得你费心,你可以找到一个合适的算法并训练它在马拉雅拉姆语上工作。

简而言之:NLTK 分词器仅适用于英语的印刷风格。您可以训练一个合适的工具来处理马拉雅拉姆语,但据我所知,NLTK 不包括这样的工具。

PS。NLTK 确实带有几个统计标记化工具;PunctSentenceTokenizer可以使用无监督学习算法进行训练以识别句子边界(这意味着您不需要在训练数据中标记边界)。不幸的是,该算法专门针对缩写问题,因此不能适用于单词边界检测。

于 2013-10-27T23:29:05.527 回答
3

也许维特比算法可以帮助?

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

于 2013-10-26T16:24:39.447 回答
3

看来您的空间是 unicode character u'\u0d41'。所以你应该用str.split().

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

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

[出去]:

ഇത ഒര സ്ഥാലമാണ്`
于 2013-10-28T17:24:53.623 回答
1

我尝试了以下方法:

# encoding=utf-8

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

作为输出,我得到以下信息:

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

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

于 2013-10-26T04:46:47.057 回答
0

形态分析示例

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

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

网址:mlmorph

如果你使用anaconda那么: 在 anaconda 提示符下安装 git

conda install -c anaconda git

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

git clone https://gitlab.com/smc/mlmorph.git
于 2019-04-08T09:51:17.630 回答