2010-06-24 16 views
29

मुझे पोस्टग्रेज़ डेटाबेस में लगभग 300k दस्तावेज़ संग्रहीत किए गए हैं जो विषय श्रेणियों के साथ टैग किए गए हैं (कुल में लगभग 150 श्रेणियां हैं)। मेरे पास एक और 150k दस्तावेज़ हैं जिनके पास अभी तक श्रेणियां नहीं हैं। मैं प्रोग्रामेटिक रूप से उन्हें वर्गीकृत करने का सबसे अच्छा तरीका खोजने की कोशिश कर रहा हूं।श्रेणियों में वर्गीकृत दस्तावेज

मैं NLTK और इसके बेवकूफ बेयस क्लासिफायर की खोज कर रहा हूं। एक अच्छा प्रारंभिक बिंदु की तरह लगता है (यदि आप इस कार्य के लिए बेहतर वर्गीकरण एल्गोरिदम का सुझाव दे सकते हैं, तो मैं सभी कान हूं)।

मेरी समस्या यह है कि मेरे पास सभी 150 केटगोई/300 के दस्तावेजों पर एक बार में NaiveBayesClassifier को प्रशिक्षित करने के लिए पर्याप्त रैम नहीं है (8 जीबी का उपयोग 5 श्रेणियों पर प्रशिक्षण)। इसके अलावा, क्लासिफायर की शुद्धता ड्रॉप हो रही है क्योंकि मैं अधिक श्रेणियों पर ट्रेन करता हूं (2 श्रेणियों के साथ 9 0% सटीकता, 5% के साथ 81%, 10% के साथ 61%)।

क्या मुझे एक समय में 5 श्रेणियों पर वर्गीकरण को प्रशिक्षित करना चाहिए और क्लासिफायर के माध्यम से सभी 150k दस्तावेज चलाने के लिए यह देखने के लिए कि क्या मैचों हैं? ऐसा लगता है कि यह काम करेगा, सिवाय इसके कि वहां बहुत सारे झूठे सकारात्मक मुद्दे होंगे जहां दस्तावेजों को वास्तव में किसी भी श्रेणी से मेल नहीं खाती है, जो क्लासिफायर द्वारा जूता-सींग मिलती है क्योंकि यह सबसे अच्छा मैच उपलब्ध है ... क्या वहां है क्लासिफायरफायर के लिए "उपर्युक्त में से कोई भी" विकल्प रखने का एक तरीका सिर्फ दस्तावेज़ में किसी भी श्रेणी में फिट नहीं होता है?

यहाँ अपने परीक्षण वर्ग http://gist.github.com/451880

+0

शायद एक ऑनलाइन/वृद्धिशील प्रशिक्षण मोड स्मृति समस्याओं को हल करेगा: http://en.wikipedia.org/wiki/Online_machine_learning – Amro

उत्तर

30

आपको अपने दस्तावेज़ों को TF-log(1 + IDF) vectors में परिवर्तित करके शुरू करना चाहिए: शब्द आवृत्तियों को स्पैस कर दिया गया है, इसलिए आपको पाइथन को शब्द के रूप में शब्द के रूप में उपयोग करना चाहिए और मूल्यों के रूप में गिनना चाहिए और फिर वैश्विक आवृत्तियों को प्राप्त करने के लिए कुल गणना से विभाजित होना चाहिए।

एक और समाधान पेट (हैश (टर्म)) का उपयोग उदाहरण के लिए सकारात्मक पूर्णांक कुंजी के रूप में करना है। फिर आप एक scipy.sparse वेक्टर का उपयोग करते हैं जो पाइथन dict की तुलना में रैखिक बीजगणित संचालन करने के लिए अधिक आसान और अधिक कुशल होते हैं।

उसी श्रेणी से संबंधित सभी लेबल किए गए दस्तावेज़ों की आवृत्तियों के औसत से 150 आवृत्तियों वैक्टर भी बनाएं। फिर नए दस्तावेज़ को लेबल करने के लिए, आप दस्तावेज़ वेक्टर और प्रत्येक श्रेणी वेक्टर के बीच cosine similarity की गणना कर सकते हैं और अपने दस्तावेज़ के लिए लेबल के रूप में सबसे समान श्रेणी चुन सकते हैं।

