2015-07-19 29 views
9

Với ví dụ này đơn giản phân loại multilabel (lấy từ câu hỏi này, use scikit-learn to classify into multiple categories)Sử dụng MultilabelBinarizer trên dữ liệu thử nghiệm với các nhãn không trong việc đào tạo thiết

import numpy as np 
from sklearn.pipeline import Pipeline 
from sklearn.feature_extraction.text import CountVectorizer 
from sklearn.svm import LinearSVC 
from sklearn.feature_extraction.text import TfidfTransformer 
from sklearn.multiclass import OneVsRestClassifier 
from sklearn import preprocessing 
from sklearn.metrics import accuracy_score 

X_train = np.array(["new york is a hell of a town", 
       "new york was originally dutch", 
       "the big apple is great", 
       "new york is also called the big apple", 
       "nyc is nice", 
       "people abbreviate new york city as nyc", 
       "the capital of great britain is london", 
       "london is in the uk", 
       "london is in england", 
       "london is in great britain", 
       "it rains a lot in london", 
       "london hosts the british museum", 
       "new york is great and so is london", 
       "i like london better than new york"]) 
y_train_text = [["new york"],["new york"],["new york"],["new york"], ["new york"], 
      ["new york"],["london"],["london"],["london"],["london"], 
      ["london"],["london"],["new york","london"],["new york","london"]] 

X_test = np.array(['nice day in nyc', 
       'welcome to london', 
       'london is rainy', 
       'it is raining in britian', 
       'it is raining in britian and the big apple', 
       'it is raining in britian and nyc', 
       'hello welcome to new york. enjoy it here and london too']) 

y_test_text = [["new york"],["london"],["london"],["london"],["new york", "london"],["new york", "london"],["new york", "london"]] 


lb = preprocessing.MultiLabelBinarizer() 
Y = lb.fit_transform(y_train_text) 
Y_test = lb.fit_transform(y_test_text) 

classifier = Pipeline([ 
('vectorizer', CountVectorizer()), 
('tfidf', TfidfTransformer()), 
('clf', OneVsRestClassifier(LinearSVC()))]) 

classifier.fit(X_train, Y) 
predicted = classifier.predict(X_test) 


print "Accuracy Score: ",accuracy_score(Y_test, predicted) 

Mã này chạy tốt, và in số điểm chính xác, tuy nhiên nếu tôi thay đổi y_test_text để

y_test_text = [["new york"],["london"],["england"],["london"],["new york", "london"],["new york", "london"],["new york", "london"]] 

tôi nhận được

Traceback (most recent call last): 
    File "/Users/scottstewart/Documents/scikittest/example.py", line 52, in <module> 
    print "Accuracy Score: ",accuracy_score(Y_test, predicted) 
    File "/Library/Python/2.7/site-packages/sklearn/metrics/classification.py", line 181, in accuracy_score 
differing_labels = count_nonzero(y_true - y_pred, axis=1) 
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/scipy/sparse/compressed.py", line 393, in __sub__ 
raise ValueError("inconsistent shapes") 
ValueError: inconsistent shapes 

Lưu ý việc giới thiệu nhãn 'england' không nằm trong tập huấn luyện. Làm cách nào để sử dụng phân loại nhiều nhãn để nếu nhãn "thử nghiệm" được giới thiệu, tôi vẫn có thể chạy một số chỉ số? Hoặc là thậm chí có thể?

CHỈNH SỬA: Cảm ơn bạn đã trả lời câu hỏi, tôi đoán câu hỏi của tôi là nhiều hơn về cách trình xử lý nhị phân của scikit hoạt động hoặc hoạt động. Với ngắn mẫu mã của tôi, tôi cũng mong chờ nếu tôi thay đổi y_test_text để

y_test_text = [["new york"],["new york"],["new york"],["new york"],["new york"],["new york"],["new york"]] 

Rằng nó sẽ làm việc - tôi có nghĩa là chúng tôi đã trang bị cho nhãn đó, nhưng trong trường hợp này tôi có được

ValueError: Can't handle mix of binary and multilabel-indicator 
+0

Ý bạn là gì bởi "một số số liệu"? Không có cách nào mà trình phân loại có thể dự đoán được nhãn nó không bao giờ được nhìn thấy. – BrenBarn

+0

Xem câu trả lời đã chỉnh sửa của tôi mà tôi cho rằng bao gồm tất cả câu hỏi của bạn. – Geeocode

+0

Cảm ơn Gyorgy! Đó là những gì tôi cần. Nên giải quyết vấn đề lớn hơn của tôi –

Trả lời

6

bạn có thể, nếu bạn "giới thiệu" nhãn mới trong tập huấn luyện y quá, như thế này:

import numpy as np 
from sklearn.pipeline import Pipeline 
from sklearn.feature_extraction.text import CountVectorizer 
from sklearn.svm import LinearSVC 
from sklearn.feature_extraction.text import TfidfTransformer 
from sklearn.multiclass import OneVsRestClassifier 
from sklearn import preprocessing 
from sklearn.metrics import accuracy_score 

