以下の内容はhttps://pydocument.hatenablog.com/entry/2023/10/06/210619より取得しました。


機械学習におけるデータ拡張(Data Augmentation)とその実践(Pythonによる実装)

機械学習モデルの性能向上に不可欠なデータ拡張(Data Augmentation) について、基本的な考え方から具体的な手法、Pythonでの実装例までを解説します。ここでは、理論と実践の両面からデータ拡張を理解することを目的とします。

データ拡張とは

データ拡張は、限られた訓練データから、人為的にデータのバリエーションを増やすことで、モデルの汎化性能を高め、過学習を抑制するテクニックです。特に、画像認識、自然言語処理音声認識などの分野で広く利用されています。

データ拡張の必要性

データ拡張が重要視される主な理由は以下の通りです。

  • 汎化性能の向上: モデルが未知のデータに対して正しく予測を行うためには、多様なパターンのデータで学習する必要があります。データ拡張は、データの多様性を擬似的に作り出し、モデルの汎化性能を向上させます。
  • 過学習の抑制: 訓練データが少ない場合、モデルは訓練データに過剰に適合し、未知のデータに対する性能が低下することがあります(過学習)。データ拡張により、モデルが学習するデータの量を増やすことで、過学習を抑制できます。
  • ロバスト性の向上: 現実世界のデータは、ノイズや歪み、多様な環境条件を含んでいます。データ拡張によって、これらの変動をシミュレートすることで、モデルのロバスト性を高めることができます。

補足: ロバスト

ロバスト性とは、「システムやモデルが、想定外の状況やノイズ、多少のデータの変化に対して、どれだけ強く、安定して動作するか」 を表す性質です。日本語では「頑健性」と表現します。

画像認識AIを例に挙げると

  • ロバスト性が低い場合
    • 写真が少し暗いだけで、写っているものを認識できなくなる。
    • 画像に少しノイズが入ると、誤った判断をしてしまう。
    • いつもと違う角度から撮影された写真だと、全く認識できない。
  • ロバスト性が高い場合
    • 写真が多少暗くても、明るさを自動で調整して認識できる。
    • 画像に多少のノイズが入っていても、正しく判断できる。
    • 様々な角度から撮影された写真でも、ある程度は認識できる。

このように、ロバスト性が高いシステムやモデルは、「多少のイレギュラーな状況にも対応できる」 というイメージです。

データ拡張の具体的な手法

データ拡張の手法は、扱うデータの種類(画像、テキスト、音声など)によって異なります。ここでは、それぞれのデータタイプに対する主要な手法を紹介します。

画像データのデータ拡張

画像データに対するデータ拡張は、最も一般的かつ多様な手法が存在します。

手法 説明
幾何学的変換
回転 (Rotation) 画像をランダムな角度で回転させます。
反転 (Flip) 画像を水平または垂直方向に反転させます。
切り抜き (Crop) 画像の一部をランダムに切り取ります。
シフト (Shift) 画像を水平または垂直方向に平行移動させます。
ズーム (Zoom) 画像を拡大または縮小します。
シアー (Shear) 画像を斜め方向に変形させます。
色調変換
明度変更 (Brightness) 画像全体の明るさを調整します。
コントラスト変更 (Contrast) 画像のコントラストを調整します。
彩度変更 (Saturation) 画像の彩度を調整します。
色相変更 (Hue) 画像の色相を調整します。
その他
ノイズ付加 (Noise) ランダムなノイズを画像に加えます。
ガウシアンブラー (Gaussian Blur) 画像にガウシアンフィルタを適用し、ぼかし効果を与えます。

テキストデータのデータ拡張

テキストデータに対するデータ拡張は、主に自然言語処理NLP)の分野で用いられます。

手法 説明
同義語置換 (Synonym Replacement) 文中の単語を、意味が近い同義語に置き換えます。
ランダム挿入 (Random Insertion) 文中にランダムな単語を挿入します。
ランダム削除 (Random Deletion) 文中の単語をランダムに削除します。
ランダムスワップ (Random Swap) 文中の2つの単語の位置をランダムに入れ替えます。
バックトランスレーション (Back Translation) 文を別の言語に翻訳し、再度元の言語に戻すことで、元の文とは異なる表現の文を生成します。

音声データのデータ拡張

音声データに対するデータ拡張は、音声認識音声合成などのタスクで利用されます。

手法 説明
速度変更 (Speed Perturbation) 音声の再生速度を変更します。
ピッチ変更 (Pitch Shifting) 音声のピッチ(音の高さ)を変更します。
ノイズ付加 (Noise Injection) 環境音や背景ノイズなどのランダムなノイズを音声に加えます。
時間伸縮 (Time Stretching) 音声の長さを変更します(速度変更とは異なり、ピッチは保持されます)。
音量変更 (Volume Perturbation) 音声の音量を変更します。

Pythonによるデータ拡張の実装例

ここでは、tensorflow.kerasnltk ライブラリを使用して、画像データとテキストデータに対するデータ拡張の簡単な実装例を示します。

画像データのデータ拡張 (ImageDataGenerator)の例

このコードでは、example.jpgという画像ファイルを読み込み、ImageDataGeneratorを使って様々な変換を施し、結果を4枚の画像として表示します。

