Читаемость Флеша-Кинкейда: Улучшение функции PHP

Я написал этот PHP-код, чтобы реализовать показатель читабельности Флеша-Кинкейда как функцию:

function readability($text) {
    $total_sentences = 1; // one full stop = two sentences => start with 1
    $punctuation_marks = array('.', '?', '!', ':');
    foreach ($punctuation_marks as $punctuation_mark) {
        $total_sentences += substr_count($text, $punctuation_mark);
    }
    $total_words = str_word_count($text);
    $total_syllable = 3; // assuming this value since I don't know how to count them
    $score = 206.835-(1.015*$total_words/$total_sentences)-(84.6*$total_syllables/$total_words);
    return $score;
}

Есть ли у вас предложения по улучшению кода? Это правильно? Это будет работать?

Я надеюсь, что вы можете мне помочь. Заранее спасибо!


person caw    schedule 02.07.2009    source источник


Ответы (4)


С точки зрения эвристики код выглядит нормально. Вот несколько моментов, которые необходимо учитывать, которые значительно усложняют расчет оборудования для машины:

  1. Что такое приговор?

    Серьезно, что такое приговор? У нас есть точки, но они также могут использоваться для обозначения степени доктора философии, например, Y.M.C.A., и для других целей, не связанных с окончанием предложения. Когда вы думаете о восклицательных знаках, вопросительных знаках и многоточиях, вы оказываете себе медвежью услугу, предполагая, что точка поможет. Я уже рассматривал эту проблему раньше, и если вам действительно нужно более надежное подсчет предложений в реальном тексте, вам нужно будет проанализировать текст. Это может потребовать больших вычислительных ресурсов, времени и трудностей с поиском бесплатных ресурсов. В конце концов, вам все равно придется беспокоиться о частоте ошибок конкретной реализации парсера. Однако только полный синтаксический анализ скажет вам, что такое предложение, а что просто точка в других случаях. Кроме того, если вы используете текст «в дикой природе» - такой как, скажем, HTML - вам также придется беспокоиться о предложениях, заканчивающихся не пунктуацией, а окончанием тегов. Например, на многих сайтах знаки препинания не добавляются к тегам h1 и h2, но это явно разные предложения или фразы.

  2. Слоги - это не то, к чему мы должны приближаться

    Это основная отличительная черта этой эвристики удобочитаемости, которая делает ее наиболее сложной для реализации. Вычислительный анализ подсчета слогов в произведении требует предположения, что предполагаемый читатель говорит на том же диалекте, что и ваш генератор подсчета слогов, на котором обучается. То, как звуки располагаются вокруг слога, на самом деле является основной частью того, что делает акценты акцентами. Если вы мне не верите, попробуйте как-нибудь съездить на Ямайку. Это означает, что даже если бы человек произвел вычисления для этого вручную, это все равно была бы оценка, зависящая от диалекта.

  3. Что это за слово?

    Ни в малейшей степени не прибегая к психолингвизму, но вы обнаружите, что слова, разделенные пробелами, и то, что воспринимается говорящим как слова, совершенно разные. Это сделает концепцию вычислимой оценки удобочитаемости несколько сомнительной.

Так что, в конце концов, я могу ответить на ваш вопрос: «Сработает ли это?». Если вы хотите взять кусок текста и отобразить эту оценку читабельности среди других показателей, чтобы предложить какую-то мыслимую добавленную стоимость, проницательный пользователь не задаст все эти вопросы. Если вы пытаетесь сделать что-то научное или даже что-то педагогическое (как это и было задумано в конечном итоге), я бы особо не беспокоился. Фактически, если вы собираетесь использовать это, чтобы делать какие-либо предложения пользователю по поводу контента, который они сгенерировали, я бы очень колебался.

Лучший способ измерить сложность чтения текста, скорее всего, связан с соотношением низкочастотных слов к высокочастотным, а также с количеством hapax legomen в тексте. Но я бы не стал придумывать подобную эвристику, потому что было бы очень сложно эмпирически проверить что-либо подобное.

