検索
連載

[文章生成]MeCabをインストールして分かち書きを試してみよう作って試そう! ディープラーニング工作室(2/2 ページ)

形態素解析エンジン「MeCab」をGoogle Colab上にインストールして、簡単なテキストを解析したり、分かち書きをしたりできるようにしてみる。

PC用表示 関連情報
Share
Tweet
LINE
Hatena
前のページへ |       

mecab-unidic-NEologdのインストール

 mecab-unidic-NEologdは、先ほどインストールしたUniDicに含まれていない語句も採録しているので、これを使えば「鬼滅の刃」もうまく単語として認識されるかもしれません。

 なお、これをインストールするには、mecab-python3に同梱のMeCabに頼らずに、きちんとMeCabをインストールする必要があるようです。というわけで、Webを検索して「Google ColabにMeCabとipadic-NEologdをインストールする」を参考に以下のコードを実行することで、MeCabとmecab-unidic-NEologdをインストールしました(主に「ipa」を「uni」にしたり、インストール時の出力の破棄をやめたりするなどの変更を行っています)。

!apt-get -q -y install mecab libmecab-dev file
!git clone --depth 1 https://github.com/neologd/mecab-unidic-neologd.git
!echo yes | mecab-unidic-neologd/bin/install-mecab-unidic-neologd -n

MeCabとmecab-unidic-NEologdをインストール

 このコマンドを実行すると、MeCabとmecab-unidic-NEologdのインストールが完了します。ここで重要なのは辞書がインストールされる場所です。これは出力の最後の方に次のように表示されています。

実行結果
実行結果

 上の画像の真ん中付近に「Usage:」という出力があります。その下にある「$ mecab -d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-unidic-neologd」というのはMeCabをコマンドラインから実行する際の辞書指定です。ここで指定している、「-d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-unidic-neologd」オプションをMeCab.Taggerクラスのインスタンス生成時に指定します(「!mecab-config --dicdir」コマンドを実行することでも確認できます)。ここでは2つのインスタンスを生成して、振る舞いの違いを見てみましょう。

tagger1 = MeCab.Tagger()
dicdir = '-d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-unidic-neologd'
tagger2 = MeCab.Tagger(dicdir)

sample_txt = '鬼滅の刃もいいけれど、約束のネバーランドもね'
print(tagger1.parse(sample_txt))
print(tagger2.parse(sample_txt))

辞書の違いを確認する

 実行結果を見てください。

実行結果
実行結果

 上側の出力がMeCab.Taggerクラスのインスタンス生成で何も指定しなかった場合の結果で、下側の出力がmecab-unidic-NEologd辞書を使うように指定した場合の結果です。ご覧の通り、mecab-unidic-NEologdを使用した方では、2つの作品名がきちんと名詞(固有名詞)として認識されたことが分かります。

 確認のために分かち書きもしてみましょう。

wakati1 = MeCab.Tagger('-Owakati')
dicdir = '-d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-unidic-neologd'
wakati2 = MeCab.Tagger('-Owakati ' + dicdir)

sample_txt = '鬼滅の刃もいいけれど、約束のネバーランドもね'
print(wakati1.parse(sample_txt))
print(wakati2.parse(sample_txt))

辞書の違いを確認する

 実行結果を以下に示します。

実行結果
実行結果

 先ほどと同様、上の出力がデフォルトのもので、下の出力がmecab-unidic-NEologd辞書を使ったものです。うまい具合に分かち書きができていることが分かります。

 これで梶井基次郎の著作データに対して、形態素解析を行う準備が整いました。次回はこれらを組み合わせて、日本語の文章を生成してみることにします。

スクレイピングについて

 前回の記事に関して「青空文庫とかWikipediaとか、わざわざ別にダンプなどをとれるところからスクレイピングという負荷をかけるやりかたをしてあげないでほしい」などのコメントをいただきました(ご指摘ありがとうございました)。この指摘は全く正しいことから、本稿の最後に青空文庫のGitHubリポジトリから梶井基次郎の著作データを(HTMLファイル、ZIPファイルなど、一括で)Google Colab上にコピーして、そのうちのZIPファイルに格納されているテキストファイルを対象に前回と同様な処理を行うコードを掲載します。

 こちらのコードでは、ZIPファイルの一覧を作成して、各ZIPファイルをテキストファイルへと展開した後、そのデータを読み込んでルビなど(前回削除していたものに追加した文字列の並びもあります)を削除する処理を行い、1文ごとに分割をした結果を最後にテキストファイルに書き込むようにしてあります。次回以降はこのコードを使って作成したテキストデータを使っていく予定です(なお、このコード自体は今回のノートブックには含まれていません)。

!sudo apt-get install subversion
!svn checkout https://github.com/aozorabunko/aozorabunko/trunk/cards/000074from zipfile import ZipFile
import os
import re
import glob

zipped_files = glob.glob('./files/*.zip')
for file in zipped_files:
    with ZipFile(file, 'r') as tmp:
        tmp.extractall()

from zipfile import ZipFile
import os
import re
import glob

zipped_files = glob.glob('./files/*.zip')
for file in zipped_files:
    with ZipFile(file, 'r') as tmp:
        tmp.extractall()

def make_txt_data(file):
    with open(file, 'rb') as f:
        bin_data = f.read()
        txt_data = bin_data.decode('shiftjis'# シフトJISをUTF-8にデコード
    
    try:
        txt_data = re.split('-{10,}', txt_data)[2]
        txt_data = txt_data.split('底本')[0]
        txt_data = txt_data.replace('|', '')
        txt_data = re.sub('《.*?》', '', txt_data)
        txt_data = re.sub('[#中見出し].*?[#中見出し終わり]', '', txt_data)
        txt_data = re.sub('[#.*?]', '', txt_data)
        txt_data = txt_data.replace('「', '').replace('」', '\n')
        txt_data = txt_data.replace('\r', '').replace('\n', '').replace('\u3000', '')
        txt_data = re.sub('([。!?])', r'\1\n', txt_data)
        txt_data = txt_data.split('\n')
    except Exception as e: # 手抜き例外処理。置換に失敗したファイルの内容は捨てる
        print(f'not processed: {file} by {e}')
        txt_data = []  # 処理しないで関数を終了。戻り値は空のリストとする
    return txt_data

txt_files = glob.glob('*.txt')
txt_list = []
for file in txt_files:
    result = make_txt_data(file)
    txt_list.extend(result)  # txt_list.extend([])は何も追加しない

for file in txt_files:
    os.remove(file)

with open('kajii.txt', 'wt') as f:
    f.writelines([line + '\n' for line in txt_list])



「作って試そう! ディープラーニング工作室」のインデックス

作って試そう! ディープラーニング工作室

Copyright© Digital Advantage Corp. All Rights Reserved.

前のページへ |       
[an error occurred while processing this directive]
ページトップに戻る