编辑:此代码已作为基本模块进行开发和发布:https://github.com/hyperreality/Poetry-Tools
我是一个语言学家,最近学过python,我正在做一个项目,希望能自动分析诗歌,包括检测诗歌的形式。也就是说,如果它发现一条10音节的线有0101010101的应力模式,它会声明它是抑扬格五步音阶。一首5-7-5音节的诗就是俳句。
我正在使用以下代码,这是较大脚本的一部分,但我有许多问题,这些问题列在程序下面:
脚本中的语料库只是诗的原始文本输入。

import sys, getopt, nltk, re, string
from nltk.tokenize import RegexpTokenizer
from nltk.util import bigrams, trigrams
from nltk.corpus import cmudict
from curses.ascii import isdigit

...

def cmuform():
    tokens = [word for sent in nltk.sent_tokenize(corpus) for word in nltk.word_tokenize(sent)]
    d = cmudict.dict()
    text = nltk.Text(tokens)
    words = [w.lower() for w in text]
    regexp = "[A-Za-z]+"
    exp = re.compile(regexp)

    def nsyl(word):
        lowercase = word.lower()
        if lowercase not in d:
                return 0
        else:
            first = [' '.join([str(c) for c in lst]) for lst in max(d[lowercase])]
            second = ''.join(first)
            third = ''.join([i for i in second if i.isdigit()]).replace('2', '1')
            return third
                #return max([len([y for y in x if isdigit(y[-1])]) for x in d[lowercase]])

    sum1 = 0
    for a in words:
            if exp.match(a):
            print a,nsyl(a),
                sum1 = sum1 + len(str(nsyl(a)))

    print "\nTotal syllables:",sum1

我想我想要的输出应该是这样的:
1101111101号
0101111001号
110101011号
第一个问题是我在标记化技术中丢失了换行符,我真的需要换行符来识别表单。不过,这不应该太难处理。更大的问题是:
我不能处理非字典词汇。目前我为他们返回0,但这将混淆任何识别这首诗的尝试,因为这行的音节计数可能会减少。
此外,CMU字典经常说,当单词“1”没有“0”时,单词“1”就有重音。这就是为什么输出看起来是这样的:1101111101,当它应该是抑扬格五分之一的应力时:0101010101
那么,我该如何添加一些敷衍的因素,使这首诗仍然被认为是抑扬格五步诗时,它只是近似的模式?当CMU字典不能输出如此干净的结果时,对标识01行的函数进行编码是不好的。我想我在问如何编写“部分匹配”算法。

最佳答案

欢迎使用堆栈溢出。我对python不太熟悉,但我发现您还没有收到很多答案,所以我将尝试帮助您处理查询。
首先,你会发现,如果你专注于你的问题,你得到答案的机会会大大提高。你的帖子太长了,包含了几个不同的问题,所以它超出了大多数回答问题的人的“关注范围”。
回到主题:
在你修改你的问题之前,你问如何使它不那么凌乱。这是一个大问题,但您可能希望使用自顶向下的过程方法,并将代码分解为功能单元:
将语料库拆分为行
每行:找出音节长度和重音模式。
分类压力模式。
您会发现第一步是在python中调用单个函数:

corpus.split("\n");

并且可以保留在主函数中,但是第二步将更好地放置在它自己的函数中,第三步将需要拆分自身,并且可能更好地使用面向对象的方法来处理。如果你在学院,你可能会说服CS的老师借给你几个月的研究生,并帮助你而不是一些车间的要求。
现在请回答其他问题:
不要丢失换行符:正如@ykaganovich所提到的,您可能希望将语料库拆分为行,并将它们提供给标记器。
字典中没有的单词/错误:单词CMU dictionary home page表示:
查找错误?请联系开发者。我们将研究这个问题并改进字典。(有关联系信息,请参见底部。)
可能有一种方法可以将自定义单词添加到词典/更改现有单词、在其网站中查找或直接与词典维护人员联系。
如果你不明白的话,你也可以在这里单独问一个问题。StackOverflow中一定有人知道答案或者可以指向正确的资源。
不管你决定什么,你都要联系维护人员,给他们提供任何额外的单词和更正,以改进字典。
当输入语料库与模式不完全匹配时对其进行分类:您可能希望查看为模糊字符串比较提供的链接ykaganovich。要查找的一些算法:
Levenshtein Distance:提供两个字符串的不同程度的度量,作为将一个字符串转换为另一个字符串所需的更改数。优点:易于实现,缺点:不规范,2分表示长度为20的模式匹配良好,而长度为3的模式匹配不良。
JaroWinkler字符串相似性度量:类似于Levenshtein,但基于两个字符串中以相同顺序出现的字符序列数。虽然实现起来有点困难,但它提供了规范化的值(0.0-完全不同,1.0-相同),并且适合于对应力模式进行分类。一个CS研究生或者去年的本科生不应该有太多的麻烦(提示提示)。
我想这些都是你的问题。希望这有点帮助。

关于python - 用NLTK和CMU Dict发现诗歌形式,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19015590/

10-12 16:24