我正在修补一个域名查找器,并希望支持那些容易发音的词。
示例:nameoic.com(bad)与namelet.com(好)。
认为与soundex有关可能是合适的,但看起来我不能用它们来产生某种比较分数。
获胜的PHP代码。
答案 0 :(得分:15)
这是一个应该与最常见的单词一起使用的函数......它应该在1(根据规则的完美可发性)到0之间给出一个很好的结果。
以下功能远非完美(它不像Tsunami [0.857]这样的词)。但是根据您的需求进行调整应该相当容易。
<?php
// Score: 1
echo pronounceability('namelet') . "\n";
// Score: 0.71428571428571
echo pronounceability('nameoic') . "\n";
function pronounceability($word) {
static $vowels = array
(
'a',
'e',
'i',
'o',
'u',
'y'
);
static $composites = array
(
'mm',
'll',
'th',
'ing'
);
if (!is_string($word)) return false;
// Remove non letters and put in lowercase
$word = preg_replace('/[^a-z]/i', '', $word);
$word = strtolower($word);
// Special case
if ($word == 'a') return 1;
$len = strlen($word);
// Let's not parse an empty string
if ($len == 0) return 0;
$score = 0;
$pos = 0;
while ($pos < $len) {
// Check if is allowed composites
foreach ($composites as $comp) {
$complen = strlen($comp);
if (($pos + $complen) < $len) {
$check = substr($word, $pos, $complen);
if ($check == $comp) {
$score += $complen;
$pos += $complen;
continue 2;
}
}
}
// Is it a vowel? If so, check if previous wasn't a vowel too.
if (in_array($word[$pos], $vowels)) {
if (($pos - 1) >= 0 && !in_array($word[$pos - 1], $vowels)) {
$score += 1;
$pos += 1;
continue;
}
} else { // Not a vowel, check if next one is, or if is end of word
if (($pos + 1) < $len && in_array($word[$pos + 1], $vowels)) {
$score += 2;
$pos += 2;
continue;
} elseif (($pos + 1) == $len) {
$score += 1;
break;
}
}
$pos += 1;
}
return $score / $len;
}
答案 1 :(得分:8)
我认为问题可以归结为将单词解析为候选集phonemes,然后使用预定的音素对列表来确定单词的发音方式。
例如:“技巧”在发音上是“/ s / k / i / l /”。 “/ s / k /”,“/ k / i /”,“/ i / l /”都应该具有高分的发音,所以这个词应该得分很高。
“skpit”在发音上是“/ s / k / p / i / t /”。 “/ k / p /”应该具有较低的发音分数,因此该单词应该得分较低。
答案 2 :(得分:6)
使用马尔可夫模型(当然是字母,而不是文字)。单词的概率是发音容易度的一个很好的代理。你必须对长度进行标准化,因为较长的单词本来就不太可能。