DEV Community

Keita Onabuta
Keita Onabuta

Posted on • Edited on

BERTによる日本語テキスト分類 (Azure)

This is Japanese article.

GitHub logo konabuta / AzureML-NLP

NLP for japanese language text.

AzureML-NLP

本リポジトリでは、Azure Machine Learning を利用した日本語の自然言語処理 NLP モデル構築のサンプルコードを提供します。Microsoft の NLP Best Practice を参考にしています。

コンテンツ

シナリオ モデル 概要 対応言語
テキスト分類 BERT テキストのカテゴリーを学習・推論する教師付き学習です。 Japanese

Get started

最初は Azure Cognitive Service の利用検討を推奨します。この学習済みのモデルで対応できない場合は、カスタムで機械学習モデルを構築する必要がございます。まず、Setup を参照し、必要なライブラリを導入してください。




Microosft が公開している自然言語処理のベストプラクティス集 "NLP Best Practices" をベースにした日本語テキスト分類のサンプルコードを作成しました。

本家と大きく違う点は下記です。

  • 日本語の BERT Tokenizer を利用する
    • Mecab (+辞書) のダウンロードとインストールの手順を追加
  • 日本語 PreTrained モデル を利用する
  • サンプルデータとして Livedoor ニュースを利用

Mecabの辞書の導入が複雑なので本家とマージするかはまだ未定です。

コード(※抜粋)はこちらです。

1. Livedoor コーパスのデータ加工

# Livedoor ニュースコーパスをダウンロードして利用します。 from urllib.request import urlretrieve import tarfile text_url = "https://www.rondhuit.com/download/ldcc-20140209.tar.gz" file_path = "./ldcc-20140209.tar.gz" urlretrieve(text_url, file_path) # gz ファイルを解凍します。 with tarfile.open('./ldcc-20140209.tar.gz', 'r:gz') as tar: tar.extractall(path='livedoor') tar.close() 
Enter fullscreen mode Exit fullscreen mode
# Pandas Dataframe を作成します。 for folder_name in os.listdir(path): print(folder_name) if folder_name.endswith(".txt") : continue for file in os.listdir(os.path.join(path, folder_name)): if folder_name == "LICENSE.txt" : continue with open(os.path.join(path, folder_name, file), 'r') as f: lines = f.read().split('\n') if len(lines) == 1: continue url = lines[0] date = lines[1] label = folder_name title = lines[3] text = "".join(lines[4:]) data = {'url': url, 'date':date, 'label': label, 'title':title, 'text':text} s = pd.Series(data) df = df.append(s, ignore_index=True) 
Enter fullscreen mode Exit fullscreen mode

2. ファインチューニング

準備されている関数 util_nlp を利用します。

classifier = SequenceClassifier( model_name=model_name, num_labels=num_labels, cache_dir=CACHE_DIR ) with Timer() as t: classifier.fit( train_dataloader, num_epochs=NUM_EPOCHS, num_gpus=NUM_GPUS, verbose=False, ) train_time = t.interval / 3600 
Enter fullscreen mode Exit fullscreen mode

精度確認を確認します。

# テストデータの予測 preds = classifier.predict(test_dataloader, num_gpus=NUM_GPUS, verbose=False) # 評価 accuracy = accuracy_score(df_test[LABEL_COL], preds) class_report = classification_report( df_test[LABEL_COL], preds, target_names=label_encoder.classes_, output_dict=True ) 
Enter fullscreen mode Exit fullscreen mode

最終的な精度は 85% ぐらいでした。

  • accuracy : 0.866052
  • f1-score : 0.858849

Top comments (0)