- 自然言語処理の試行につけてはコーパス(まとまった量のテキスト)が必要になります。
- しばしば利用させていただく『青空文庫』は、近代文学など著作権が切れた作品のテキストを公開しているインターネット上の図書館です。
- 自然言語処理の素材として『青空文庫』から作品を取得し、コーパス用に加工する手順を整理しておきます。
##1. ファイルを取得して本文のみ抽出
###⑴ 各種モジュールのインポート
import re
import zipfile
import urllib.request
import os.path
import glob
-
re
:Regular Expressionの略で、正規表現の操作をするためのモジュール -
zipfile
:zipファイルを操作するためのモジュール -
urllib.request
:インターネット上のリソースを取得するためのモジュール -
os.path
:パス名を操作するためのモジュール -
glob
:ファイルパス名を取得するためのモジュール
###⑵ ファイルパスの取得
ここでは、宮沢賢治の『銀河鉄道の夜』を素材とします。
- 『青空文庫』のトップページ右上の検索ボックスに「宮沢賢治」を入力して検索。
- 検索結果の最上位に挙がる「作家別作品リスト:宮沢 賢治」から当該ページに遷移。
- リストの中から「59. 銀河鉄道の夜(新字新仮名、作品ID:43737)」を選択。
- 遷移先の「図書カード:No.43737」を下へ「ファイルのダウンロード」までスクロール。
- ファイル名(リンク)欄のzipファイル名を右クリックして「リンクのアドレスをコピー」を選択。
URL = 'https://www.aozora.gr.jp/cards/000081/files/43737_ruby_19028.zip'
###⑶ zipファイルを取得・解凍するメソッド
def download(URL):
zip_file = re.split(r'/', URL)[-1] #➀
urllib.request.urlretrieve(URL, zip_file) #➁
dir = os.path.splitext(zip_file)[0] #➂
with zipfile.ZipFile(zip_file) as zip_object: #➃
zip_object.extractall(dir) #➄
os.remove(zip_file) #➅
path = os.path.join(dir,'*.txt') #➆
list = glob.glob(path) #➇
return list[0] #➈
1) zipファイルのダウンロード
- ➀
re.split()
:URLの文字列を/
で区切り、末尾のzipファイル名「43737_ruby_19028.zip」を取得。 - ➁
urllib.request.urlretrieve(URL, 保存名)
:当該サイトから直接ファイルをダウンロードし、zipファイル名「43737_ruby_19028.zip」で保存。 - ➂
os.path.splitext()
:zipファイル名をドット「.」で分割し、拡張子なしのファイル名dir
を取得。
2) zipファイルの解凍と保存
- ➃
zipfile.ZipFile()
:先に保存したzipファイルを読み込んで、zipオブジェクトを作成し、 - ➄
extractall()
:zipオブジェクトの中身をすべて、ディレクトリdir
に展開。 - ➅
os.remove()
:解凍前のzipファイルを削除。
3) 保存したファイルのパスを取得
- ➆
os.path.join()
:dir
のパス文字列を生成。 - ➇
glob.glob()
: ディレクトリ内のテキストファイル名をすべて出力してリスト化。 - ➈
list[0]
: リスト内の一番目のファイルのパスを返す。
###⑷ ファイル読み込み・本文を抽出するメソッド
def convert(download_text):
data = open(download_text, 'rb').read() #➀
text = data.decode('shift_jis') #➁
# 本文抽出
text = re.split(r'\-{5,}', text)[2] #➂
text = re.split(r'底本:', text)[0] #➃
text = re.split(r'[#改ページ]', text)[0] #➄
# ノイズ削除
text = re.sub(r'《.+?》', '', text) #➅
text = re.sub(r'[#.+?]', '', text) #➆
text = re.sub(r'|', '', text) #➇
text = re.sub(r'\r\n', '', text) #➈
text = re.sub(r'\u3000', '', text) #➉
return text
1) ファイルの読み込み
- ①
open(ファイル名, 'rb').read()
:当該ファイルを'rb'
(バイナリモード)で読み込む。 - ②
decode('shift_jis')
:shift_jis
に従ってデコードし、テキストを取得。
2) re.split()
による本文の抽出
- ➂
(r'\-{5,}', text)[2]
:ハイフン「-」を5回以上くり返す部分を削除し、これを区切り文字として分割されたうちの3番目の要素を取り出す。 - ④
(r'底本:', text)[0]
:「底本:」を削除し、これを区切り文字として分割されたうちの1番目の要素を取り出す。 - ➄
(r'[#改ページ]', text)[0]
:「[#改ページ]」を削除し、これを区切り文字として分割されたうちの1番目の要素を取り出す。
3) re.sub()
によるノイズの削除(置換)
- ➅
'《.+?》'
:《ルビ》 - ➆
'[#.+?]'
:[注記] - ➇
'|'
:ルビ付き文字列の開始位置 - ➈
'\r\n'
:改行コード - ➉
'\u3000'
:全角スペース
###⑸ ファイル取得と本文抽出の実行
download_file = download(URL)
text = convert(download_file)
print(text)
##2. MeCabによる「分かち書き」
###⑹ MeCabのインストール、分かち書き
!apt install aptitude
!aptitude install mecab libmecab-dev mecab-ipadic-utf8 git make curl xz-utils file -y
!pip install mecab-python3==0.7
-
MeCab.Tagger()
というクラスに引数を-Owakati
としてインスタンスを生成し、さらにparse()
というメソッドを呼ぶことで結果が文字列として取得できます。
import MeCab
mecab = MeCab.Tagger("-Owakati")
text = mecab.parse(text)
print(text)
- さらに
split()
で、空白を区切り文字として文字列を分割します。
separated_text = text.split()
print(separated_text)
##3. ローカルPCにダウンロードするなら
###⑺ ファイル化してローカルPCに取得
- 分かち書きにした状態のテキストを、ローカルPCにダウンロードします。
with open('output.txt', 'w') as f:
f.write(text)
-
text
を'output.txt'
というファイルに書き出します。引数の'w'
は書き込みモードの指定です。
from google.colab import files
files.download('output.txt')
-
files
は、ColaboratoryとローカルPCとの間でファイルをアップロードないしダウンロードするためのモジュールです。 - ダウンロード後のテキストファイルを示します。文中のルビや脚注などの不要部分は取り除かれ、分かち書きにした本文のみとなっています。