person Robert Elwell    schedule 02.07.2009
comment
Большое спасибо за подробный ответ. Теперь я понял, что нет смысла использовать эту формулу, если мне нужны точные результаты. - person caw; 03.07.2009

Взгляните на текстовую статистику PHP на GitHub.

person Alix Axel    schedule 07.09.2009

Обратите внимание на следующие два класса и информацию об их использовании. Это обязательно вам поможет.

Класс библиотеки шаблонов подсчета слогов для удобочитаемости:

<?php class ReadabilitySyllableCheckPattern {

public $probWords = [
    'abalone' => 4,
    'abare' => 3,
    'abed' => 2,
    'abruzzese' => 4,
    'abbruzzese' => 4,
    'aborigine' => 5,
    'acreage' => 3,
    'adame' => 3,
    'adieu' => 2,
    'adobe' => 3,
    'anemone' => 4,
    'apache' => 3,
    'aphrodite' => 4,
    'apostrophe' => 4,
    'ariadne' => 4,
    'cafe' => 2,
    'calliope' => 4,
    'catastrophe' => 4,
    'chile' => 2,
    'chloe' => 2,
    'circe' => 2,
    'coyote' => 3,
    'epitome' => 4,
    'forever' => 3,
    'gethsemane' => 4,
    'guacamole' => 4,
    'hyperbole' => 4,
    'jesse' => 2,
    'jukebox' => 2,
    'karate' => 3,
    'machete' => 3,
    'maybe' => 2,
    'people' => 2,
    'recipe' => 3,
    'sesame' => 3,
    'shoreline' => 2,
    'simile' => 3,
    'syncope' => 3,
    'tamale' => 3,
    'yosemite' => 4,
    'daphne' => 2,
    'eurydice' => 4,
    'euterpe' => 3,
    'hermione' => 4,
    'penelope' => 4,
    'persephone' => 4,
    'phoebe' => 2,
    'zoe' => 2
];

public $addSyllablePatterns = [
    "([^s]|^)ia",
    "iu",
    "io",
    "eo($|[b-df-hj-np-tv-z])",
    "ii",
    "[ou]a$",
    "[aeiouym]bl$",
    "[aeiou]{3}",
    "[aeiou]y[aeiou]",
    "^mc",
    "ism$",
    "asm$",
    "thm$",
    "([^aeiouy])\1l$",
    "[^l]lien",
    "^coa[dglx].",
    "[^gq]ua[^auieo]",
    "dnt$",
    "uity$",
    "[^aeiouy]ie(r|st|t)$",
    "eings?$",
    "[aeiouy]sh?e[rsd]$",
    "iell",
    "dea$",
    "real",
    "[^aeiou]y[ae]",
    "gean$",
    "riet",
    "dien",
    "uen"
];

public $prefixSuffixPatterns = [
    "^un",
    "^fore",
    "^ware",
    "^none?",
    "^out",
    "^post",
    "^sub",
    "^pre",
    "^pro",
    "^dis",
    "^side",
    "ly$",
    "less$",
    "some$",
    "ful$",
    "ers?$",
    "ness$",
    "cians?$",
    "ments?$",
    "ettes?$",
    "villes?$",
    "ships?$",
    "sides?$",
    "ports?$",
    "shires?$",
    "tion(ed)?$"
];

public $subSyllablePatterns = [
    "cia(l|$)",
    "tia",
    "cius",
    "cious",
    "[^aeiou]giu",
    "[aeiouy][^aeiouy]ion",
    "iou",
    "sia$",
    "eous$",
    "[oa]gue$",
    ".[^aeiuoycgltdb]{2,}ed$",
    ".ely$",
    "^jua",
    "uai",
    "eau",
    "[aeiouy](b|c|ch|d|dg|f|g|gh|gn|k|l|ll|lv|m|mm|n|nc|ng|nn|p|r|rc|rn|rs|rv|s|sc|sk|sl|squ|ss|st|t|th|v|y|z)e$",
    "[aeiouy](b|c|ch|dg|f|g|gh|gn|k|l|lch|ll|lv|m|mm|n|nc|ng|nch|nn|p|r|rc|rn|rs|rv|s|sc|sk|sl|squ|ss|th|v|y|z)ed$",
    "[aeiouy](b|ch|d|f|gh|gn|k|l|lch|ll|lv|m|mm|n|nch|nn|p|r|rn|rs|rv|s|sc|sk|sl|squ|ss|st|t|th|v|y)es$",
    "^busi$"
]; } ?>

