文書の過去の版を表示しています。
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))
結果は以下の通り:
c_sekbo_06_main_v03.txt 須達 0.719277 舍利弗 0.272642 精舍 0.244040 부텨 0.243841 耶輸 0.166975 太子 0.155795 六師 0.154131 目連 0.128442 舍衛國 0.125518 護彌 0.115598 c_sekbo_09_main_v03.txt 有情 0.514115 藥師瑠璃光如來 0.431194 橫死 0.265350 大願 0.215597 일훔 0.213857 菩提 0.199012 來世 0.199012 惡趣 0.149259 文殊師利 0.130755 부텨 0.118809 c_sekbo_13_main_v03.txt 부텨 0.494233 舍利弗 0.349437 佛道 0.257761 菩薩 0.244011 諸佛 0.238970 衆生 0.162934 일훔 0.141209 知見 0.121299 佛乘 0.121299 因緣 0.115584 c_sekbo_19_main_v03.txt 소리 0.405196 부텨 0.239810 菩薩 0.195539 隨喜 0.184687 法華經 0.184687 得大勢 0.184687 善女人 0.156186 淸淨 0.151089 功德 0.146655 摩訶薩 0.140011 c_sekbo_23_main_v03.txt 부텨 0.354663 舍利 0.318446 供養 0.241816 拘尸城 0.225031 金棺 0.225031 大衆 0.196956 如來 0.182705 一切 0.177332 阿那律 0.165022 涅槃 0.146129 c_sekbo_24_main_v03.txt 尊者 0.421416 阿育王 0.387703 부텨 0.289824 夫人 0.190071 善容 0.185423 太子 0.184018 供養 0.169064 比丘 0.144912 對答 0.144265 上座 0.134853
須達と舎利仏のストーリーが中心的な巻6,『薬師瑠璃光如来本願功徳経』の翻訳である巻9,『法華経』の翻訳である巻13,19,釈迦入滅後,舎利の扱いを論じる巻23,阿育王の話が出てくる巻24と,それぞれの特徴が示されています.