2017-02-16 9 views
3

複数ラベルのアウトオブコアテキスト分類子を作成しようとしています。 hereに記載されているように、バッチ内の(大規模な)テキストデータセットを読み込み、それらを部分的に分類器に適合させることが考えられる。さらに、hereで説明したマルチラベルのインスタンスを使用する場合は、データセットのクラス数として多数のバイナリクラシファイアをOne-Vs-All方式で作成することをお勧めします。テキストデータの複数ラベルアウトコア学習:部分一致のValueError

部分のフィッティングでMultiLabelBinarizerとsklearnのOneVsRestClassifierクラスを組み合わせる場合、私は次のエラーを取得する:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

コードは以下の通りです:

from sklearn.naive_bayes import MultinomialNB 
from sklearn.feature_extraction.text import HashingVectorizer 
from sklearn.preprocessing import MultiLabelBinarizer 
from sklearn.multiclass import OneVsRestClassifier 

categories = ['a', 'b', 'c'] 
X = ["This is a test", "This is another attempt", "And this is a test too!"] 
Y = [['a', 'b'],['b'],['a','b']] 

mlb = MultiLabelBinarizer(classes=categories) 
vectorizer = HashingVectorizer(decode_error='ignore', n_features=2 ** 18,   non_negative=True) 
clf = OneVsRestClassifier(MultinomialNB(alpha=0.01)) 

X_train = vectorizer.fit_transform(X) 
Y_train = mlb.fit_transform(Y) 
clf.partial_fit(X_train, Y_train, classes=categories) 

あなたはその最後の3行を想像することができます各ミニバッチに適用されます。そのコードは、わかりやすくするために削除したものです。

OneVsRestClassifierを削除してMultinomialNBのみを使用すると、コードは正しく動作します。

答えて

3

を[[1、1、0]、[ 0、1、0]、[1、1、0]が、['a','b','c']としてカテゴリを通過すると、その後this line the code通過させる: -

例えば[FALSE TRUEとしてブール値のアレイをもたらす
if np.setdiff1d(y, self.classes_): 
raise ValueError(("Mini-batch contains {0} while classes " + 
       "must be subset of {1}").format(np.unique(y), 
               self.classes_)) 

、..]。 ifは、そのような配列を単一の真理値、したがってエラーとして扱うことはできません。

まず、Y_trainと同じ数値形式のクラスを渡す必要があります。 これを実行してもinternal label_binarizer_ of OneVsRestClassifiermultilabelではなく "multiclass"タイプであると判断し、正しくクラスを変換することを拒否します。これは私の意見では、OneVsRestClassiferおよび/またはLabelBinarizerのバグです。

scikit-learn githubにpartial_fitについての問題を提出し、何が起こるかをご覧ください。

更新 はどうやら、ターゲットベクトル(Y)から「マルチラベル」または「マルチクラス」を決定することはscikit-学ぶために、それを取り巻くすべての合併症のためにcurrenlty継続的な問題です。

+0

どうやら問題はパルティのでOneVsRestClassifieにありNaive Bayesのal fitは、そのタイプのカテゴリでもうまく機能します。私は今のところ、私は自分自身を対立させるべきだと思う。 – vkolias

3

多分別の答えが当然期待されますが、私はあなたがscikit-multilearnライブラリを使用してOneVsRestClassifierを使用しないことをお勧めします。これは、scikit-learnの上に構築されたライブラリです。シンプルなOneVsRestより芸術のより多くの状態。

tutorialにはscikit-multilearnの使用例があります。複数ラベル分類のアプローチのレビューはTsoumakas's introduction to MLCにあります。

しかし、お互いに共起しているラベルがある場合は、出力スペースで高速な貪欲なコミュニティ検出を使用して、Label Powersetとラベル空間分割を別の分類子で使用することをおすすめします。 my paper about label space divisionで動作します。

次のようにそれが見えるようになりscikit-multilearnを使用するようにコードを変換する:の形をしているMultiLabelBinarizerから変換としてあなたがy_train渡している

from sklearn.naive_bayes import MultinomialNB 
from sklearn.feature_extraction.text import HashingVectorizer 
from sklearn.preprocessing import MultiLabelBinarizer 

from skmultilearn.ensemble import LabelSpacePartitioningClassifier 
from skmultilearn.cluster import IGraphLabelCooccurenceClusterer 
from skmultilearn.problem_transform import LabelPowerset 

categories = ['a', 'b', 'c'] 
X = ["This is a test", "This is another attempt", "And this is a test too!"] 
Y = [['a', 'b'],['b'],['a','b']] 

mlb = MultiLabelBinarizer(classes=categories) 
vectorizer = HashingVectorizer(decode_error='ignore', n_features=2 ** 18,   non_negative=True) 

X_train = vectorizer.fit_transform(X) 
Y_train = mlb.fit_transform(Y) 

# base single-label classifier 
base_classifier = MultinomialNB(alpha=0.01) 

# problem transformation from multi-label to single-label 
transformation_classifier = LabelPowerset(base_classifier) 

# clusterer dividing the label space using fast greedy modularity maximizing scheme 
clusterer = IGraphLabelCooccurenceClusterer('fastgreedy', weighted=True, include_self_edges=True) 

# ensemble 
clf = LabelSpacePartitioningClassifier(transformation_classifier, clusterer) 

clf.fit(X_train, Y_train)