Другой класс - это класс алгоритма удобочитаемости, имеющий два метода расчета баллов:

<?php class ReadabilityAlgorithm {
function countSyllable($strWord) {
    $pattern = new ReadabilitySyllableCheckPattern();
    $strWord = trim($strWord);

    // Check for problem words
    if (isset($pattern->{'probWords'}[$strWord])) {
        return $pattern->{'probWords'}[$strWord];
    }

    // Check prefix, suffix
    $strWord = str_replace($pattern->{'prefixSuffixPatterns'}, '', $strWord, $tmpPrefixSuffixCount);

    // Removed non word characters from word
    $arrWordParts = preg_split('`[^aeiouy]+`', $strWord);
    $wordPartCount = 0;
    foreach ($arrWordParts as $strWordPart) {
        if ($strWordPart <> '') {
            $wordPartCount++;
        }
    }
    $intSyllableCount = $wordPartCount + $tmpPrefixSuffixCount;

    // Check syllable patterns 
    foreach ($pattern->{'subSyllablePatterns'} as $strSyllable) {
        $intSyllableCount -= preg_match('`' . $strSyllable . '`', $strWord);
    }

    foreach ($pattern->{'addSyllablePatterns'} as $strSyllable) {
        $intSyllableCount += preg_match('`' . $strSyllable . '`', $strWord);
    }

    $intSyllableCount = ($intSyllableCount == 0) ? 1 : $intSyllableCount;
    return $intSyllableCount;
}

function calculateReadabilityScore($stringText) {
    # Calculate score
    $totalSentences = 1;
    $punctuationMarks = array('.', '!', ':', ';');

    foreach ($punctuationMarks as $punctuationMark) {
        $totalSentences += substr_count($stringText, $punctuationMark);
    }

    // get ASL value
    $totalWords = str_word_count($stringText);
    $ASL = $totalWords / $totalSentences;

    // find syllables value
    $syllableCount = 0;
    $arrWords = explode(' ', $stringText);
    $intWordCount = count($arrWords);
    //$intWordCount = $totalWords;

    for ($i = 0; $i < $intWordCount; $i++) {
        $syllableCount += $this->countSyllable($arrWords[$i]);
    }

    // get ASW value
    $ASW = $syllableCount / $totalWords;

    // Count the readability score
    $score = 206.835 - (1.015 * $ASL) - (84.6 * $ASW);
    return $score;
} } ?>

// Пример: как использовать

<?php // Create object to count readability score
$readObj = new ReadabilityAlgorithm();
echo $readObj->calculateReadabilityScore("Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into: electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently; with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum!");
?>
person Nikunj Kabariya    schedule 25.01.2017

На самом деле я не вижу проблем с этим кодом. Конечно, его можно немного оптимизировать, если вы действительно этого хотите, заменив все различные функции одним циклом подсчета. Однако я решительно утверждаю, что в этом нет необходимости и даже совершенно неправильно. Ваш текущий код очень читабелен и прост для понимания, и любые оптимизации, вероятно, усугубят ситуацию с этой точки зрения. Используйте его как есть и не пытайтесь оптимизировать, если только он не окажется узким местом производительности.

person Emil H    schedule 02.07.2009