web-dev-qa-db-ja.com

scikitlearnでアンダーサンプリングを実行する方法は?

病変のある眼の情報が情報の70%を構成し、非罹患の眼が残りの30%を構成する網膜データセットがあります。罹患したサンプルと罹患していないサンプルの数が同じである、データセットが必要です。私たちが同じことをすることができる助けを借りて利用可能な機能はありますか?

11
Gaurav Patil

私はこれを Pandas DataFramenumpy.random.choice 。このようにして、ランダムサンプリングを実行して、同じサイズのデータ​​セットを生成するのは簡単です。例:

import pandas as pd
import numpy as np

data = pd.DataFrame(np.random.randn(7, 4))
data['Healthy'] = [1, 1, 0, 0, 1, 1, 1]

このデータには、2つの非健康サンプルと5つの健康サンプルがあります。健康な母集団からランダムに2つのサンプルを選択するには、次のようにします。

healthy_indices = data[data.Healthy == 1].index
random_indices = np.random.choice(healthy_indices, 2, replace=False)
healthy_sample = data.loc[random_indices]

正常でないグループと同じサイズのサブサンプルを自動的に選択するには、次のようにします。

sample_size = sum(data.Healthy == 0)  # Equivalent to len(data[data.Healthy == 0])
random_indices = np.random.choice(healthy_indices, sample_size, replace=False)
16
RickardSjogren

変形として、確率論的方法を使用できます。多数のタプル_(X, Y)_であるデータセットdataがあるとします。ここで、Yは病気の目の情報(0または1)です。データセットのラッパーを準備できます。これは、すべての非罹患眼を通過し、確率0.3/0.7で罹患眼を通過します(データセットからの罹患眼の30%のみが必要です)。

_from random import random


def wrapper(data):
    prob = 0.3 / 0.7

    for X, Y in data:
        if Y == 0:
            yield X, Y
        else:
            if random() < prob:
                yield X, Y


# now you can use the wrapper to extract needed information
for X, Y in wrapper(your_dataset):
    print X, Y
_

このラッパーをジェネレーターとして何度も使用する必要があり、同じ結果が必要な場合は、関数random()を使用する前に固定ランダムシードを設定する必要があることに注意してください。詳細: https://docs.python.org/2/library/random.html

2
Fomalhaut

前に提案したように、単純なアンダーサンプリングにはnp.random.choiceを使用できますが、ランダムサンプルの一部が非常に類似しているため、データセットを誤って表現している可能性があります。

より良いオプションは、データセットのバランスをとるための複数のオプションがある imbalanced-learn パッケージを使用することです。これらの優れたチュートリアルと説明は ここ にあります。

パッケージには、(githubからの)アンダーサンプリングに適したオプションがいくつかリストされています。

  • 置換によるランダムな過半数のアンダーサンプリング
  • マジョリティ-マイノリティトメックリンクの抽出
  • クラスター重心によるアンダーサンプリング
  • ニアミス-(1&2&3)
  • 凝縮された最近傍
  • 片面選択
  • 近所の掃除のルール
  • 編集された最寄りの隣人
  • インスタンスの硬度のしきい値
  • 繰り返される編集された最も近い隣人
  • AllKNN
1
ege