X_train = np.array(["new york is a hell of a town", 
       "new york was originally dutch", 
       "the big apple is great", 
       "new york is also called the big apple", 
       "nyc is nice", 
       "people abbreviate new york city as nyc", 
       "the capital of great britain is london", 
       "london is in the uk", 
       "london is in england", 
       "london is in great britain", 
       "it rains a lot in london", 
       "london hosts the british museum", 
       "new york is great and so is london", 
       "i like london better than new york"]) 
y_train_text = [["new york"],["new york"],["new york"],["new york"],  
       ["new york"],["new york"],["london"],["london"],   
       ["london"],["london"],["london"],["london"], 
       ["new york","England"],["new york","london"]] 

X_test = np.array(['nice day in nyc', 
       'welcome to london', 
       'london is rainy', 
       'it is raining in britian', 
       'it is raining in britian and the big apple', 
       'it is raining in britian and nyc', 
       'hello welcome to new york. enjoy it here and london too']) 

y_test_text = [["new york"],["new york"],["new york"],["new york"],["new york"],["new york"],["new york"]] 


lb = preprocessing.MultiLabelBinarizer(classes=("new york","london","England")) 
Y = lb.fit_transform(y_train_text) 
Y_test = lb.fit_transform(y_test_text) 

print Y_test 

classifier = Pipeline([ 
('vectorizer', CountVectorizer()), 
('tfidf', TfidfTransformer()), 
('clf', OneVsRestClassifier(LinearSVC()))]) 

classifier.fit(X_train, Y) 
predicted = classifier.predict(X_test) 
print predicted 

print "Accuracy Score: ",accuracy_score(Y_test, predicted) 

Output:

Accuracy Score: 0.571428571429 

Phần quan trọng là:

y_train_text = [["new york"],["new york"],["new york"], 
       ["new york"],["new york"],["new york"], 
       ["london"],["london"],["london"],["london"], 
       ["london"],["london"],["new york","England"], 
       ["new york","london"]] 

đâu chúng ta chèn "Anh" quá. Nó có ý nghĩa, bởi vì cách khác làm thế nào có thể dự đoán phân loại một số nhãn nếu anh ta không nhìn thấy nó trước? Vì vậy, chúng tôi đã tạo ra ba vấn đề phân loại nhãn theo cách này.

EDITED:

lb = preprocessing.MultiLabelBinarizer(classes=("new york","london","England")) 

Bạn phải vượt qua các lớp học như arg để MultiLabelBinarizer() và nó sẽ làm việc với bất kỳ y_test_text.

+0

Câu trả lời hay. Vài đề nghị. sklearn.metrics.accuracy_score() để phân loại nhiều nhãn tính toán độ chính xác tập con (_meaning thực hiện một kết hợp chính xác_). Tuy nhiên, hamming_loss tính toán độ chính xác đối với các nhãn riêng lẻ đã được dự đoán. [Phân loại nhiều nhãn nhất quán] (https://papers.nips.cc/paper/5883-consistent-multilabel-classification.pdf) – Pramit

4

Tóm lại - đó là vấn đề gây khó chịu. Phân loại giả định rằng tất cả các nhãn đều được biết đến trước và bộ nén binarizer cũng vậy. Phù hợp với tất cả các nhãn và sau đó đào tạo trên bất kỳ tập hợp con nào bạn muốn.

+1

Tôi nghĩ rằng sự bất tiện là người ta có thể thích MultiLabelBinarizer đơn giản là bỏ qua bất kỳ nhãn nào mà nó chưa thấy, thay vì lỗi.So sánh với hành vi của CountVectorizer: Nếu trong phương thức transform() của nó, nó sẽ thấy các token mà nó không thấy trong quá trình fit(), nó sẽ tự động bỏ qua chúng. Đây thường là những gì bạn sẽ muốn khi, ví dụ, chuyển đổi tập kiểm tra của bạn bằng cách sử dụng cùng một vectơ bạn đã sử dụng để chuyển đổi tập huấn luyện của bạn. Tương tự, khi bạn sử dụng MultiLabelBinarizer để chuyển đổi nhãn thử nghiệm của mình, bạn có thể muốn nó tự động bỏ qua bất kỳ thứ gì bạn không thấy trong đào tạo. – Stephen

+1

Sự cố này có nhiều khả năng xảy ra khi bạn đang đào tạo một trình phân loại nhiều nhãn với số lượng nhãn rất lớn. Và đặc biệt là khi bạn đang làm việc với một tập con của tập dữ liệu của bạn trong quá trình phát triển. Để giải quyết vấn đề này, tôi chỉ cần làm sạch nhãn trước một cách thủ công. – Stephen

+0

Tôi gặp vấn đề tương tự ở đây: https://stats.stackexchange.com/questions/298046/achieving-consistency-between-training-test-target-representations-in-multilabe – Stephen

Các vấn đề liên quan