文書の過去の版を表示しています。
HanDicの出力結果をPythonで利用する:tf-idfの計算
はじめに
HanDicを使ったMeCabの出力結果をPythonで利用する例として,文書中に現れる単語の重要度を示す,TF-IDFの計算を行ってみます.今回は中期朝鮮語の資料である『석보상절(釈譜詳節)』(1447年刊)を,中期朝鮮語のMeCab用解析辞書「MkHanDic」で解析した結果を使います.解析結果については,MeCabの出力そのままではなく,テキストファイルに出力した結果を手作業で修正したものを利用します.辞書構築の際の学習用データとして用いているものです.
上記資料の原刊本のうち,巻6,9,13,19,23,24の本文のみ解析して修正した巻次ごとのテキストファイルが,スクリプトと同じディレクトリ下のsekbo_texts
というディレクトリにあるものとします.巻6のファイル(ファイル名はc_sekbo_06_main_v03.txt
とする)の冒頭は以下の通りとなっています:
世尊 Noun,固有名詞,人名,*,*,世尊,世尊,世尊,*,NNP 'i Ending,助詞,主格,*,*,이,이,*,*,JKS 象頭山 Noun,固有名詞,地名,*,*,象頭山,象頭山,象頭山,*,NNP 'ai Ending,助詞,処格,*,*,애,애,*,*,JKB ga Verb,自立,*,語基2,*,가다01,가,*,*,VV sia Prefinal,尊敬,*,語基3,*,시,샤,*,*,EP 龍 Noun,普通,*,*,*,龍,龍,龍,*,NNG goa Ending,助詞,接続助詞,*,*,과,과,*,*,JC 鬼神 Noun,普通,*,*,*,鬼神,鬼神,鬼神,*,NNG goa Ending,助詞,接続助詞,*,*,과,과,*,*,JC 'uih@'ia Verb,自立,*,語基3,*,위다,위야,*,*,VV 說法 Noun,普通,動作,*,*,說法,說法,說法,*,NNG h@ Suffix,動詞派生,*,語基1,*,다80,,*,*,XSV de Prefinal,回想,*,語基2,*,더,더,*,*,EP si Prefinal,尊敬,*,語基1,*,시,시,*,*,EP da Ending,語尾,終止形,*,1接続,다,다,*,*,EF . Symbol,ピリオド,*,*,*,.,.,*,*,SF EOS
中期朝鮮語に固有の文字は,表示されていないかと思います.表層形(各行の冒頭)にアルファベット転写を用いていますが,この表記についてはmecab-k2alphaのアルファベット転写表を参照してください.
やること
上述の『釈譜詳節』のそれぞれの巻次について,名詞類(普通名詞,固有名詞,語根)のTF-IDFを計算します.その上で,各巻次のTF-IDF上位10語を列挙します.基本的にはHanDicをPythonで利用する:TF-IDFの計算のやり方と同じです.
準備
今回はMeCabを呼び出したりしないので,必要最低限のモジュールだけ呼び出します.
import glob, os from sklearn.feature_extraction.text import TfidfVectorizer import pandas as pd
読み込んだファイルの処理
読み込んだファイルについて処理する関数を定義します.出力結果は各行「表層形[タブ文字]コンマ区切りの素性」という形式なので,まずsplit('\t')
で表層形と素性とを区切った後,素性に当たる部分をsplit(',')
で個別の素性に分け,配列に入れます.
素性のうち「世宗タグ」がNNG(普通名詞),NNP(固有名詞),XR(語根)に該当するものを抽出し,スペース区切りの配列にします.
def extract(file): words = [] with open(file, mode='rt', encoding='utf-8') as fi: for line in fi: mecab_features = [] line = line.rstrip('\n') if line == 'EOS': continue mecab_features = line.split('\t')[1].split(',') if mecab_features[9] in ['NNG', 'NNP', 'XR']: words.append(mecab_features[5]) text_result = ' '.join(words) return text_result
こちらもHanDicをPythonで利用する:TF-IDFの計算と同じく,普通名詞と固有名詞,語根に限定しました.
ファイルの読み込みとその処理
ディレクトリsekbo_texts
内にあるファイルをそれぞれ読み込み,前節の処理を行います.
# sekbo_texts フォルダ内のテキスト読み込み all_files = glob.glob("sekbo_texts/*.txt") docs = [] titles = [] for i in all_files: text = extract(i) titles.append(os.path.split(i)[1]) docs.append(text)
それぞれのファイル名を取り出して,別途配列に入れます.
TF-IDFの計算と上位10語の表示
ここから後は,HanDicをPythonで利用する:TF-IDFの計算と同じ手順です.scikit-learnでTF-IDFを計算します.
# モデルを作成 vectorizer = TfidfVectorizer(smooth_idf=False) values = vectorizer.fit_transform(docs).toarray() feature_names = vectorizer.get_feature_names_out() df = pd.DataFrame(values, columns = feature_names, index=titles)
今回はファイル数が少ないので,全てのファイルについてTF-IDFで上位の10語を表示するようにしました.
for num in range(len(df)): temp_df = [] temp_df = df[num:num+1].T temp_df = temp_df.sort_values(by=titles[num], ascending=False) print(temp_df.head(10))
(以下継続)