import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img, img_to_array, array_to_img

# 画像の読み込み
img_path = 'example.jpg'  # 画像ファイルへのパス
img = load_img(img_path, target_size=(150, 150))  # サイズを揃える

# ImageDataGenerator の設定
datagen = ImageDataGenerator(
    rotation_range=40,       # ランダムに回転する角度の範囲 (0-180)
    width_shift_range=0.2,  # 水平方向のシフト範囲 (画像幅に対する割合)
    height_shift_range=0.2, # 垂直方向のシフト範囲 (画像高さに対する割合)
    shear_range=0.2,        # シアー変換の角度 (ラジアン)
    zoom_range=0.2,         # ランダムにズームする範囲
    horizontal_flip=True,   # 水平方向にランダムに反転
    fill_mode='nearest'     # 変換後の画像の空いたピクセルを埋める方法
)

# 画像を配列に変換し、次元を調整
x = img_to_array(img)  # (150, 150, 3) のNumPy配列
x = np.expand_dims(x, axis=0) # (1, 150, 150, 3) に変形

# データ拡張の実行と結果の表示
i = 0
for batch in datagen.flow(x, batch_size=1):
    plt.figure(i)
    imgplot = plt.imshow(array_to_img(batch[0]))
    i += 1
    if i % 4 == 0:  # 4枚の画像を生成したら終了
        break
plt.show()

テキストデータのデータ拡張 (NLTK)の例

このコードでは、nltkライブラリのwordnetを使用して、入力テキスト内の単語を同義語に置き換えることでデータ拡張を行います。

import nltk
import random
from nltk.corpus import wordnet

# NLTKリソースのダウンロード (初回のみ)
# nltk.download('punkt')
# nltk.download('wordnet')
# nltk.download('omw-1.4')
# nltk.download('averaged_perceptron_tagger')

def synonym_replacement(text, n=1):
    """同義語置換によるデータ拡張"""
    words = nltk.word_tokenize(text)
    new_words = words.copy()
    random_word_list = list(set([word for word in words if wordnet.synsets(word)])) # 同義語が存在する単語
    random.shuffle(random_word_list)
    num_replaced = 0
    for random_word in random_word_list:
      synonyms = get_synonyms(random_word)
      if len(synonyms) >= 1:
        synonym = random.choice(list(synonyms))
        new_words = [synonym if word == random_word else word for word in new_words]
        num_replaced += 1
      if num_replaced >= n:
        break

    sentence = ' '.join(new_words)
    return sentence

def get_synonyms(word):
    """単語の同義語を取得"""
    synonyms = set()
    for syn in wordnet.synsets(word):
        for l in syn.lemmas():
            synonym = l.name().replace("_", " ").replace("-", " ").lower()
            synonym = "".join([char for char in synonym if char in ' qwertyuiopasdfghjklzxcvbnm'])
            synonyms.add(synonym)
    if word in synonyms:
        synonyms.remove(word)
    return list(synonyms)

# サンプルテキスト
text = "The quick brown fox jumps over the lazy dog."

# データ拡張の実行
augmented_text = synonym_replacement(text, n=3)  # 3つの単語を同義語に置換
print(f"元の文: {text}")
print(f"拡張された文: {augmented_text}")

このサンプルコードでは、get_synonyms関数の中で、同義語として取得した単語をさらにフィルタリングしています。これにより、より自然な文を生成することが期待できます。必要に応じて、nltk.download()を実行し、必要なリソースをダウンロードしてください。上記はあくまで一例ですので、より高度なテキストデータ拡張には、専門のライブラリ(nlpaugなど)を使用することも検討してください。

データ拡張の注意点

データ拡張はデータが限られている際に有効な手法になりますが、やりすぎには注意が必要です。

  • 過度な拡張は逆効果: データ拡張を過度に行うと、モデルが現実には存在しないようなデータパターンを学習してしまい、性能が低下する可能性があります。
  • タスクとデータの特性を考慮: データ拡張の手法は、タスクの性質やデータの種類によって適切に選択する必要があります。例えば、医療画像に対して、左右反転が常に適切とは限りません(臓器の位置が左右逆になることは通常ないため)。
  • ラベルの整合性を保つ: データ拡張を行う際には、データのラベル(正解データ)との整合性を保つ必要があります。例えば、画像分類タスクで画像を回転させた場合、ラベルもそれに合わせて変更する必要がある場合があります。

実務で役立つPython機械学習入門 課題解決のためのデータ分析の基礎 [ 池田 雄太郎 ]

まとめ

データ拡張は、機械学習モデルの性能を向上させるための重要なテクニックです。本稿では、データ拡張の基本的な概念、様々なデータタイプに対する具体的な手法、Pythonでの実装例、そして注意点について解説しました。

データ拡張を効果的に活用することで、モデルの汎化性能、ロバスト性を高め、より実用的な機械学習システムを構築することが可能になります。

最後にUdemyのPythonによる機械学習の学習のオンラインコースを紹介します。

click.linksynergy.com

click.linksynergy.com

Pythonではじめる機械学習 scikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎 [ Andreas C. Muller ]




以上の内容はhttps://pydocument.hatenablog.com/entry/2023/10/06/210619より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14