यदि यह पर्याप्त नहीं है, तो आप एक एल 1 दंड का उपयोग कर एक रसद प्रतिगमन मॉडल के रूप में प्रशिक्षित करने के लिए scikit-learn की this example में विस्तार से बताया है (यह liblinear के लिए एक आवरण के रूप में @ephes द्वारा समझाया गया है) कोशिश करनी चाहिए। अच्छे प्रदर्शन (सटीकता और याद) प्राप्त करने के लिए आपके लॉजिस्टिक रिग्रेशन मॉडल को प्रशिक्षित करने के लिए उपयोग किए जाने वाले वैक्टर पहले से पेश किए गए टीडी-लॉग (1 + आईडीएफ) वैक्टर होना चाहिए। Scikit सीखें lib एक दिए गए मॉडल और दिए गए डेटासेट के लिए उन स्कोर की गणना करने के लिए दिनचर्या के साथ sklearn.metrics मॉड्यूल प्रदान करता है।

बड़े डेटासेट के लिए: आपको vowpal wabbit का प्रयास करना चाहिए जो शायद बड़े पैमाने पर दस्तावेज़ वर्गीकरण समस्याओं के लिए पृथ्वी पर सबसे तेज़ खरगोश है (लेकिन पाइथन रैपर AFAIK का उपयोग करना आसान नहीं है)।

+2

वोपाल वैबिट तेज़ है। लेकिन हम अभी भी एक ऑनलाइन शिक्षण एल्गोरिदम के बजाय बैच प्रशिक्षण का उपयोग करते हैं, क्योंकि liblinear (उचित रूप से अनुकूलित) लाखों दस्तावेजों के लिए केवल कुछ मिनट लेता है (हमने फीचर-वेक्टर को mmaped (साझा) किया ताकि नई ट्रेन या वर्गीकृत प्रक्रियाओं को पार्स करने की आवश्यकता न हो फ़ाइल लेकिन मुख्य मेमोरी पर केवल लूप) और यह बेहतर प्रदर्शन करता है (मेरे पास अभी संख्याएं नहीं हैं ...)। – ephes

+2

सहमत, vowpal wabbit वास्तव में दिलचस्प है जब डेटा की स्ट्रीम अनंत है और अब स्मृति में फिट नहीं है उदा। एक लोकप्रिय वेबमेल प्रदाता के "स्पैम की रिपोर्ट करें" बटन से आते समय :) – ogrisel

+2

इसके अलावा ... सेंट्रॉइड वर्गीकरण बेवकूफ बेयस से कहीं ज्यादा बेहतर नहीं है। यह पत्र http://www2009.org/proceedings/pdf/p201.pdf गलत है। हमने उनसे कहा कि उन्होंने प्रशिक्षण के लिए परीक्षण डेटा (एक बग के कारण) का उपयोग किया था, लेकिन चर्चा कहीं भी नहीं गई ... रैखिक एसवीएम अभी भी कला की स्थिति है। – ephes

2

वहाँ वर्गीकारक के लिए विकल्प के लिए एक "ऊपर में से कोई भी" के लिए एक रास्ता है सिर्फ मामले में दस्तावेज में फ़िट नहीं होता श्रेणियों में से किसी ?

आपको हर बार प्रशिक्षित "उपरोक्त में से कोई भी" छद्म श्रेणी नहीं होने पर यह प्रभाव मिल सकता है। यदि आप अधिकतम अधिकतम 5 श्रेणियां प्रशिक्षित कर सकते हैं (हालांकि मुझे यकीन नहीं है कि यह काफी रैम क्यों खा रहा है), प्रत्येक वास्तविक 2 के दस्तावेज़ों से 4 वास्तविक श्रेणियों को प्रशिक्षित करें, और "2 में से कोई भी" इसके 2 के दस्तावेज़ों में से एक नहीं अन्य सभी 146 श्रेणियों से यादृच्छिक रूप से लिया गया है (यदि आप "स्तरीकृत नमूनाकरण" दृष्टिकोण चाहते हैं, तो प्रत्येक से लगभग 13-14), जो कि ध्वनि हो सकता है)।

अभी भी थोड़ा सा कड़वाहट जैसा लगता है और आप एक पूरी तरह से अलग दृष्टिकोण के साथ बेहतर हो सकते हैं - एक बहु-आयामी दस्तावेज़ माप ढूंढें जो आपके 300 के पूर्व-टैग किए गए दस्तावेज़ों को 150 उचित रूप से अलग करने योग्य क्लस्टर में परिभाषित करता है, फिर बस प्रत्येक को असाइन करें इस तरह के निर्धारित क्लस्टर के लिए अन्य अभी तक अनगिनत दस्तावेज़ों में से। मुझे नहीं लगता कि एनएलटीके के पास इस तरह की चीज का समर्थन करने के लिए सीधे कुछ भी उपलब्ध है, लेकिन, हे, एनएलटीके इतनी तेजी से बढ़ रहा है कि मैं कुछ याद कर सकता हूं ... ;-)

