ユーザ用ツール

サイト用ツール


korean:mecab:python_mk_tfidf

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

次のリビジョン
前のリビジョン
korean:mecab:python_mk_tfidf [2021/11/07 23:00] – 作成 yoshikorean:mecab:python_mk_tfidf [2021/11/12 19:38] (現在) – [TF-IDFの計算と上位10語の表示] yoshi
行 1: 行 1:
-====== HanDicの出力結果をPythonで利用する:tf-idfの計算 ======+====== HanDicの出力結果をPythonで利用する:TF-IDFの計算 ======
  
 ===== はじめに ===== ===== はじめに =====
  
-[[https://ja.osdn.net/projects/handic/|HanDic]]を使ったMeCabの出力結果をPythonで利用する例として,文書中に現れる単語の重要度を示す,TF-IDFの計算を行ってみます.今回は中期朝鮮語の資料である『석보상절(釈譜詳節)』(1447年刊)を,中期朝鮮語のMeCab用解析辞書「[[https://ja.osdn.net/pkg/handic/mkhandic-mecab|MkHanDic]]」で解析した結果を使います.解析結果については,MeCabの出力そのままではなく,テキストファイルに出力した結果を手作業で修正したものを利用します.+[[https://ja.osdn.net/projects/handic/|HanDic]]を使ったMeCabの出力結果をPythonで利用する例として,文書中に現れる単語の重要度を示す,TF-IDFの計算を行ってみます.今回は中期朝鮮語の資料である『석보상절(釈譜詳節)』(1447年刊)を,中期朝鮮語のMeCab用解析辞書「[[https://ja.osdn.net/pkg/handic/mkhandic-mecab|MkHanDic]]」で解析した結果を使います.解析結果については,MeCabの出力そのままではなく,テキストファイルに出力した結果を手作業で修正したものを利用します.辞書構築の際の学習用データとして用いているものです.
  
 上記資料の原刊本のうち,巻6,9,13,19,23,24の本文のみ解析して修正した巻次ごとのテキストファイルが,スクリプトと同じディレクトリ下の''sekbo_texts''というディレクトリにあるものとします.巻6のファイル(ファイル名は''c_sekbo_06_main_v03.txt''とする)の冒頭は以下の通りとなっています: 上記資料の原刊本のうち,巻6,9,13,19,23,24の本文のみ解析して修正した巻次ごとのテキストファイルが,スクリプトと同じディレクトリ下の''sekbo_texts''というディレクトリにあるものとします.巻6のファイル(ファイル名は''c_sekbo_06_main_v03.txt''とする)の冒頭は以下の通りとなっています:
行 28: 行 28:
 </code> </code>
  
-以下継続+中期朝鮮語に固有の文字は,表示されていないかと思います.表層形各行の冒頭にアルファベット転写を用いていますが,この表記については[[https://ja.osdn.net/projects/handic/wiki/MkHanDicAlphabet|mecab-k2alphaのアルファベット転写表]]を参照してください.
  
 +===== やること =====
 +
 +上述の『釈譜詳節』のそれぞれの巻次について,名詞類(普通名詞,固有名詞,語根)のTF-IDFを計算します.その上で,各巻次のTF-IDF上位10語を列挙します.基本的には[[korean:mecab:python_tfidf|]]のやり方と同じです.
 +
 +===== 準備 =====
 +
 +今回はMeCabを呼び出したりしないので,必要最低限のモジュールだけ呼び出します.
 +
 +<code python>
 +import glob, os
 +from sklearn.feature_extraction.text import TfidfVectorizer
 +import pandas as pd
 +</code>
 +
 +===== 読み込んだファイルの処理 =====
 +
 +読み込んだファイルについて処理する関数を定義します.出力結果は各行「表層形[タブ文字]コンマ区切りの素性」という形式なので,まず''split('\t')''で表層形と素性とを区切った後,素性に当たる部分を''split(',')''で個別の素性に分け,配列に入れます.
 +
 +素性のうち「世宗タグ」がNNG(普通名詞),NNP(固有名詞),XR(語根)に該当するものを抽出し,スペース区切りの配列にします.
 +
 +<code python>
 +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
 +</code>
 +
 +こちらも[[korean:mecab:python_tfidf|]]と同じく,普通名詞と固有名詞,語根に限定しました.
 +
 +===== ファイルの読み込みとその処理 =====
 +
 +ディレクトリ''sekbo_texts''内にあるファイルをそれぞれ読み込み,前節の処理を行います.
 +
 +<code python>
 +# 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)
 +</code>
 +
 +それぞれのファイル名を取り出して,別途配列に入れます.
 +
 +===== TF-IDFの計算と上位10語の表示 =====
 +
 +ここから後は,[[korean:mecab:python_tfidf|]]と同じ手順です.scikit-learnでTF-IDFを計算します.
 +
 +<wrap info>[2021/11\09 追記]</wrap> ''TfidfVectorizer()''の''token_pattern''を書いておかないと,古ハングルが無視されて計算されてしまいます.Unicodeの私用領域(PUA)に含まれる古ハングルを,文字コードで指定することにしました(参照:[[https://ja.wikipedia.org/wiki/%E5%8F%A4%E3%83%8F%E3%83%B3%E3%82%B0%E3%83%AB|古ハングル(Wikipedia)]]).これで合っているか分かりませんが,ともかく古ハングルが含まれた項目も計算に入るようになります.
 +
 +<code python>
 +# モデルを作成
 +vectorizer = TfidfVectorizer(smooth_idf=False, token_pattern='(?u)[\\w\\ue0bc-\\uefff\\uf100-\\uf66e\\uf784-\\uf800\\uf806-\\uf864\\uf86a-\\uf8f7]+')
 +values = vectorizer.fit_transform(docs).toarray()
 +feature_names = vectorizer.get_feature_names_out()
 +df = pd.DataFrame(values, columns = feature_names, index=titles)
 +</code>
 +
 +今回はファイル数が少ないので,全てのファイルについてTF-IDFで上位の10語を表示するようにしました.
 +
 +<code python>
 +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))
 +</code>
 +
 +結果は以下の通り(<wrap info>[2021/11/09 追記]</wrap> ''token_pattern''を変えたことで,計算結果に違いが出ましたので変更しておきます.傾向にあまり変わりはありません):
 +
 +<code text>
 +     c_sekbo_06_main_v03.txt
 +須達                  0.688172
 +舍利弗                 0.260852
 +精舍                  0.233487
 +부텨                  0.233296
 +耶輸                  0.159754
 +太子                  0.149058
 +六師                  0.147465
 +사                  0.145260
 +目連                  0.122888
 +舍衛國                 0.120090
 +         c_sekbo_09_main_v03.txt
 +有情                      0.475275
 +藥師瑠璃光如來                 0.398618
 +橫死                      0.245303
 +大願                      0.199309
 +일훔                      0.197701
 +來世                      0.183978
 +菩提                      0.183978
 +惡趣                      0.137983
 +病                       0.123366
 +文殊師利                    0.120877
 +     c_sekbo_13_main_v03.txt
 +부텨                  0.454087
 +舍利弗                 0.321053
 +佛道                  0.236824
 +菩薩                  0.224191
 +諸佛                  0.219559
 +法                   0.189619
 +사                  0.179639
 +衆生                  0.149699
 +일훔                  0.129739
 +佛乘                  0.111446
 +     c_sekbo_19_main_v03.txt
 +소리                  0.354649
 +사                  0.231608
 +香                   0.213933
 +부텨                  0.209894
 +經                   0.172931
 +菩薩                  0.171147
 +隨喜                  0.161648
 +法華經                 0.161648
 +得大勢                 0.161648
 +得                   0.159230
 +     c_sekbo_23_main_v03.txt
 +부텨                  0.322129
 +舍利                  0.289234
 +棺                   0.231640
 +供養                  0.219634
 +拘尸城                 0.204388
 +金棺                  0.204388
 +大衆                  0.178889
 +如來                  0.165945
 +사                  0.165945
 +一切                  0.161065
 +     c_sekbo_24_main_v03.txt
 +王                   0.605065
 +尊者                  0.305280
 +阿育王                 0.280858
 +부텨                  0.209953
 +사                  0.139969
 +夫人                  0.137691
 +善容                  0.134323
 +놈                   0.134323
 +太子                  0.133305
 +塔                   0.129287
 +</code>
 +
 +須達と舎利仏のストーリーが中心的な巻6,『薬師瑠璃光如来本願功徳経』の翻訳である巻9,『法華経』の翻訳である巻13,19,釈迦入滅後,舎利の扱いを論じる巻23,阿育王の話が出てくる巻24と,それぞれの特徴が示されています.
 +
 +===== 終わりに =====
 +
 +取得したデータをMeCabで処理しながら,その結果を利用するということが多いかと思いますが,既に出力結果がある場合,また出力結果を修正した正解ファイルがある場合も,簡単に処理することができます.形態素解析の結果には誤りも含まれることがあるため,正解ファイルを利用する,ということもニーズがあると思われます.
 +
 +{{indexmenu_n>206}}
korean/mecab/python_mk_tfidf.1636293614.txt.gz · 最終更新: 2021/11/07 23:00 by yoshi