textstat文章の読みやすさを数値化し、機械学習の特徴量として活用する方法
本記事では、「文章の読みやすさ」を特徴量として数値化し、機械学習に利用する方法を解説します。英文の読みやすさはtextstatライブラリを使えば数値化することができます。textstatは、テキストのさまざまな統計量を提供するライブラリで、テキストの分析に活用することができます。
はじめに
機械学習では、テキスト(文章)を数値化し、特徴量として利用したい場合があります。テキストを特徴量にする方法は、いろいろありますが、ここではtextstatライブラリを利用する方法を解説します。
textstatは、さまざまな統計量を計算する機能を備えており、これを使うことで例えば「読みやすさ」などを数値化できます。
textstatについて
textstatは、テキストの統計量を計算するためのライブラリです。基本は英語のテキストの解析ですが、関数によっては他の言語もサポートしています。ただ、基本的には、英語のテキストの統計量を算出するライブラリと考えて良いかと思います。
以下、各関数のサポートする言語です。en
は英語で、de
はドイツ語となります。詳しくはGithubリポジトリを参照してください。
Function | en | de | es | fr | it | nl | pl | ru |
---|---|---|---|---|---|---|---|---|
flesch_reading_ease | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | |
gunning_fog | ✔ | ✔ |
GitHubリポジトリ: https://github.com/textstat/textstat
使い方
インストール
pipを用いてインストールできます。
pip install textstat
基本的な使い方(ほぼ全部の関数共通)
基本的な使い方は以下の通りです。ほとんどの統計量を算出する関数が以下のような呼び出しで使うことができます。かなり便利です。
text = "英語の文章"
score = textstat.関数名(text)
関数一覧
英語向けの統計量を計算する関数としては以下のものが準備されています。統計量の詳しい説明は公式GitHubを参考にしてください。
一覧からわかるように、かなりの種類の統計量が準備されています。また、一覧に記載した以外に言語固有の統計量もいくつか準備されています(スペイン語、アラビア語、イタリア語、ドイツ語)。
指標 | 関数名 |
Fleschの読みやすさ。60-69が標準で大きいほど簡単 | flesch_reading_ease(text) |
Flesch-Kincaidの学年レベル | flesch_kincaid_grade(text) |
FOGスコア | gunning_fog(text) |
SMOGインデックス | smog_index(text) |
Automated Readabilityインデックス | automated_readability_index(text) |
Coleman Liauインデックス | coleman_liau_index(text) |
Linsear Write | linsear_write_formula(text) |
Dale-Chall Readability Score | dale_chall_readability_score(text) |
上記の全てに基づいたスコア | text_standard(text) |
Spacheの可読性スコア | spache_readability(text) |
Mcalpine Eflawの可読性スコア | mcalpine_eflaw(text) |
読み終わるまでの時間(ms_per_char には1文字あたりの時間をミリ秒で設定) | reading_time(text, ms_per_char=14.69) |
音節数 | syllable_count(text) |
単語数 | lexicon_count(text) |
文数 | sentence_count(text) |
文字数 | char_count(text, ignore_spaces=True) |
句読点なしの文字数 | letter_count(text, ignore_spaces=True) |
音節が3以上の単語数 | polysyllabcount(text) |
音節数が1の単語の数 | monosyllabcount(text) |
pandasのデータフレームでの利用例
Pandasのデータフレームと組み合わせて使う場合の書き方の例です。
pandasのデータフレーム(df
)が以下のような内容だとします。
統計量を1つ列に追加する方法
これにFleschの読みやすさの列を追加する場合は、以下のようにapply
を使います。下記の例では、flesch_reading_ease
という列が新たに追加されます。
df['flesch_reading_ease'] = df['text'].apply(lambda x: textstat.flesch_reading_ease(x))
なお、処理時間がかかる場合は、 経過をビジュアルに表示するために、apply
の代わりにprogress_apply
を使っても良いです(別途tqdm
パッケージの導入が必要)。progress_apply
を使う場合は、以下のコードをどこかで実行します。
from tqdm import tqdm
tqdm.pandas()
tqdmが導入されていれば、apply
をprogress_apply
に書き換えるだけです。
df['flesch_reading_ease'] = df['text'].progress_apply(lambda x: textstat.flesch_reading_ease(x))
統計量をまとめて列に追加
以下のような関数を準備すると統計量を一気に計算することができます。下記の関数では、引数data
のtext
に評価したい文字列が入っている前提のプログラムになります。例えば、pandasのDataFrameの列にtext
がある場合がこれにあたります。
import textstat
def calc_textstat(data):
text = data['text']
return (
textstat.flesch_reading_ease(text),
textstat.flesch_kincaid_grade(text),
textstat.gunning_fog(text),
textstat.smog_index(text),
textstat.automated_readability_index(text),
textstat.coleman_liau_index(text),
textstat.linsear_write_formula(text),
textstat.dale_chall_readability_score(text),
textstat.text_standard(text, float_output=True),
textstat.spache_readability(text, float_output=True),
textstat.mcalpine_eflaw(text),
textstat.reading_time(text, ms_per_char=14.69),
textstat.syllable_count(text),
textstat.lexicon_count(text, removepunct=True),
textstat.sentence_count(text),
textstat.char_count(text, ignore_spaces=True),
textstat.letter_count(text, ignore_spaces=True),
textstat.polysyllabcount(text),
textstat.monosyllabcount(text)
)
これの利用の仕方ですが、pandasのデータフレームがdf
だとして、f0
~f15
という名前で列を追加する場合は、以下のようなコードで書くことができます。
n = len(calc_textstat(df.iloc[0]))
labels = [f'f{i}' for i in range(n)]
df[labels]=df.progress_apply(lambda x:calc_textstat(x),axis=1, result_type='expand')
これで一気に特徴量を追加できます。
上記のコードでは、追加される列数の計算とカラム名の設定は自動で行われますので、calc_textstat
関数の特徴量を削除したり追加した場合も、自動的に列数が調整され便利です。
私は、こんな感じでコーディングしておき、lightGBMなどの出力を見ながら、特徴量を削除・追加しています。こうしておくと、自動で列数が調整されるので試行錯誤が楽になります。
おわりに
英語のテキストの統計量を計算するtextstatライブラリを紹介しました。色々な統計量を手軽に算出することができるので機械学習の特徴量の検討時などに重宝すると思います。
文章同士の類似検索はFaissを利用する方法もあります。こちらについては、以下の記事を参考にしてください。