u++の備忘録

言語処理100本ノック 2020「50. データの入手・整形」

問題文

nlp100.github.io

問題の概要

本章では、ニュース記事の見出しからカテゴリを分類する機械学習モデルを構築します。最初に指示に従ってデータセットを整形します。次の4段階で処理しました。

  1. ファイルのデータ形式の確認
  2. 情報源(publisher)が”Reuters”, “Huffington Post”, “Businessweek”, “Contactmusic.com”, “Daily Mail”の事例(記事)のみを抽出
  3. 抽出された事例をランダムに並び替え
  4. 抽出された事例の80%を学習データ,残りの10%ずつを検証データと評価データに分割し,それぞれtrain.txt,valid.txt,test.txtというファイル名で保存

1について、提供されているデータセットにはheaderがありません。そのため読み込み時には「header=None」を指定し、後に「pandas.DataFrame.columns」でカラム名を定義しています。

2については「pandas.Series.isin()」を利用しました。同時に「pandas.Series.sample(frac=1)」で値をランダムに並び替えています。「pandas.Series.sample()」はデータセットから指定した割合を抽出する処理で、抽出率を100%にすることでランダム並び替えと同等の処理になります。

後に機械学習アルゴリズムに投入するための前処理として、目的変数(予測の対象)のカラムの値は「map」を用いて数値に変換しています。

最後に4について「train_test_split()」を用いてデータセットを分割しました。「stratify」で目的変数の値を指定することで、分割後の目的変数の割合が等しくなるように設定しています。この分割方法は、機械学習アルゴリズムを検証する上で一般的です*1

import pandas as pd
from sklearn.model_selection import train_test_split


newsCorpora = pd.read_table('ch06/NewsAggregatorDataset/newsCorpora.csv', header=None)
newsCorpora.columns = ['ID', 'TITLE', 'URL', 'PUBLISHER', 'CATEGORY', 'STORY', 'HOSTNAME', 'TIMESTAMP']
newsCorpora = newsCorpora[newsCorpora['PUBLISHER'].isin(
    ['Reuters', 'Huffington Post', 'Businessweek', 'Contactmusic.com', 'Daily Mail'])].sample(frac=1, random_state=0)

X = newsCorpora[['TITLE', 'CATEGORY']].copy()
X['CATEGORY'] = X['CATEGORY'].map({'b': 0, 'e': 1, 't': 2, 'm': 3})
y = newsCorpora['CATEGORY']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y, random_state=0)
X_valid, X_test, y_valid, y_test = train_test_split(X_test, y_test, test_size=0.5, stratify=y_test, random_state=0)

X_train.to_csv('ch06/train.txt', sep='\t', index=False, header=None)
X_valid.to_csv('ch06/valid.txt', sep='\t', index=False, header=None)
X_test.to_csv('ch06/test.txt', sep='\t', index=False, header=None)