http://scikit-learn.org/0.18/modules/multiclass.html を google翻訳した
scikit-learn 0.18 ユーザーガイド 1. 教師付き学習 より
1.12. 多クラスアルゴリズムと多ラベルアルゴリズム
警告:scikit-learnのすべての分類器は、すぐに使用できる多クラス分類を行います。 さまざまな多クラス戦略を試していない限り、sklearn.multiclassモジュールを使用する必要はありません。
sklearn.multiclass モジュールは、多クラスと多ラベル分類問題を解決するために、バイナリ分類問題にこのような問題を分解してメタ推定を実現します。 マルチターゲット回帰もサポートされています。
- 多クラス分類 とは、2つ以上のクラスを持つ分類タスクを意味します。例えば、オレンジ、リンゴまたはナシであり得る果実の画像のセットを分類することができる。多クラス分類は、各サンプルが1つの唯一のラベルに割り当てられていることを前提にしています。果物はリンゴかナシのどちらかですが、同時に両方ではありません。
- 多ラベル分類 は、各サンプルにターゲットラベルのセットを割り当てる。これは、ドキュメントに関連するトピックなど、相互に排他的ではないデータポイントのプロパティを予測するものと考えることができます。テキストは、宗教、政治、財政、教育のいずれかと同時に、あるいはこれらのいずれでもないことがあります。
- マルチ出力回帰 は、各サンプルに目標値のセットを割り当てます。これは、特定の場所での風の方向や大きさなど、各データポイントのいくつかのプロパティを予測するものと考えることができます。
- マルチ出力 - 多クラス分類 と マルチタスク分類 は、単一の推定器が複数の共同分類タスクを処理しなければならないことを意味します。これは、多クラス分類タスクの一般化だけでなく、バイナリ分類も考慮する多ラベル分類タスクの一般化である。出力フォーマットは、2次元の配列または疎行列です。
ラベルのセットは、出力変数ごとに異なる場合があります。 例えば、「梨」、「リンゴ」などの種の有限集合で可能な値をとる出力変数に対して、サンプルに「梨」を割り当てることができます。 「緑」、「赤」、「青」、「黄」などの有限の色のセットで可能な値をとる第2の出力変数の「青」または「緑」...
これは、マルチ出力の多クラスタスクまたはマルチタスク分類タスクを処理する任意の分類器が、特別なケースとして多ラベル分類タスクをサポートすることを意味する。 マルチタスク分類は、異なるモデルの形式を用いたマルチ出力分類タスクに似ています。 詳細については、該当する推定器のドキュメントを参照してください。
すべてのscikit-learn分類器は多クラス分類が可能ですが、sklearn.multiclassが提供するメタ推定器は、2つ以上のクラスを処理する方法を変更することができます。これは、(一般化誤差または必要な計算資源の観点から)分類器の性能に影響を与える可能性があるからです。
以下は、戦略によってグループ化されたscikit-learnでサポートされている分類器の概要です。カスタムの多クラス動作を必要としない限り、これらのいずれかを使用している場合は、このクラスのメタ推定ツールは必要ありません。
- 本質的にマルチクラス:Naive Bayes、LDAとQDA、決定木、ランダムフォレスト、最近傍法、sklearn.linear_model.LogisticRegression で
multi_class = 'multinomial'
を設定する。 - マルチラベルサポート:決定木、ランダムフォレスト、最近傍法。
- One-Vs-One:sklearn.svm.SVC。
- One-Vs-All:sklearn.svm.SVCを除くすべての線形モデル。
一部の推定器は、マルチ出力 - マルチクラス分類タスクをサポートしています。決定木、ランダムフォレスト、最近傍法。
警告: 現在、sklearn.metrics のメトリックは、マルチ出力 - マルチクラス分類タスクをサポートしていません。
1.12.1. 多ラベル分類フォーマット
多ラベル学習では、バイナリ分類タスクのジョイントセットは、ラベルバイナリインジケータ配列で表されます。各サンプルは、バイナリ値を持つ2次元配列(n_samples,n_classes)の1行です。つまり、非ゼロ要素です。 ラベルのサブセット np.array([[1,0,0],[0,1,1],[0,0,0]])
などの配列は、最初のサンプルのラベル0、2番目のサンプルのラベル1および2 、第3のサンプルにはラベルがない。ラベルのセットのリストとしてマルチラベルデータを生成する方が直感的です。 MultiLabelBinarizer トランスフォーマーを使用すると、ラベルのコレクションとインジケータ形式を変換できます。
>>> from sklearn.preprocessing import MultiLabelBinarizer
>>> y = [[2, 3, 4], [2], [0, 1, 3], [0, 1, 2, 3, 4], [0, 1, 2]]
>>> MultiLabelBinarizer().fit_transform(y)
array([[0, 0, 1, 1, 1],
[0, 0, 1, 0, 0],
[1, 1, 0, 1, 0],
[1, 1, 1, 1, 1],
[1, 1, 1, 0, 0]])
1.12.2. One-Vs-The-Rest
この戦略は One-VS All として知られており、OneVsRestClassifier で実装されています。戦略は、クラスごとに1つの分類器を適合させることにある。各分類器について、そのクラスは他のすべてのクラスに適合する。その計算効率に加えて(n_classes
分類器だけが必要です)、このアプローチの1つの利点は、その解釈可能性です。各クラスは1つの唯一の分類器によって表されるので、対応する分類子を検査することによってそのクラスに関する知識を得ることが可能である。これは最も一般的に使用される戦略であり、公正なデフォルト選択です。
1.12.2.1. マルチクラス学習
以下は、OvRを使用したマルチクラス学習の例です。
>>> from sklearn import datasets
>>> from sklearn.multiclass import OneVsRestClassifier
>>> from sklearn.svm import LinearSVC
>>> iris = datasets.load_iris()
>>> X, y = iris.data, iris.target
>>> OneVsRestClassifier(LinearSVC(random_state=0)).fit(X, y).predict(X)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])
1.12.2.2. マルチラベル学習
OneVsRestClassifierはマルチラベル分類もサポートしています。この機能を使用するには、セル[i、j]がサンプルiのラベルjの存在を示すインジケータ行列を分類器に送ります。
- 例:
1.12.3. One-Vs-One
OneVsOneClassifier は、クラスのペアごとに1つの分類子を構築します。 予測時には、最も投票を受けたクラスが選択されます。 (同数の投票数を有する2つのクラスの中で)同点の場合、基礎となるバイナリ分類器によって計算された対ごとの分類信頼度レベルを加算することによって、最も高い総計分類信頼度を有するクラスを選択する。
n_classes *(n_classes - 1)/ 2
の分類子を適合させる必要があるので、このメソッドは通常、そのO(n_classes ^ 2)の複雑さのため、 one-vs-the-rest よりも遅くなります。 しかしながら、この方法は、n_samples
にうまく適合しないカーネルアルゴリズムのようなアルゴリズムにとって有利であり得る。 これは、個々の学習問題がデータの小さなサブセットのみを含むのに対し、1対の残りの場合、完全なデータセットはn_classes回使用されるからです。
1.12.3.1. マルチクラス学習
以下は、OvOを使用したマルチクラス学習の例です。
>>> from sklearn import datasets
>>> from sklearn.multiclass import OneVsOneClassifier
>>> from sklearn.svm import LinearSVC
>>> iris = datasets.load_iris()
>>> X, y = iris.data, iris.target
>>> OneVsOneClassifier(LinearSVC(random_state=0)).fit(X, y).predict(X)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])
- 参考文献:
- [1] "パターン認識と機械学習。 Springer "、Christopher M. Bishop、page 183、(第1版)
1.12.4. エラー訂正出力コード
Output-code ベースの戦略は、one-vs-the-rest や one-vs-one とはかなり異なる。これらの戦略では、各クラスはユークリッド空間で表現され、各次元は0または1のみです。別の方法として、各クラスはバイナリコード(0と1の配列)で表されます。各クラスの位置/コードを追跡する行列は、コードブックと呼ばれます。コードサイズは前述の空間の次元数です。直感的には、各クラスはできるだけユニークなコードで表現されるべきであり、分類精度を最適化するための良いコードブックを設計する必要があります。この実装では、[3]で提唱されているようにランダムに生成されたコードブックを単に使用しますが、将来もっと複雑なメソッドが追加される可能性があります。
フィッティング時に、コードブック内のビットごとに1つのバイナリ分類器が適合する。予測時に、分類器はクラス空間内に新しい点を投影するために使用され、点に最も近いクラスが選択される。
OutputCodeClassifier では、code_size
属性を使用して、使用される分類器の数を制御できます。これは、クラスの総数に対するパーセンテージです。
0と1の間の数は、1対の残りの数よりも少ない分類子を必要とします。 理論的には、log2(n_classes)/ n_classes
で各クラスを明白に表現できます。 しかし、 log2(n_classes)
は n_classes
よりもはるかに小さいので、実際には精度が低下する可能性があります。
1より大きい数には、1対の残りの分類子よりも多くの分類子が必要です。 この場合、いくつかの分類器は、理論上、他の分類器によってなされた誤りを訂正するので、「誤り訂正」という名前になります。 しかし、実際には、クラシファイアミスが一般に相関するため、これは起こり得ない。 誤り訂正出力コードは、バギングと同様の効果を有する。
1.12.4.1. マルチクラス学習
以下は、出力コードを使用したマルチクラス学習の例です。
>>> from sklearn import datasets
>>> from sklearn.multiclass import OutputCodeClassifier
>>> from sklearn.svm import LinearSVC
>>> iris = datasets.load_iris()
>>> X, y = iris.data, iris.target
>>> clf = OutputCodeClassifier(LinearSVC(random_state=0),
... code_size=2, random_state=0)
>>> clf.fit(X, y).predict(X)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1,
1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1, 1, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])
- 参考文献:
- [2] "誤り訂正出力コードによるマルチクラス学習問題の解法"、Dietterich T.、Bakiri G.、Journal of Artificial Intelligence Research 2、1995。
- [3] "エラーコーディング方法とPICT"、James G.、Hastie T.、Journal of Computational and Graphical statistics 7、1998
- [4] "統計学習の要素"、Hastie T.、Tibshirani R.、Friedman J.、606ページ(第2版)2008。
1.12.5. マルチ出力回帰
MultiOutputRegressorを使用する任意の回帰分析器に、複数出力回帰サポートを追加することができます。 この戦略は、目標ごとに1つの回帰因子を当てはめることからなる。 各ターゲットは正確に1つの回帰式によって表されるので、対応する回帰式を検査することによってターゲットについての知識を得ることが可能である。 MultiOutputRegressorはターゲットごとに1つの回帰式に適合するため、ターゲット間の相関を利用することはできません。
以下は、マルチ出力回帰の例です。
>>> from sklearn.datasets import make_regression
>>> from sklearn.multioutput import MultiOutputRegressor
>>> from sklearn.ensemble import GradientBoostingRegressor
>>> X, y = make_regression(n_samples=10, n_targets=3, random_state=1)
>>> MultiOutputRegressor(GradientBoostingRegressor(random_state=0)).fit(X, y).predict(X)
array([[-154.75474165, -147.03498585, -50.03812219],
[ 7.12165031, 5.12914884, -81.46081961],
[-187.8948621 , -100.44373091, 13.88978285],
[-141.62745778, 95.02891072, -191.48204257],
[ 97.03260883, 165.34867495, 139.52003279],
[ 123.92529176, 21.25719016, -7.84253 ],
[-122.25193977, -85.16443186, -107.12274212],
[ -30.170388 , -94.80956739, 12.16979946],
[ 140.72667194, 176.50941682, -17.50447799],
[ 149.37967282, -81.15699552, -5.72850319]])
1.12.6. 複数出力の分類
複数出力分類サポートは、MultiOutputClassifierを使用する任意の分類器に追加できます。 この戦略は、ターゲットごとに1つの分類器を適合させることからなる。 これにより、複数のターゲット変数分類が可能になります。 このクラスの目的は、一連の目標関数 (f1,f2,f3...,fn) を1つのX予測器行列で訓練して推定し、(y1,y2,y3...,yn) の一連の予測を予測できるように推定器を拡張することです。
以下は、マルチ出力の分類の例です。
>>> from sklearn.datasets import make_classification
>>> from sklearn.multioutput import MultiOutputClassifier
>>> from sklearn.ensemble import RandomForestClassifier
>>> from sklearn.utils import shuffle
>>> import numpy as np
>>> X, y1 = make_classification(n_samples=10, n_features=100, n_informative=30, n_classes=3, random_state=1)
>>> y2 = shuffle(y1, random_state=1)
>>> y3 = shuffle(y1, random_state=2)
>>> Y = np.vstack((y1, y2, y3)).T
>>> n_samples, n_features = X.shape # 10,100
>>> n_outputs = Y.shape[1] # 3
>>> n_classes = 3
>>> forest = RandomForestClassifier(n_estimators=100, random_state=1)
>>> multi_target_forest = MultiOutputClassifier(forest, n_jobs=-1)
>>> multi_target_forest.fit(X, Y).predict(X)
array([[2, 2, 0],
[1, 2, 1],
[2, 1, 0],
[0, 0, 2],
[0, 2, 1],
[0, 0, 2],
[1, 1, 0],
[1, 1, 1],
[0, 0, 2],
[2, 0, 0]])
scikit-learn 0.18 ユーザーガイド 1. 教師付き学習 より
©2010 - 2016、scikit-learn developers(BSDライセンス)。