Ruby,Count音节

时间:2009-08-13 13:23:41

标签: ruby nlp

我正在使用ruby来计算我拥有的某些内容的Gunning Fog Index,我可以成功实现此处描述的算法:

Gunning Fog Index

我使用以下方法计算每个单词中的音节数:

Tokenizer = /([aeiouy]{1,3})/

def count_syllables(word)

  len = 0

  if word[-3..-1] == 'ing' then
    len += 1
    word = word[0...-3]
  end

  got = word.scan(Tokenizer)
  len += got.size()

  if got.size() > 1 and got[-1] == ['e'] and
      word[-1].chr() == 'e' and
      word[-2].chr() != 'l' then
    len -= 1
  end

  return len

end

它有时会只用2个音节来获取有3个音节的单词。任何人都可以提出任何建议或意识到更好的方法吗?

text = "The word logorrhoea is often used pejoratively to describe prose that is highly abstract and contains little concrete language. Since abstract writing is hard to visualize, it often seems as though it makes no sense and all the words are excessive. Writers in academic fields that concern themselves mostly with the abstract, such as philosophy and especially postmodernism, often fail to include extensive concrete examples of their ideas, and so a superficial examination of their work might lead one to believe that it is all nonsense."

# used to get rid of any puncuation
text = text.gsub!(/\W+/, ' ')

word_array = text.split(' ')

word_array.each do |word|
    puts word if count_syllables(word) > 2
end

“他们自己”被计为3,但只有2

4 个答案:

答案 0 :(得分:11)

我之前提供的功能基于here概述的这些简单规则:

  

a中的每个元音(a,e,i,o,u,y)   单词算作一个音节   以下子规则:

     
      
  • 忽略最终-ES,-ED,-E(除了   for -LE)
  •   
  • 三个字母的单词或   少计算为一个音节
  •   
  • 连续元音算作一个   音节。
  •   

以下是代码:

def new_count(word)
  word.downcase!
  return 1 if word.length <= 3
  word.sub!(/(?:[^laeiouy]es|ed|[^laeiouy]e)$/, '')
  word.sub!(/^y/, '')
  word.scan(/[aeiouy]{1,2}/).size
end

显然,这也不完美,但你所能得到的东西都是启发式的。

编辑:

我稍微更改了代码以处理前导'y'并修复了正则表达式以更好地处理'les'结尾(例如“蜡烛”)。

以下是使用问题中的文字进行的比较:

# used to get rid of any puncuation
text = text.gsub!(/\W+/, ' ')

words = text.split(' ')

words.each do |word|
  old = count_syllables(word.dup)
  new = new_count(word.dup)
  puts "#{word}: \t#{old}\t#{new}" if old != new
end

输出结果为:

logorrhoea:     3   4
used:   2   1
makes:  2   1
themselves:     3   2

所以这似乎是一种改进。

答案 1 :(得分:4)

你应该做的一件事是教你的算法diphthongs。如果我正确地阅读你的代码,它会错误地将“援助”标记为有两个音节。

您还可以将“es”等添加到特殊情况结​​尾(您已经拥有“ing”)并且不将其视为音节,但这可能仍然会导致一些错误计数。

最后,为了获得最佳准确度,您应该将输入转换为与单词的发音有明确关系的拼写方案或字母表。使用您的“自己”示例,该算法没有可靠的方法来知道“e”“ves”被删除。但是,如果你把它作为“themselvz”重新驱逐,或者教授算法IPA并喂它[ðəmsɛlvz],很明显这个词只用两个音节发音。当然,这假设您可以控制输入,并且可能更多的工作不仅仅是自己计算音节。

答案 2 :(得分:1)

首先,似乎你应该减去len应该被排除的后缀。

len-=1 if /.*[ing,es,ed]$/.match(word)

您还可以查看Lingua::EN::Readability

  

它还可以计算几种可读性指标,例如雾指数和Flesch-Kincaid级别。

PS。我想我知道你在哪里得到了函数from。 DS。

答案 3 :(得分:0)

还有一个名为Odyssey的红宝石计算Gunning Fog,还有一些其他流行的(Flesch-Kincaid,SMOG等)