20
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Hugging Faceで独自データセットを使う

Posted at

本記事は、Hugging Face (Transformers) で独自データセットを使用する 方法の備忘録的記事です。CSVファイルやpandas.DataFrameのデータを、Hugging Faceで使用するための方法を紹介します。

ちなみに、Hugging Face (Transformers)は、主に自然言語処理にて広く活用されている、ディープラーニングのライブラリです。Hugging Faceで公開されている訓練済みモデルを簡単に使用できたり、Keras/Pytorchの両方で使用できたり、便利なライブラリです。

概要

Hugging Faceには、Datasetsというパッケージがあります。
そして、その中にdatasets.Datasetクラスが存在します。
Hugging Face (Transformers) では、データセットを、このdatasets.Datasetクラスとして読み込んで使用します。

本記事は、独自データセット(csvファイルやpandas.DataFrame形式)を、datasets.Datasetクラスとして読み込む方法を紹介していく、という内容です。

主な内容:

  1. datasets.Datasetとして読み込む方法
    • csvファイルから
    • pandas.DataFrameから
  2. datasets.Featuresによるクラスラベルの指定
  3. train_test_split() によるサンプル分割

文章分類タスクを想定しています。
他のタスクでの方法は、今後追記できたらとは思います。

また、本記事の内容は、以下の、Hugging Faceのドキュメントをベースにしています。
より詳細な内容を知りたい方は、こちらをご参照ください。

Hugging Face - Datasets > Load

準備

まず、読み込むダミーデータを用意します。

フォルダ構成
./my_dataset/
    train1.csv
    train2.csv
    test.csv
train1.csv
id,text,label
0,ようやく目標が達成できそうだ,喜
1,どうしてこんな目に遭うんだ,怒
2,全然上手くいかない……,哀
3,明日から長期休暇だ,楽
... (略)

(train2.csv, test.csvは省略します。ファイル形式はtrain1.csvと同じものとします。)

csvファイルから読み込む

読み込み方法は2パターンあります。

import datasets
# 方法1
dataset_dict = datasets.load_dataset('csv', data_files=['./my_dataset/train1.csv'])
# 方法2
dataset_dict = datasets.load_dataset('./my_dataset', data_files=['train1.csv'])

また、複数ファイルを指定したり、訓練・評価ファイルを指定したりすることも可能です。

# 方法2, 複数ファイル指定
dataset_dict = datasets.load_dataset('./my_dataset', data_files=['train1.csv', 'train2.csv'])
# 方法2, 訓練・評価サンプルをそれぞれ指定
dataset_dict = datasets.load_dataset('./my_dataset', data_files={'train': 'train1.csv', 'test': 'test.csv'})

なお、これらの返値は、datasets.DatasetDictクラスとなっています。
traintestといったキーに対して、値としてdatasets.Datasetが格納されています。

print(dataset_dict) ※方法2, 訓練・評価サンプルをそれぞれ指定
DatasetDict({
    train: Dataset({
        features: ['id', 'text', 'label'],
        num_rows: 50
    }),
    test: Dataset({
        features: ['id', 'text', 'label'],
        num_rows: 20
    })
})

datasets.Datasetとして直接読み込むことも可能です。

# datasets.Datasetとして読み込む
dataset = datasets.Dataset.from_csv(['./my_dataset/train1.csv'])

他にも、csvファイル内の、必要な列だけ読み込むことも可能です。

# 方法2, 読み込む列名を指定
dataset_dict = datasets.load_dataset('./my_dataset', data_files=['train1.csv'], usecols=['text', 'label'])
print(dataset_dict)
print(dataset_dict)
DatasetDict({
    train: Dataset({
        features: ['text', 'label'],  # 'id'列が除外されている
        num_rows: 50
    })
})

pandas.DataFrameから読み込む

続いて、pandas.DataFrameからの読み込み方法です。

データセットに前処理を加えたり一部を除外したりしたい場合など、csvファイルから直接ではなく、DataFrameで処理をしてから取り込みたい、という場合があるかと思います。

df_train = pd.read_csv('./my_dataset/train1.csv')
dataset = datasets.Dataset.from_pandas(df_train[['text', 'label']])

datasets.Features を指定する

データセットの各値の「意味」を指定することで、データセットを使いやすくします。
本記事の文脈においては、labelが文章分類のクラスラベルであることを指定します。

具体的には、引数featuresに、datasets.Featuresを指定します。

# datsets.Featuresを定義
my_features = datasets.Features({
    'text': datasets.Value('string'),
    'label': datasets.ClassLabel(names=['', '', '', ''])})

# Dataset生成時に、featuresを指定
dataset_w_feat = datasets.Dataset.from_pandas(
    df_train[['text', 'label']], features=my_features)

上記では、Dataset.from_pandas()で使用していますが、load_dataset()Dataset.from_csv()でも同様に使用できます。

featuresの指定の有無で、出力を確認してみます。
labelの要素が、クラス名(文字列)から、クラス番号に変換されているのがわかります。

print(dataset.features)
# {'text': Value(dtype='string', id=None),
#  'label': Value(dtype='string', id=None),  <--- 文字列として読み込まれている

print(dataset_w_feat.features)
# {'text': Value(dtype='string', id=None),
#  'label': ClassLabel(num_classes=4, names=['喜', '怒', '哀', '楽'], id=None)}  <--- クラスラベルとして読み込まれている

print(dataset[0])
# {'text': 'ようやく目標が達成できそうだ', 'label': '喜'}

print(dataset_w_feat[0])
# {'text': 'ようやく目標が達成できそうだ', 'label': 0}  <--- クラス番号に変換されている

なお、クラス名とクラス番号は、以下の方法で相互に変換することも可能です。

dataset_w_feat.features['label'].int2str(0)    # 喜
dataset_w_feat.features['label'].str2int('')  # 1

train_test_split()によるサンプル分割

最後に、datasets.Datasetを、訓練・評価用にサンプルを分割する方法です。
train_test_split()という関数を使用します

dataset_dict = dataset_w_feat.train_test_split(test_size=0.2, shuffle=True)
print(dataset_dict)
print(dataset_dict)
DatasetDict({
    train: Dataset({
        features: ['text', 'label'],
        num_rows: 40
    })
    test: Dataset({
        features: ['text', 'label'],
        num_rows: 10
    })
})

csvファイルの時点でサンプルが分割されている場合は、前述の方法(「方法2, 訓練・評価サンプルをそれぞれ指定」)を使用します。

おわりに

Hugging Face (Transformers) にて、独自データセットを使用する方法を、一部まとめてみました。

何かしら参考になりましたら嬉しいです。
また、誤った記載やより良い方法がありましたら、ご指摘いただけますと幸いです。

最後までお読みいただきありがとうございました。
それでは!(*ˊᗜˋ)ノシ

20
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?