読みやすさの指標を構築する


13

フレッシュ・キンケイド可読性アルゴリズムは、完全に客観的、またはコンピュータを使用して、容易に自動化されどちらもワードカウントと音節数、の措置に依存します。たとえば、ハイフンを含む「code-golf」は1語または2語としてカウントされますか?「百万」という言葉は2音節か3音節ですか?このタスクでは、正確なカウントには時間、スペース、そして最も重要なことにはコードが必要になるため、概算する必要があります。

あなたの仕事は、英語の文章を読める言語(完全な文章であると仮定)で可能な限り最小のプログラム(関数)を構築し、Flesch Reading Easeインデックスを8ポイントの許容範囲まで計算することです(説明のため)音節カウントと単語カウントのバリエーション)。次のように計算されます。

FRE = 206.835 - 1.015 * (words per sentence) - 84.6 * (syllables per word)

プログラムは、手動カウントを使用してインデックスが計算された以下の参照パッセージに合わせる必要があります。

I would not, could not, in the rain.
Not in the dark, not on a train.
Not in a car, not in a tree.
I do not like them, Sam, you see.
Not in a house, not in a box.
Not with a mouse, not with a fox.
I will not eat them here or there.
I do not like them anywhere!

インデックス:111.38(8文章中62ワードの64音節)

It was a bright cold day in April, and the clocks were striking thirteen.
Winston Smith, his chin nuzzled into his breast in an effort to escape
the vile wind, slipped quickly through the glass doors of Victory Mansions,
though not quickly enough to prevent a swirl of gritty dust from entering
along with him.

インデックス:65.09(2センテンスの55ワードで74音節)

When in the Course of human events, it becomes necessary for one people to
dissolve the political bands which have connected them with another, and to
assume among the powers of the earth, the separate and equal station to
which the Laws of Nature and of Nature's God entitle them, a decent respect
to the opinions of mankind requires that they should declare the causes
which impel them to the separation.

インデックス:3.70(1文中71語の110音節)

音節と単語を手動でカウントし、インデックスを計算した他のパッセージがある場合、それらを検証として表示できます。


関数になることができますか?それともSTDINを取る必要がありますか?
ブリガンド

2
3つの例のパッセージで使用可能な音節カウントを持っていますか、それともインデックスだけですか?持っている場合、音節数は比較に便利です。
ストリゴイデス

関数にすることができます。実際、関数でなければなりません。
ジョーZ.

回答:


6

Perl 120バイト

