कई श्रेणियों में वर्गीकृत करने के लिए scikit-learn का उपयोग करें


80

मैं एक या अधिक श्रेणियों में पाठ के टुकड़ों को वर्गीकृत करने के लिए scikit-learn के पर्यवेक्षित शिक्षण विधियों में से एक का उपयोग करने की कोशिश कर रहा हूं। सभी एल्गोरिदम की भविष्यवाणी का कार्य मैंने केवल एक मैच की वापसी की कोशिश की।

उदाहरण के लिए मेरे पास पाठ का एक टुकड़ा है:

"Theaters in New York compared to those in London"

और मैंने हर पाठ स्निपेट के लिए एक जगह चुनने के लिए एल्गोरिथ्म को प्रशिक्षित किया है जो मैं इसे खिलाता हूं।

उपरोक्त उदाहरण में, मैं चाहता हूं कि यह वापस आए New Yorkऔर London, लेकिन यह केवल वापस लौटे New York

क्या कई परिणामों को वापस करने के लिए scikit-learn का उपयोग करना संभव है? या यहां तक ​​कि अगले उच्चतम संभावना के साथ लेबल वापस करें?

आपकी सहायता के लिए धन्यवाद।

---अपडेट करें

मैंने उपयोग करने की कोशिश की, OneVsRestClassifierलेकिन मुझे अभी भी केवल एक विकल्प प्रति पाठ का एक टुकड़ा वापस मिल रहा है। नीचे नमूना कोड मैं उपयोग कर रहा हूं

y_train = ('New York','London')


train_set = ("new york nyc big apple", "london uk great britain")
vocab = {'new york' :0,'nyc':1,'big apple':2,'london' : 3, 'uk': 4, 'great britain' : 5}
count = CountVectorizer(analyzer=WordNGramAnalyzer(min_n=1, max_n=2),vocabulary=vocab)
test_set = ('nice day in nyc','london town','hello welcome to the big apple. enjoy it here and london too')

X_vectorized = count.transform(train_set).todense()
smatrix2  = count.transform(test_set).todense()


base_clf = MultinomialNB(alpha=1)

clf = OneVsRestClassifier(base_clf).fit(X_vectorized, y_train)
Y_pred = clf.predict(smatrix2)
print Y_pred

परिणाम: ['न्यू यॉर्क' 'लंदन' 'लंदन']

जवाबों:


111

आप जो चाहते हैं, उसे मल्टी-लेबल वर्गीकरण कहा जाता है। Scikits- सीख सकते हैं। यहां देखें: http://scikit-learn.org/dev/modules/multiclass.html

मुझे यकीन नहीं है कि आपके उदाहरण में क्या गलत हो रहा है, मेरे sklearn के संस्करण में स्पष्ट रूप से WordNGramAnalyzer नहीं है। शायद यह अधिक प्रशिक्षण उदाहरणों का उपयोग करने या एक अलग क्लासिफायर की कोशिश करने का सवाल है? हालांकि ध्यान दें कि मल्टी-लेबल क्लासिफायर लक्ष्य को ट्यूल की सूची / लेबल की सूची होने की उम्मीद करता है।

निम्नलिखित मेरे लिए काम करता है:

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

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 = [[0],[0],[0],[0],[0],[0],[1],[1],[1],[1],[1],[1],[0,1],[0,1]]
X_test = np.array(['nice day in nyc',
                   'welcome to london',
                   'hello welcome to new york. enjoy it here and london too'])   
target_names = ['New York', 'London']

classifier = Pipeline([
    ('vectorizer', CountVectorizer(min_n=1,max_n=2)),
    ('tfidf', TfidfTransformer()),
    ('clf', OneVsRestClassifier(LinearSVC()))])
classifier.fit(X_train, y_train)
predicted = classifier.predict(X_test)
for item, labels in zip(X_test, predicted):
    print '%s => %s' % (item, ', '.join(target_names[x] for x in labels))

मेरे लिए, यह आउटपुट का उत्पादन करता है:

nice day in nyc => New York
welcome to london => London
hello welcome to new york. enjoy it here and london too => New York, London

उम्मीद है की यह मदद करेगा।


1
मैंने पिछले दो प्रशिक्षण उदाहरणों को हटाने की कोशिश की जो शहर के नामों को मिलाते हैं और मुझे मिलता है: नए यॉर्क में हैलो का स्वागत है। यहां आनंद लें और लंदन भी => न्यूयॉर्क यह अब दो लेबल नहीं लौटाता है। अगर मैं दो शहरों के संयोजन को प्रशिक्षित करता हूं तो मेरे लिए यह केवल दो लेबल लौटाना है। क्या मैं कुछ भूल रहा हूँ? आपकी सभी मदद के लिए फिर से धन्यवाद
CodeMonkeyB

1
यह सिर्फ एक खिलौना डाटासेट है, मैं इससे बहुत अधिक निष्कर्ष नहीं निकालूंगा। क्या आपने इस प्रक्रिया को अपने वास्तविक डेटा पर आज़माया है?
mwv

3
@CodeMonkeyB: आपको वास्तव में इस उत्तर को स्वीकार करना चाहिए, यह एक प्रोग्रामिंग दृष्टिकोण से सही है। यह व्यवहार में काम करता है या नहीं, यह आपके डेटा पर निर्भर करता है, कोड पर नहीं।
फ्रेड फू

2
किसी और के साथ एक समस्या हो रही है min_nऔर max_n। मुझे उन्हें ngram_range=(1,2)काम करने के लिए बदलने की ज़रूरत है
15