+0

हमारे पास एक विशेष श्रेणी के दस्तावेज़ हैं जिसके लिए हम जानते हैं कि हम सही ढंग से वर्गीकृत नहीं कर सकते हैं। यह एक कड़वाहट का थोड़ा सा है लेकिन काफी अच्छी तरह से काम करता है। – ephes

11

कितना बड़ा (शब्दों की संख्या) क्या आपके दस्तावेज हैं? 150 के प्रशिक्षण डॉक्स पर मेमोरी खपत एक मुद्दा नहीं होना चाहिए।

बेवकूफ बेयस एक अच्छा विकल्प है, खासकर जब आपके पास केवल कुछ प्रशिक्षण उदाहरण या बहुत शोर प्रशिक्षणडेटा के साथ कई श्रेणियां हैं। लेकिन सामान्य रूप से, रैखिक समर्थन वेक्टर मशीनें बेहतर प्रदर्शन करती हैं।

क्या आपकी समस्या मल्टीक्लास (एक दस्तावेज़ केवल एक वर्ग से संबंधित है) या मल्टीलाबेल (एक दस्तावेज़ एक या अधिक श्रेणियों से संबंधित है)?

वर्गीकरण प्रदर्शन का न्याय करने के लिए शुद्धता एक खराब विकल्प है। आपको परिशुद्धता बनाम रिकॉल, सटीक याद ब्रेकवेन पॉइंट (पीआरबीपी), एफ 1, ऑक का उपयोग करना चाहिए और परिशुद्धता बनाम रिकॉल वक्र को देखना होगा जहां याद (x) आपके आत्मविश्वास के आधार पर परिशुद्धता (वाई) के खिलाफ प्लॉट किया गया है (गीला एक दस्तावेज एक श्रेणी से संबंधित है या नहीं)।आम तौर पर आप प्रति श्रेणी एक बाइनरी क्लासिफायरफायर (एक श्रेणी के सकारात्मक प्रशिक्षण उदाहरण अन्य सभी प्रशिक्षण उदाहरण बनाते हैं जो आपकी वर्तमान श्रेणी से संबंधित नहीं हैं)। आपको प्रति श्रेणी एक इष्टतम आत्मविश्वास दहलीज चुननी होगी। यदि आप प्रति श्रेणी के उन उपायों को वैश्विक प्रदर्शन माप में जोड़ना चाहते हैं, तो आपको माइक्रो (सभी वास्तविक सकारात्मक, झूठी सकारात्मक, झूठी नकारात्मक और वास्तविक नकारात्मक और कैल्क संयुक्त स्कोर) को जोड़ना होगा या मैक्रो (प्रति श्रेणी कैल्क स्कोर और फिर सभी श्रेणियों पर उन स्कोर औसत) औसत।

हमारे पास दस लाख दस्तावेज, लाखों प्रशिक्षण उदाहरण और हजारों श्रेणियां (मल्टीलाबेल) का एक अंश है। चूंकि हम गंभीर प्रशिक्षण समय की समस्याओं का सामना करते हैं (दस्तावेजों की संख्या नई है, प्रतिदिन अपडेट या हटा दी गई है), हम liblinear के एक संशोधित संस्करण का उपयोग करते हैं। लेकिन liblinear (liblinear2scipy या scikit-learn) के आसपास एक पायथन रैपर का उपयोग कर छोटी समस्याओं के लिए ठीक काम करना चाहिए।

+0

औसत दस्तावेज लगभग 500-1000 शब्द है। दस्तावेज "मल्टीलाबेल" हो सकते हैं। – erikcw

+1

ठीक है, फिर @ogrisel द्वारा सुझाए गए स्पैस टीएफआईडीएफ-वैक्टरों के लिए जाएं (मैं उल्लेख करना भूल गया) और प्रति श्रेणी एक बाइनरी क्लासिफायरफायर। शायद आप अपने दस्तावेज़ों में कुछ गैर-सामान्य (संख्यात्मक) विशेषताएं हैं - आपको उन्हें उचित रूप से बिन करना होगा। – ephes

+0

क्या आपने liblinear के संशोधित संस्करण का उपयोग किया था? या आपने खुद को क्या संशोधित किया? वर्गीकरण गुणवत्ता –

संबंधित मुद्दे