言語処理100本ノック 2020 (Rev2)の「第6章: 機械学習」の51本目「特徴量抽出」記録です。
「第9章: RNN, CNN」の前提だったためやりました。あまり熱心にやっておらず、以前やった「2015年版言語処理言語処理100本ノック-71(StanfordNLP使用):ストップワード」のコピペがほとんどです。今回はspacyを使うなどいくつか変更しています。
記事「まとめ: 言語処理100本ノックで学べることと成果」に言語処理100本ノック 2015についてはまとめていますが、追加で差分の言語処理100本ノック 2020 (Rev2)についても更新します。
参考リンク
リンク | 備考 |
---|---|
51.特徴量抽出.ipynb | 回答プログラムのGitHubリンク |
まとめ: 言語処理100本ノックで学べることと成果 | 言語処理100本ノックまとめ記事 |
言語処理言語処理100本ノック-71(StanfordNLP使用):ストップワード | 2015年版100本ノックの素性抽出処理 |
環境
後々GPUを使わないと厳しいので、Goolge Colaboratory使いました。Pythonやそのパッケージでより新しいバージョンありますが、新機能使っていないので、プリインストールされているものをそのまま使っています。
種類 | バージョン | 内容 |
---|---|---|
Python | 3.7.12 | Google Colaboratoryのバージョン |
2.0.3 | Google Drive連携 | |
pandas | 1.1.5 | ファイル読込や行列処理 |
spacy | 2.2.4 | 形態素解析 |
第6章: 機械学習
学習内容
『文書分類器を機械学習で構築します.さらに,機械学習手法の評価方法を学びます.
ノック内容
本章では,Fabio Gasparetti氏が公開しているNews Aggregator Data Setを用い,ニュース記事の見出しを「ビジネス」「科学技術」「エンターテイメント」「健康」のカテゴリに分類するタスク(カテゴリ分類)に取り組む.
51.特徴量抽出
学習データ,検証データ,評価データから特徴量を抽出し,それぞれtrain.feature.txt,valid.feature.txt,test.feature.txtというファイル名で保存せよ. なお,カテゴリ分類に有用そうな特徴量は各自で自由に設計せよ.記事の見出しを単語列に変換したものが最低限のベースラインとなるであろう.
回答
回答結果
訓練データの先頭10行です。Linuxのhead
コマンドで出力しています。
title category
REFILE UPDATE car sale up for sixth month as economy recover b
Amazon plan to fight FTC over Mobile App purchase t
kid still get codeine in emergency room despite Risky side effect STUDY m
what on earth happen between Solange and Jay after the Met Gala e
NATO Missile Defense be flight test over Hawaii b
NYT Publisher Sulzberger say Abramson Firing drive by conduct b
Argentina Kicillof say have process June debt payment b
the Perfect and the good on Network Neutrality t
Scarlett Johansson and Lupita Nyong'o land role in Jungle Book Adaptation e
回答プログラム 51.特徴量抽出.ipynb
GitHubには確認用コードも含めていますが、ここには必要なものだけ載せています。
import re
import pandas as pd
import spacy
from google.colab import drive
drive.mount('/content/drive')
BASE_PATH = '/content/drive/MyDrive/ColabNotebooks/ML/NLP100_2020/06.MachineLearning/'
nlp = spacy.load('en_core_web_sm')
reg_sym = re.compile(r'^[!-/:-@[-`{-~]|[!-/:-@[-`{-~]$')
reg_dit = re.compile('[0-9]')
# RNN・CNN用なので、そんなに除去しない
EXC_POS = {'PUNCT', # 句読点
'X', # その他
'SYM', # 記号
'SPACE' } # SPACE
def is_stopword(token):
lemma = reg_sym.sub('', token.lemma_)
return True if lemma == '' \
or token.pos_ in EXC_POS \
or len(lemma) == 1 \
or reg_dit.search(lemma) \
else False
def preproc_text(text):
doc = nlp(text)
return ' '.join([reg_sym.sub('', token.lemma_) for token in doc if is_stopword(token) is False])
def change_text(type_):
df = pd.read_table(BASE_PATH+type_+'.txt')
print('---'+type_+'---')
df.info()
df['title'] = df['title'].map(preproc_text)
df.to_csv(BASE_PATH+type_+'.feature.txt', sep='\t', index=False)
change_text('train')
change_text('valid')
change_text('test')
回答解説
回答の補足説明です。
形態素解析
「言語処理100本ノック-71(StanfordNLP使用):ストップワード」ではStanfordNLPを形態素解析に使っていましたが、今回はspacyを使いました。たいした理由はなく、最近仕事でspacy
使うので、少しでも慣れるためにと使いました。両者を比較して、精度などを理由として選定したわけではありません。
使い方もたいして変わりません。最初にロードします。
nlp = spacy.load('en_core_web_sm')
で、テキストを渡すだけです。
def preproc_text(text):
doc = nlp(text)
形態素解析の属性一覧です。裏でGinzaを使った場合も同じ属性になり、その辺の統一性がMeCabよりいいですね。
今回はレンマを意味するlemma_
とUniversal POS tagsを意味するpos_
を使っています。最初はnltk
パッケージを使ってStemmingもしていましたが、「84.単語ベクトルの導入」で学習済みのEmbeddingへと変換できないことに気づき、やめました。
また、除去するUniversal POS tagsも最初は多かったのですが、除去しすぎてタイトルがなくなるものもできてきて、除去対象を少なくしました。まぁ、CNNやRNNなのでそんなに除去しなくても、とも思いました。
今回、あまりこの辺りは細かい調整をしていません。
ちなみに、レンマ処理では人物の固有名詞はPRON
に変換されていました。例えばトランプ大統領だったら政治トピックなど、重要な単語もありそうで失敗したかも。後で気づきました。