1
यह यह त्रुटि दे रहा है: ValueError: आप एक लीगेसी मल्टी-लेबल डेटा प्रतिनिधित्व का उपयोग करते हुए दिखाई देते हैं। अनुक्रमों के अनुक्रम अब समर्थित नहीं हैं; इसके बजाय एक बाइनरी सरणी या विरल मैट्रिक्स का उपयोग करें।
MANU

61

संपादित करें: पाइथन 3 के लिए अपडेट किया गया, मल्टीक्लैबिनराइज़र के रूप में सुझाए गए का उपयोग करके शिकन-सीखें 0.18.1।

मैं इस पर भी काम कर रहा हूं, और mwv के उत्कृष्ट उत्तर के लिए थोड़ी वृद्धि की है जो उपयोगी हो सकता है। यह बाइनरी लेबल के बजाय इनपुट के रूप में टेक्स्ट लेबल लेता है और उन्हें मल्टीलेबलबिनिज़र का उपयोग करके एन्कोड करता है।

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.preprocessing import MultiLabelBinarizer

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'])
target_names = ['New York', 'London']

mlb = MultiLabelBinarizer()
Y = mlb.fit_transform(y_train_text)

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

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

for item, labels in zip(X_test, all_labels):
    print('{0} => {1}'.format(item, ', '.join(labels)))

यह मुझे निम्न आउटपुट देता है:

nice day in nyc => new york
welcome to london => london
london is rainy => london
it is raining in britian => london
it is raining in britian and the big apple => new york
it is raining in britian and nyc => london, new york
hello welcome to new york. enjoy it here and london too => london, new york

13
labelBinarizerपुराना है। का प्रयोग करें lb = preprocessing.MultiLabelBinarizer()बजाय
रोमन

1
यह ब्रिटेन को नहीं देता है क्योंकि केवल आउटपुट लेबल हैं New Yorkऔर London
umop aplsdn

2
स्किकिट-लर्न के अनुसार One-Vs-All को sklearn.svm.SVC को छोड़कर सभी रेखीय मॉडलों द्वारा समर्थित किया गया है और मल्टीलेबेल द्वारा भी समर्थन किया जाता है: निर्णय पेड़, यादृच्छिक वन, निकटतम पड़ोसियों, इसलिए मैं इस प्रकार के लिए LinearSVC () नहीं करूंगा कार्य (उर्फ मल्टीलेबेल वर्गीकरण जो मुझे लगता है कि आप उपयोग करना चाहते हैं)
पीटरब

2
फ़ाइ वन-वी-ऑल कि @ मिन्स्टस्टॉर्म में उल्लेख किया गया है, स्किकिट-लर्न क्लास "वनवेस्टरेस्टक्लासीफायर" ("सभी" के बजाय "आराम" पर ध्यान दें) से मेल खाती है। यह स्कोर-लर्न हेल्प पेज इसे स्पष्ट करता है।
ल्यूसिड_ड्रीमर

1
जैसा कि @mindstorm उल्लेख करता है, यह सच है कि इस पृष्ठ पर , दस्तावेज़ में उल्लेख किया गया है: "One-Vs-All: sklearn.svm.SVC को छोड़कर सभी रैखिक मॉडल"। हालाँकि scikit-learn प्रलेखन से एक और मल्टीलेबल उदाहरण इस लाइन के साथ एक मल्टीलेबल उदाहरण दिखाता है classif = OneVsRestClassifier(SVC(kernel='linear'))। हैरान हो गया।
ल्यूसिड_ड्रीमर

8

मैं बस इसी में भाग गया, और मेरे लिए समस्या यह थी कि मेरा y_Train स्ट्रिंग्स के अनुक्रम के बजाय स्ट्रिंग्स का एक अनुक्रम था। जाहिर है, OneVsRestClassifier इनपुट लेबल फॉर्मेट के आधार पर तय करेगा कि मल्टी-क्लास बनाम मल्टी-लेबल का उपयोग करना है या नहीं। तो बदलो:

y_train = ('New York','London')

सेवा

y_train = (['New York'],['London'])

जाहिरा तौर पर यह भविष्य में गायब हो जाएगा, क्योंकि यह सभी लेबलों का टूटना समान है: https://github.com/scikit-learn/scikit-learn/pull/1987


8

अजगर के नए संस्करणों में काम करने के लिए इस लाइन को बदलें

# lb = preprocessing.LabelBinarizer()
lb = preprocessing.MultiLabelBinarizer()

2

कुछ बहु वर्गीकरण उदाहरण इस प्रकार हैं: -

उदाहरण 1:-

import numpy as np
from sklearn.preprocessing import LabelBinarizer
encoder = LabelBinarizer()

arr2d = np.array([1, 2, 3,4,5,6,7,8,9,10,11,12,13,14,1])
transfomed_label = encoder.fit_transform(arr2d)
print(transfomed_label)

आउटपुट है

[[1 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 1 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 1 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 1 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 1 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 1 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 1 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 1 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 1 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 1 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 1 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 1 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 1 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 1]
 [1 0 0 0 0 0 0 0 0 0 0 0 0 0]]

उदाहरण 2: -

import numpy as np
from sklearn.preprocessing import LabelBinarizer
encoder = LabelBinarizer()

arr2d = np.array(['Leopard','Lion','Tiger', 'Lion'])
transfomed_label = encoder.fit_transform(arr2d)
print(transfomed_label)

आउटपुट है

[[1 0 0]
 [0 1 0]
 [0 0 1]
 [0 1 0]]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.