#!perl -pa0
s@\w+|([.!?])@$s+=$#-,lc($&)=~s![aeiou]+\B|([aeiouy]$)!$y+=1-$#-/3!ger@ge}
{$_=206.835-1.015*@F/$s-84.6*$y/@F

サンプルI / O:

$ perl flesch-kincaid.pl < input1.dat
110.730040322581

$ perl flesch-kincaid.pl < input2.dat
65.6097727272728

$ perl flesch-kincaid.pl < input2.dat
1.71366197183096

音節のカウントは、各母音クラスタが単一の音節であると想定して行われます。ただし、単語の最後にある孤立した母音は、時間の3分の2しかカウントされません。かなり正確であると思われるヒューリスティック。


3

K&R C - 188の196 199 229文字

関数を指定するために仕様を変更すると、カウントから多くのcオーバーヘッドを得ることができます。また、Strigoidesの音節カウントハックを使用するように変更しました。これは、私の式の調整よりも優れており、単語のオーバーカウントに対処するために拡張されました。

悲しいことに基づいた母音検出のより短い方法を見つけた後stdchr、私は退屈する必要がないように、私が使用してきた少しいじる嫌悪感からさらにいくつかを絞るインセンティブがありました。

d,a,v,s,t,w;float R(char*c){for(;*c;++c){s+=*c=='.';if(isalpha(*c)){
w+=!a++;d=(*c&30)>>1;if(*c&1&(d==7|((!(d&1))&(d<6|d>8)))){t+=!v++;}
else v=0;}else v=a=0;}return 206.835-1.*w/s-82.*t/w;}

ここでのロジックは、単純なステートマシンです。文はピリオドのみ、単語はアルファベット文字列、および音節は母音文字列(yを含む)としてカウントします。

正しい数字を出すには定数を少し調べなければなりませんでしたが、音節を一定の割合で過少カウントするというStrigoidesのトリックを借りました。

コメントといくつかのデバッグツールを使用したゴルフなし

#include <stdlib.h>
#include <stdio.h>
d,a,/*last character was alphabetic */
  v,/*lastcharacter was a vowel */
  s, /* sentences counted by periods */
  t, /* syllables counted by non-consequtive vowels */
  w; /* words counted by non-letters after letters */
float R/*eadability*/(char*c){
  for(;*c;++c){
    s+=*c=='.';
    if(isalpha(*c)){ /* a letter might mark the start of a word or a
               vowel string */
      w+=!a++; /* It is only the start of a word if the last character
              wasn't a letter */
      /* Extract the four bits of the character that matter in determining
       * vowelness because a vowel might mark a syllable */
      d=(*c&30)>>1;
      if( *c&1  & ( d==7 | ( (!(d&1)) & (d<6|d>8) ) ) 
      ) { /* These bits 7 or even and not 6, 8 make for a
         vowel */
    printf("Vowel: '%c' (mangled as %d [0x%x]) counts:%d\n",*c,d,d,!v);
    t+=!v++;
      } else v=0; /* Not a vowel so set the vowel flag to zero */
    }else v=a=0; /* this input not alphabetic, so set both the
            alphabet and vowel flags to zero... */
  }
  printf("Syllables: %3i\n",t);
  printf("Words:     %3i       (t/w) = %f\n",w,(1.0*t/w));
  printf("Sentences: %3i       (w/s) = %f\n",s,(1.0*w/s));
  /* Constants tweaked here due to bad counting behavior ...
   * were:       1.015     84.6 */
  return 206.835-1.   *w/s-82. *t/w;
}
main(c){
  int i=0,n=100;
  char*buf=malloc(n);
  /* Suck in the whole input at once, using a dynamic array for staorage */
  while((c=getc(stdin))!=-1){
    if(i==n-1){ /* Leave room for the termination */
      n*=1.4;
      buf=realloc(buf,n);
      printf("Reallocated to %d\n",n);
    }
    buf[i++]=c;
    printf("%c %c\n",c,buf[i-1]);
  }
  /* Be sure the string is terminated */
  buf[i]=0;
  printf("'%s'\n",buf);
  printf("%f\n",R/*eadability*/(buf));
}

出力:(長いバージョンの足場を使用しますが、ゴルフ機能を使用します。)

$ gcc readability_golf.c
readability_golf.c:1: warning: data definition has no type or storage class
$ ./a.out < readability1.txt 
'I would not, could not, in the rain.
Not in the dark, not on a train.
Not in a car, not in a tree.
I do not like them, Sam, you see.
Not in a house, not in a box.
Not with a mouse, not with a fox.
I will not eat them here or there.
I do not like them anywhere!
'
104.074631    
$ ./a.out < readability2.txt
'It was a bright cold day in April, and the clocks were striking thirteen.
Winston Smith, his chin nuzzled into his breast in an effort to escape
the vile wind, slipped quickly through the glass doors of Victory Mansions,
though not quickly enough to prevent a swirl of gritty dust from entering
along with him.
'
63.044090
$ ./a.out < readability3.txt 
'When in the Course of human events, it becomes necessary for one people to
dissolve the political bands which have connected them with another, and to
assume among the powers of the earth, the separate and equal station to
which the Laws of Nature and of Nature's God entitle them, a decent respect
to the opinions of mankind requires that they should declare the causes
which impel them to the separation.
'
-1.831667

欠陥:

  • 文のカウントロジックは間違っていますが、入力の1つだけがa !またはaを持っているので、私はそれを避け?ます。
  • 単語カウントロジックは、短縮を2つの単語として扱います。
  • 音節のカウントロジックは、それらの同じ収縮を1つの音節として扱います。ただし、おそらく平均してオーバーthereカウント(たとえば、2としてカウントされ、終わる単語eが1つ多くカウントされます)で、96.9%の修正という一定の係数を適用しました。
  • ASCII文字セットを想定しています。
  • 母音の検出は[およびを認めると信じていますが{、これは明らかに正しくありません。
  • K&Rのセマンティクスに依存しているため、これは見苦しくなりますが、コードゴルフです。

見るべきもの:

  • perlを追いかけているとしても、私はここで(一時的に)両方のPythonソリューションの先を行っています。

  • 母音を検出するために私がした恐ろしいことの負荷を取得します。ASCII表現をバイナリで記述し、長いバージョンでコメントを読むと、ある程度意味があります。


「許容できる結果を得るには、手作業で式を少し変更する必要がありました。」これ悪い形式かもしれません。
ジョーZ.

1
これで、Strigoidesのリードに少なくとも従い、3つのテストケースを一致させるための純粋なアドホックな調整ではなく、テキストの理解がエラーになる人に基づいて調整を行いました。
dmckee ---元モデレーター子猫

2

Python、202 194 188 184 171 167文字

import re
def R(i):r=re.split;w=len(r(r'[ \n]',i));s=r('\\.',i);y=r('[^aeiou](?i)+',i);return 206.835-1.015*w/(len(s)-s.count('\n'))-84.6*(len(y)-y.count(' ')-2)*.98/w

最初に、スペースと改行に沿って分割して単語の合計数を取得します。

w=len(r(r'[ \n]',i))

次に、式。文と音節のカウントは一度だけ使用されるため、この式に埋め込まれます。

文章は.、改行が除外された、単純な入力分割です。

s=r('\\.',i);s=len(s)-s.count('\n')

音節は、スペースが削除された非母音に沿った入力分割で構成されます。これは、音節の数を一貫してわずかに過大評価しているようですので、それを調整する必要があります(約.98はそれをしているようです):

y=r('[^aeiou](?i)+',i);y=len(y)-y.count(' ')-2;

202-> 194: len(x)-2ではなくlen(x[1:-1])。不要な括弧を削除しました。音節の正規表現で大文字と小文字を区別しないようにしました

194-> 188: ファイルは以前、unixファイル形式ではなくdosとして保存されていたため、wc -c改行を2文字としてカウントしていました。おっと。

188-> 184:x for x in ... if x!=...中間結果を保存して減算することにより 、これらの厄介なものを取り除きますx.count(...)

184-> 171: 入出力を削除し、関数に変換する

171-> 167:len(x)-x.count(...) sを式に 挿入します


答えには、入力手順と出力手順を含める必要はありません。
ジョーZ.

@JoeZengああ、わかりました。それから関数に変えます。
ストリゴイデス

1

Python 380文字

import re
def t(p):
 q=lambda e: e!=''
 w=filter(q,re.split('[ ,\n\t]',p))
 s=filter(q,re.split('[.?!]',p))
 c=len(w)*1.0
 f=c/len(s)
 return w,f,c
def s(w):
 c= len(re.findall(r'([aeiouyAEIOUY]+)',w))
 v='aeiouAEIOU'
 if len(w)>2 and w[-1]=='e'and w[-2]not in v and w[-3]in v:c-= 1
 return c
def f(p):
 w,f,c=t(p)
 i=0
 for o in w:
  i+=s(o)
 x=i/c
 return 206.835-1.015*f-84.6*x

これはかなり長い解決策ですが、少なくとも3つのテストケースのうち、機能する場合は十分に機能します。

テストコード

def test():
 test_cases=[['I would not, could not, in the rain.\
        Not in the dark, not on a train.\
        Not in a car, not in a tree.\
        I do not like them, Sam, you see.\
        Not in a house, not in a box.\
        Not with a mouse, not with a fox.\
        I will not eat them here or there.\
        I do not like them anywhere!', 111.38, 103.38, 119.38],\
        ['It was a bright cold day in April, and the clocks were striking thirteen.\
        Winston Smith, his chin nuzzled into his breast in an effort to escape\
        the vile wind, slipped quickly through the glass doors of Victory Mansions,\
        though not quickly enough to prevent a swirl of gritty dust from entering\
        along with him.', 65.09, 57.09, 73.09],\
        ["When in the Course of human events, it becomes necessary for one people to\
        dissolve the political bands which have connected them with another, and to\
        assume among the powers of the earth, the separate and equal station to\
        which the Laws of Nature and of Nature's God entitle them, a decent respect\
        to the opinions of mankind requires that they should declare the causes\
        which impel them to the separation.", 3.70, -4.70, 11.70]]
 for case in test_cases:
  fre= f(case[0])
  print fre, case[1], (fre>=case[2] and fre<=case[3])

if __name__=='__main__':
 test()

結果-

elssar@elssar-laptop:~/code$ python ./golf/readibility.py
108.910685484 111.38 True
63.5588636364 65.09 True
-1.06661971831 3.7 True

ここから音節カウンターを使用しました- 音節のカウント

より読みやすいバージョンはこちらから入手できます


1
if len(w)>2 and w[-1]=='e'and w[-2]not in v and w[-3]in v:c-= 1シンプルだが良い近似。私はそれが好きです。
dmckee ---元モデレーター子猫

0

Javascript、191バイト

t=prompt(q=[]);s=((t[m="match"](/[!?.]+/g)||q)[l="length"]||1);y=(t[m](/[aeiouy]+/g)||q)[l]-(t[m](/[^aeiou][aeiou][s\s,'.?!]/g)||q)[l]*.33;w=(t.split(/\s+/g))[l];alert(204-1.015*w/s-84.5*y/w)

最初のテストケースでは112.9が得られます(正解は111.4、1.5ポイントオフ)

2番目のテストケースでは67.4となります(正解は65.1、2.3ポイントオフ)

3番目のテストケースでは1.7が得られます(正解は3.7、2.0ポイント減)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.