साथ ही, हमारा Keras चीट शीट भी देखें, जो आपको कोड उदाहरणों के साथ Python में न्यूरल नेटवर्क्स बनाने के लिए आवश्यक छह चरण दिखाती है!
Artificial Neural Networks का परिचय
Keras में गहराई में जाने और इसे Python में डीप लर्निंग शुरू करने के लिए कैसे उपयोग करें, यह देखने से पहले, आपको न्यूरल नेटवर्क्स के बारे में कुछ बातें पता होनी चाहिए। जैसा कि आपने पिछला सेक्शन में संक्षेप में पढ़ा, न्यूरल नेटवर्क्स को जीवविज्ञान से प्रेरणा मिली, जहाँ “neural network” शब्द न्यूरॉन्स के लिए भी इस्तेमाल किया जा सकता है। मानव मस्तिष्क ऐसा ही एक न्यूरल नेटवर्क का उदाहरण है, जो कई न्यूरॉन्स से बना है।
और, जैसा कि आप जानते हैं, मस्तिष्क काफ़ी जटिल गणनाएँ करने में सक्षम है, और यहीं से Artificial Neural Networks की प्रेरणा आती है। संपूर्ण नेटवर्क एक शक्तिशाली मॉडलिंग टूल है।
Perceptrons
सबसे सरल न्यूरल नेटवर्क “परसेप्ट्रॉन” है, जो अपनी सबसे सरल अवस्था में एक अकेले न्यूरॉन से बना होता है। जैविक न्यूरॉन्स की तरह, जिनमें डेंड्राइट्स और एक्सॉन्स होते हैं, एकल कृत्रिम न्यूरॉन एक सरल वृक्ष संरचना है जिसमें इनपुट नोड्स और एकल आउटपुट नोड होता है, जो प्रत्येक इनपुट नोड से जुड़ा होता है। यहाँ दोनों का दृश्य तुलना दी गई है:
जैसा कि आप चित्र से देख सकते हैं, कृत्रिम न्यूरॉन्स के छह घटक होते हैं। बाएँ से दाएँ, ये हैं:
इनपुट नोड्स । प्रत्येक इनपुट नोड एक संख्यात्मक मान से संबद्ध होता है, जो कोई भी वास्तविक संख्या हो सकती है। याद रखें कि वास्तविक संख्याएँ संख्याओं का पूरा स्पेक्ट्रम बनाती हैं: वे धनात्मक या ऋणात्मक, पूर्णांक या दशमलव हो सकती हैं।
कनेक्शन्स । इसी प्रकार, इनपुट नोड से निकलने वाला प्रत्येक कनेक्शन एक वेट से संबद्ध होता है, और यह भी कोई भी वास्तविक संख्या हो सकती है।
इसके बाद, इनपुट नोड्स के सभी मान और कनेक्शन्स के वेट्स एक साथ लाए जाते हैं: उन्हें एक वेटेड सम के इनपुट के रूप में उपयोग किया जाता है: \(y = f(\sum_{i=1}^{D} w_i*x_i)\) , या, दूसरे शब्दों में, \(y = f(w_1*x_1 + w_2*x_2 + ... w_D*x_D)\) ।
यह परिणाम एक ट्रांसफ़र या एक्टिवेशन फ़ंक्शन के लिए इनपुट होगा। सबसे सरल लेकिन तुच्छ मामले में, यह ट्रांसफ़र फ़ंक्शन एक आइडेंटिटी फ़ंक्शन होगा, \(f(x)=x\) या \(y=x\) । इस मामले में, \(x\) इनपुट नोड्स और कनेक्शन्स का वेटेड सम है। हालाँकि, जैसे एक जैविक न्यूरॉन केवल तब फायर करता है जब कोई थ्रेशहोल्ड पार हो, कृत्रिम न्यूरॉन भी तभी फायर करेगा जब इनपुट्स का योग किसी थ्रेशहोल्ड, मान लीजिए 0, से अधिक हो। यह वह बात है जो आप आइडेंटिटी फ़ंक्शन में नहीं पाएँगे! इसे समझने का सबसे सहज तरीका निम्न प्रणाली जैसा कुछ बनाना है:
\(f(x) = 0\) यदि \(x<0\) \(f(x) = 0.5\) यदि \(x=0\) \(f(x) = 1\) यदि \(x>0\)
बेशक, आप कल्पना कर सकते हैं कि आउटपुट एक स्मूथ रेखा नहीं होगा: यह एक असतत फ़ंक्शन होगा। क्योंकि यह गणितीय प्रोसेसिंग में समस्याएँ पैदा कर सकता है, एक सतत वैरिएंट, sigmoid फ़ंक्शन, का अक्सर उपयोग किया जाता है। sigmoid फ़ंक्शन का एक उदाहरण जिसे आप पहले से जानते होंगे, लॉजिस्टिक फ़ंक्शन है। इस फ़ंक्शन का उपयोग करने से परिणाम कहीं अधिक स्मूथ हो जाता है!
परिणामस्वरूप, आपके पास आउटपुट नोड होता है, जो इनपुट नोड्स के वेटेड सम के फ़ंक्शन (जैसे sigmoid फ़ंक्शन) से संबद्ध होता है। ध्यान दें कि sigmoid फ़ंक्शन एक गणितीय फ़ंक्शन है जो “S” आकार का कर्व देता है; आप इसके बारे में आगे और पढ़ेंगे।
अंत में, परसेप्ट्रॉन में एक अतिरिक्त पैरामीटर, जिसे बायस कहते हैं, हो सकता है, जिसे आप एक अतिरिक्त इनपुट नोड से जुड़े वेट के रूप में मान सकते हैं जो हमेशा 1 पर सेट रहता है। बायस का मान महत्वपूर्ण है क्योंकि यह आपको एक्टिवेशन फ़ंक्शन को बाएँ या दाएँ शिफ्ट करने की अनुमति देता है, जो आपके लर्निंग की सफलता निर्धारित कर सकता है।
ध्यान दें कि इस मॉडल का तार्किक परिणाम यह है कि परसेप्ट्रॉन्स केवल संख्यात्मक डेटा के साथ काम करते हैं। इसका मतलब है कि आपको किसी भी नाममात्र (nominal) डेटा को संख्यात्मक प्रारूप में बदलना चाहिए।
अब जब आप जानते हैं कि परसेप्ट्रॉन्स थ्रेशहोल्ड्स के साथ काम करते हैं, तो उन्हें क्लासिफिकेशन उद्देश्यों के लिए उपयोग करने का कदम बहुत दूर नहीं है: परसेप्ट्रॉन यह मान सकता है कि कोई भी आउटपुट जो किसी थ्रेशहोल्ड से अधिक है, वह किसी उदाहरण के एक क्लास से संबंधित होने को दर्शाता है, जबकि थ्रेशहोल्ड से नीचे आउटपुट होने पर इनपुट दूसरी क्लास का सदस्य हो सकता है। वह सीधी रेखा जहाँ आउटपुट थ्रेशहोल्ड के बराबर है, तब दो क्लासेस के बीच की सीमा होती है।
मल्टी-लेयर परसेप्ट्रॉन्स
परसेप्ट्रॉन्स के नेटवर्क मल्टी-लेयर परसेप्ट्रॉन्स होते हैं, और यही वह है जिसे यह ट्यूटोरियल Keras की मदद से Python में इम्प्लीमेंट करेगा! मल्टी-लेयर परसेप्ट्रॉन्स को “feed-forward neural networks” भी कहा जाता है। जैसा कि आप अब तक अंदाज़ा लगा चुके होंगे, ये परसेप्ट्रॉन से अधिक जटिल नेटवर्क हैं, क्योंकि वे लेयर्स में व्यवस्थित कई न्यूरॉन्स से मिलकर बने होते हैं। लेयर्स की संख्या आमतौर पर दो या तीन तक सीमित रहती है, लेकिन सैद्धांतिक रूप से इसकी कोई सीमा नहीं है!
लेयर्स बहुत हद तक उन जैविक न्यूरॉन्स की तरह काम करती हैं जिनके बारे में आपने ऊपर पढ़ा: एक लेयर के आउटपुट अगली लेयर के इनपुट के रूप में काम करते हैं।
लेयर्स में, आप इनपुट लेयर, हिडन लेयर्स और आउटपुट लेयर को अलग-अलग पहचान सकते हैं। मल्टी-लेयर परसेप्ट्रॉन्स अक्सर फुली कनेक्टेड होते हैं। इसका मतलब है कि किसी विशिष्ट लेयर में प्रत्येक परसेप्ट्रॉन से अगली लेयर के प्रत्येक परसेप्ट्रॉन तक एक कनेक्शन होता है। हालाँकि कनेक्टेडनेस कोई अनिवार्यता नहीं है, लेकिन आमतौर पर ऐसा ही होता है।
ध्यान दें कि जहाँ परसेप्ट्रॉन केवल क्लासेस के बीच रैखिक (linear) पृथक्करण को दर्शा सकता था, मल्टी-लेयर परसेप्ट्रॉन उस सीमा को पार करता है और अधिक जटिल निर्णय सीमाएँ भी दर्शा सकता है।
Keras के साथ Python में वाइन टाइप्स की भविष्यवाणी
इस ट्यूटोरियल के लिए, आप UCI Machine Learning Repository के वाइन क्वालिटी डेटा सेट में मिलने वाले wine quality डेटा सेट का उपयोग करेंगे। आदर्श रूप से, आप बड़े डेटा सेट्स पर डीप लर्निंग करेंगे, लेकिन इस ट्यूटोरियल के उद्देश्य के लिए, आप एक छोटे सेट का उपयोग करेंगे। मुख्यतः इसलिए क्योंकि लक्ष्य आपको लाइब्रेरी के साथ शुरुआत कराना और यह समझने में मदद करना है कि न्यूरल नेटवर्क्स कैसे काम करते हैं।
हो सकता है कि आप इस डेटा सेट को पहले से जानते हों, क्योंकि मशीन लर्निंग समस्याओं पर काम करना सीखने के लिए यह सबसे लोकप्रिय डेटा सेट्स में से एक है। इस मामले में, यह आपको Keras के साथ Python में डीप लर्निंग शुरू करने में मदद करेगा।
अब शुरू करते हैं!
डेटा को समझना
हालाँकि, डेटा लोड करने से पहले, यह देखना अच्छा रहेगा कि आपको वाइन के बारे में वास्तव में कितना पता है (बेशक, डेटासेट के संदर्भ में)। आपमें से अधिकांश जानते होंगे कि आम तौर पर दो बहुत लोकप्रिय प्रकार की वाइन होती हैं: रेड और व्हाइट।
(मुझे यकीन है कि और भी कई प्रकार हैं, लेकिन सादगी के लिए और वाइन्स के बारे में मेरे सीमित ज्ञान के कारण, मैं यहीं तक सीमित रहूँगा। यदि मैं आपमें से सच्चे पारखी लोगों को निराश कर रहा हूँ तो क्षमा चाहता हूँ :)).
यह जानना एक बात है, लेकिन यदि आप इस डेटा का विश्लेषण करना चाहते हैं, तो आपको थोड़ी और जानकारी की ज़रूरत होगी।
सबसे पहले, यह देखने के लिए डेटा विवरण फ़ोल्डर देखें कि किन वेरिएबल्स को शामिल किया गया है। आमतौर पर यह आपका डेटा समझने का पहला कदम होता है। विवरण देखने के लिए इस पेज पर जाएँ या अपने डेटा को थोड़ी बेहतर तरह से जानने के लिए पढ़ते रहें।
डेटा में पुर्तगाली “Vinho Verde” वाइन के रेड और व्हाइट वेरिएंट्स से संबंधित दो डेटासेट शामिल हैं। जैसा कि विवरण में कहा गया है, आपको इस डेटा सेट में केवल भौतिक-रासायनिक (physicochemical) और संवेदी (sensory) वेरिएबल्स मिलेंगे। डेटा विवरण फ़ाइल उन 12 वेरिएबल्स की सूची देती है जो डेटा में शामिल हैं, लेकिन जो लोग, मेरी तरह, रसायन विज्ञान के विशेषज्ञ नहीं हैं, उनके लिए प्रत्येक वेरिएबल का संक्षिप्त विवरण यहाँ दिया गया है:
Fixed acidity : एसिड वाइन के प्रमुख गुण होते हैं और वाइन के स्वाद में बहुत योगदान करते हैं। आमतौर पर, कुल अम्लता को दो समूहों में विभाजित किया जाता है: volatile acids और nonvolatile या fixed acids। वाइन्स में मिलने वाले fixed acids में निम्न शामिल हैं: tartaric, malic, citric, और succinic। डेटा सेट्स में यह वेरिएबल g(\(tartaric acid\) )/\(dm^3\) में व्यक्त किया गया है।
Volatile acidity : volatile acidity मूलतः वाइन का सिरके में बदलने की प्रक्रिया है। अमेरिका में, volatile acidity की कानूनी सीमाएँ रेड टेबल वाइन के लिए 1.2 g/L और व्हाइट टेबल वाइन के लिए 1.1 g/L हैं। इन डेटा सेट्स में, volatile acidity g(\(acetic acid\) )/\(dm^3\) में व्यक्त की गई है।
Citric acid fixed acids में से एक है जो वाइन्स में पाया जाता है। इसे दोनों डेटा सेट्स में g/\(dm^3\) में व्यक्त किया गया है।
Residual sugar आम तौर पर किण्वन (fermentation) रुकने (या रोके जाने) के बाद बची शक्कर को संदर्भित करता है। यह red और white डेटा में g/\(dm^3\) में व्यक्त किया गया है।
Chlorides वाइन में खारापन बढ़ाने में महत्वपूर्ण योगदानकर्ता हो सकते हैं। यहाँ, आप देखेंगे कि इसे g(\(sodium chloride\) )/\(dm^3\) में व्यक्त किया गया है।
Free sulfur dioxide : वाइन में मिलाए गए सल्फर डाइऑक्साइड का जो भाग वाइन में बंध (bound) जाता है, उसे bound कहा जाता है, जबकि सक्रिय भाग को free कहा जाता है। वाइनमेकर हमेशा free sulfur का अनुपात अधिकतम रखने की कोशिश करेगा। इस वेरिएबल को डेटा में mg/\(dm^3\) में व्यक्त किया गया है।
Total sulfur dioxide bound और free sulfur dioxide (SO2) का योग है। यहाँ, इसे mg/\(dm^3\) में व्यक्त किया गया है। वाइन्स में सल्फर के स्तर के कानूनी मानदंड हैं: EU में, रेड वाइन्स में केवल 160mg/L तक हो सकता है, जबकि व्हाइट और रोज़े वाइन्स में लगभग 210mg/L हो सकता है। मीठी वाइन्स में 400mg/L की अनुमति है। US में कानूनी सीमा 350mg/L है, और ऑस्ट्रेलिया में 250mg/L।
Density आमतौर पर शक्कर के अल्कोहल में रूपांतरण के माप के रूप में प्रयोग होती है। यहाँ, इसे g/\(cm^3\) में व्यक्त किया गया है।
pH या potential of hydrogen वाइन की अम्लता या क्षारीयता निर्दिष्ट करने के लिए एक संख्यात्मक पैमाना है। जैसा कि आप जानते होंगे, pH 7 से कम वाले घोल अम्लीय, जबकि 7 से अधिक वाले क्षारीय होते हैं। pH 7 पर, शुद्ध जल न्यूट्रल होता है। अधिकांश वाइन्स का pH 2.9 और 3.9 के बीच होता है और इसलिए वे अम्लीय हैं।
Sulfates वाइन के लिए वैसे ही हैं जैसे भोजन के लिए ग्लूटेन। आप sulfites को उन सिरदर्दों से पहले से जानते होंगे जिनका वे कारण बन सकते हैं। वे दुनिया भर में वाइनमेकिंग का नियमित हिस्सा हैं और आवश्यक माने जाते हैं। इस मामले में, इन्हें g(\(potassium sulphate\) )/\(dm^3\) में व्यक्त किया गया है।
Alcohol : वाइन एक मादक पेय है, और जैसा कि आप जानते हैं, अल्कोहल का प्रतिशत वाइन-टू-वाइन भिन्न हो सकता है। यह आश्चर्य की बात नहीं होनी चाहिए कि यह वेरिएबल डेटा सेट्स में शामिल है, जहाँ इसे % vol में व्यक्त किया गया है।
Quality : वाइन विशेषज्ञों ने वाइन की गुणवत्ता को 0 (बहुत खराब) से 10 (बहुत उत्कृष्ट) के बीच ग्रेड किया। अंतिम संख्या उन्हीं वाइन विशेषज्ञों द्वारा की गई कम से कम तीन मूल्यांकनों की माध्यिका है।
यह सब, बेशक, कुछ बहुत बुनियादी जानकारी है जो शुरुआत करने के लिए आपके काम आ सकती है। यदि आप एक सच्चे वाइन पारखी हैं, तो आप शायद यह सब और भी बहुत कुछ जानते होंगे!
अब, अपना डेटा प्राप्त करने का समय आ गया है!
डेटा लोड करना
यह काम Python की डेटा मैनिपुलेशन लाइब्रेरी Pandas से आसानी से किया जा सकता है। आप इम्पोर्ट कन्वेंशन का पालन करते हैं और पैकेज को उसके उपनाम pd से इम्पोर्ट करते हैं।
इसके बाद, आप read_csv() फ़ंक्शन का उपयोग करके उन CSV फाइलों को पढ़ते हैं जिनमें डेटा संग्रहीत है। अतिरिक्त रूप से, sep आर्ग्युमेंट का उपयोग करके यह निर्दिष्ट करें कि सेपरेटर इस मामले में सेमीकोलन है, न कि सामान्य कॉमा।
इसे नीचे दिए गए DataCamp Light चंक में आज़माएँ:
# Import pandas
import pandas as pd
# Read in white wine data
white = ___________("http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-white.csv", sep=';')
# Read in red wine data
red = ___________("http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv", sep=';')
कमाल! यह बहुत आसान था, है ना?
आप शायद अब तक यह लाखों बार कर चुके होंगे, लेकिन यह शुरुआत करने का हमेशा एक आवश्यक कदम है। अब आप अपने डेटा को एक्सप्लोर, मैनिपुलेट और मॉडल करने के लिए पूरी तरह तैयार हैं!
डेटा एक्सप्लोरेशन
डेटा हाथ में होने पर, आपके लिए इन वाइन्स के बारे में और जानना आसान है! सबसे पहली चीज़ जो आप शायद करना चाहेंगे, वह दोनों DataFrames का एक त्वरित दृश्य प्राप्त करना है:
# Print info on white wine
_____(white.____())
# Print info on red wine
_____(red.____())
अब यह जाँचने का समय है कि आपका इम्पोर्ट सफल रहा था या नहीं: दोबारा जाँच लें कि डेटा में वे सभी वेरिएबल्स मौजूद हैं जिनका वादा UCI Machine Learning Repository की डेटा विवरण फ़ाइल ने किया था। वेरिएबल्स की संख्या के अलावा, इम्पोर्ट की गुणवत्ता भी जाँचें: क्या डेटा टाइप्स सही हैं? क्या सभी पंक्तियाँ आ गईं? क्या कोई null वैल्यू हैं जिन्हें डेटा क्लीन करते समय आपको ध्यान में रखना चाहिए?
आप info() से आगे बढ़कर भी अपने डेटा को देखना चाहेंगे:
# First rows of `red`
red.____()
# Last rows of `white`
white.____()
# Take a sample of 5 rows of `red`
red.______(5)
# Describe `white`
white.________()
# Double check for null values in `red`
pd.isnull(red)
इन सभी pandas फ़ंक्शन्स का संक्षिप्त पुनर्कथन: आप देखते हैं कि head(), tail() और sample() शानदार हैं क्योंकि वे बिना किसी झंझट के आपके डेटा का त्वरित निरीक्षण करने का तरीका देते हैं।
इसके बाद, describe() आपके डेटा के बारे में कुछ सारांश आँकड़े देता है जो आपके डेटा की गुणवत्ता का आकलन करने में मदद कर सकते हैं। आप देखते हैं कि कुछ वेरिएबल्स के min और max मानों में काफी अंतर है। यह ऐसी बात है जिससे आप बाद में निपटेंगे, लेकिन इस बिंदु पर, बस इस बात से अवगत होना ज़रूरी है।
अंत में, आपने isnull() की मदद से red में null वैल्यू की उपस्थिति दोबारा जाँच ली है। यह एक ऐसा फ़ंक्शन है जो तब काम आता है जब info() के परिणाम पढ़ने के बाद भी आप संदेह में हों।
टिप : यह भी जाँचें कि क्या वाइन डेटा में null वैल्यू हैं। आप यह ऊपर के DataCamp Light चंक के IPython शेल का उपयोग करके कर सकते हैं।
अब जब आपने यह जाँच लिया है कि आपका इम्पोर्ट सफल और सही था, तो अब थोड़ा गहराई में जाने का समय है।
डेटा का विज़ुअलाइज़ेशन
ऐसा करने का एक तरीका यह है कि डेटासेट के कुछ वेरिएबल्स के वितरण को देखें और संभावित सहसंबंधों को देखने के लिए स्कैटर प्लॉट्स बनाएं। बेशक, यदि आप इस डेटा का उपयोग अपने प्रोजेक्ट के लिए करते, तो आप इसे और भी ऊँचे स्तर पर ले जा सकते थे।
Alcohol
एक वेरिएबल जो पहली नज़र में आपको दिलचस्प लग सकता है, वह है alcohol। जब आप वाइन डेटा सेट की जाँच कर रहे होते हैं, तो यह शायद सबसे पहले आपका ध्यान खींचने वाली चीजों में से एक होता है। आप किसी भी डेटा विज़ुअलाइज़ेशन लाइब्रेरी से वितरणों को विज़ुअलाइज़ कर सकते हैं, लेकिन इस मामले में, ट्यूटोरियल ने वितरणों को जल्दी से प्लॉट करने के लिए matplotlib का उपयोग किया है:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1, 2)
ax[0].hist(red.alcohol, 10, facecolor='red', alpha=0.5, label="Red wine")
ax[1].hist(white.alcohol, 10, facecolor='white', ec="black", lw=0.5, alpha=0.5, label="White wine")
fig.subplots_adjust(left=0, right=1, bottom=0, top=0.5, hspace=0.05, wspace=1)
ax[0].set_ylim([0, 1000])
ax[0].set_xlabel("Alcohol in % Vol")
ax[0].set_ylabel("Frequency")
ax[1].set_xlabel("Alcohol in % Vol")
ax[1].set_ylabel("Frequency")
#ax[0].legend(loc='best')
#ax[1].legend(loc='best')
fig.suptitle("Distribution of Alcohol in % Vol")
plt.show()
जैसा कि आप नीचे दी गई इमेज में देख सकते हैं, रेड और व्हाइट वाइन के बीच अल्कोहल स्तर अधिकांशतः समान दिखते हैं: इनमें लगभग 9% अल्कोहल होता है। बेशक, काफ़ी संख्या में ऐसे ऑब्ज़र्वेशन्स भी हैं जिनमें 10% या 11% अल्कोहल प्रतिशत है।
ध्यान दें कि आप numpy पैकेज के histogram() फ़ंक्शन का उपयोग करके white और red डेटा का हिस्टोग्राम निकालें, तो इसे दोगुना जाँचा जा सकता है, इस तरह:
import numpy as np
print(np.histogram(red.alcohol, bins=[7,8,9,10,11,12,13,14,15]))
print(np.histogram(white.alcohol, bins=[7,8,9,10,11,12,13,14,15]))
यदि आप matplotlib ट्यूटोरियल्स में रुचि रखते हैं, तो DataCamp का Matplotlib शुरुआती ट्यूटोरियल और Viewing 3D Volumetric Data ट्यूटोरियल ज़रूर देखें, जो आपको Matplotlib के इवेंट हैंडलर API का उपयोग करना सिखाता है।
Sulfates
अगला, मुझे सल्फेट्स और वाइन की गुणवत्ता के बीच संबंध में रुचि है। जैसा कि आपने ऊपर पढ़ा, सल्फेट्स लोगों में सिरदर्द का कारण बन सकते हैं, और मैं सोच रहा हूँ कि क्या यह वाइन की गुणवत्ता को प्रभावित करता है। साथ ही, मैंने अक्सर सुना है कि ख़ासकर महिलाएँ सिरदर्द के कारण वाइन पीना नहीं चाहतीं। शायद यह रेड वाइन की रेटिंग्स को प्रभावित करता है?
आइए एक नज़र डालते हैं।
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1, 2, figsize=(8, 4))
ax[0].scatter(red['quality'], red["sulphates"], color="red")
ax[1].scatter(white['quality'], white['sulphates'], color="white", edgecolors="black", lw=0.5)
ax[0].set_title("Red Wine")
ax[1].set_title("White Wine")
ax[0].set_xlabel("Quality")
ax[1].set_xlabel("Quality")
ax[0].set_ylabel("Sulphates")
ax[1].set_ylabel("Sulphates")
ax[0].set_xlim([0,10])
ax[1].set_xlim([0,10])
ax[0].set_ylim([0,2.5])
ax[1].set_ylim([0,2.5])
fig.subplots_adjust(wspace=0.5)
fig.suptitle("Wine Quality by Amount of Sulphates")
plt.show()
जैसा कि आप नीचे की इमेज में देख सकते हैं, रेड वाइन में व्हाइट वाइन की तुलना में अधिक सल्फेट्स प्रतीत होते हैं, जिसमें 1 g/\(dm^3\) से ऊपर सल्फेट्स कम हैं। व्हाइट वाइन के लिए, केवल कुछ अपवाद दिखाई देते हैं जो 1 g/\(dm^3\) से थोड़ा ऊपर आते हैं, जबकि रेड वाइन्स के लिए यह निश्चित रूप से अधिक है। यह शायद उस आम कहावत की व्याख्या कर सकता है कि रेड वाइन सिरदर्द देती है, लेकिन गुणवत्ता का क्या?
आप स्पष्ट रूप से देख सकते हैं कि अपेक्षाकृत कम सल्फेट्स वाली व्हाइट वाइन को 9 का स्कोर मिलता है, लेकिन बाकी के लिए, इस समय डेटा की सही व्याख्या करना मुश्किल है।
बेशक, आपको ध्यान में रखना होगा कि ऑब्ज़र्वेशन्स के अंतर से ग्राफ़ और उनकी आपकी व्याख्या भी प्रभावित हो सकती है।
Acidity
सल्फेट्स के अलावा, acidity गुणवत्ता वाली वाइन्स प्राप्त करने के लिए आवश्यक प्रमुख और महत्वपूर्ण वाइन विशेषताओं में से एक है। बेहतरीन वाइन अक्सर acidity, tannin, alcohol, और sweeteness का संतुलन बनाती हैं। थोड़ी और खोज से पता चला कि 0.2 से 0.4 g/L की मात्रा में, volatile acidity वाइन की गुणवत्ता को प्रभावित नहीं करती। हालाँकि, उच्च स्तर पर, volatile acidity वाइन को तेज़, सिरके जैसा स्पर्श-संवेदन (tactile sensation) दे सकती है। अत्यधिक volatile acidity एक गंभीर रूप से दोषपूर्ण वाइन का संकेत देती है।
आइए डेटा को परखें और एक स्कैटर प्लॉट बनाएं जो अल्कोहल बनाम volatile acidity को प्लॉट करता है। डेटा पॉइंट्स को उनकी रेटिंग या quality लेबल के अनुसार रंगीन होना चाहिए:
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(570)
redlabels = np.unique(red['quality'])
whitelabels = np.unique(white['quality'])
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1, 2, figsize=(8, 4))
redcolors = np.random.rand(6,4)
whitecolors = np.append(redcolors, np.random.rand(1,4), axis=0)
for i in range(len(redcolors)):
redy = red['alcohol'][red.quality == redlabels[i]]
redx = red['volatile acidity'][red.quality == redlabels[i]]
ax[0].scatter(redx, redy, c=redcolors[i])
for i in range(len(whitecolors)):
whitey = white['alcohol'][white.quality == whitelabels[i]]
whitex = white['volatile acidity'][white.quality == whitelabels[i]]
ax[1].scatter(whitex, whitey, c=whitecolors[i])
ax[0].set_title("Red Wine")
ax[1].set_title("White Wine")
ax[0].set_xlim([0,1.7])
ax[1].set_xlim([0,1.7])
ax[0].set_ylim([5,15.5])
ax[1].set_ylim([5,15.5])
ax[0].set_xlabel("Volatile Acidity")
ax[0].set_ylabel("Alcohol")
ax[1].set_xlabel("Volatile Acidity")
ax[1].set_ylabel("Alcohol")
#ax[0].legend(redlabels, loc='best', bbox_to_anchor=(1.3, 1))
ax[1].legend(whitelabels, loc='best', bbox_to_anchor=(1.3, 1))
#fig.suptitle("Alcohol - Volatile Acidity")
fig.subplots_adjust(top=0.85, wspace=0.7)
plt.show()
ध्यान दें कि इस इमेज में रंग NumPy के random मॉड्यूल की मदद से रैंडम चुने गए हैं। आप हमेशा redcolors या whitecolors वेरिएबल्स को सूची पास करके इसे बदल सकते हैं। ध्यान रखें कि वे एक जैसे हों (सिवाय 1 के, क्योंकि व्हाइट वाइन डेटा में रेड वाइन डेटा की तुलना में एक अनोखा quality मान अधिक है), नहीं तो आपकी लेजेंड्स मेल नहीं खाएँगी!
पूरा ग्राफ़ यहाँ देखें:
ऊपर की इमेज में, आप देखते हैं कि आपने ऊपर जिन स्तरों के बारे में पढ़ा था, वे ख़ासकर व्हाइट वाइन के लिए लागू होते हैं: अधिकांश वाइन्स जिनका लेबल 8 है, उनकी volatile acidity 0.5 या उससे कम है, लेकिन इसका गुणवत्ता पर प्रभाव पड़ता है या नहीं, यह कहना मुश्किल है, क्योंकि सभी डेटा पॉइंट्स ग्राफ़ के एक तरफ़ बहुत घनी तरह से पैक्ड हैं।
यह सिर्फ़ एक त्वरित डेटा एक्सप्लोरेशन है। यदि आप अपने प्रोजेक्ट्स में इस चरण को विस्तार से करना चाहते हैं, तो DataCamp की डेटा एक्सप्लोरेशन पोस्ट्स, जैसे Python Exploratory Data Analysis और Python Data Profiling ट्यूटोरियल्स पर विचार करें, जो आपको EDA की बुनियाद से मार्गदर्शन करेंगे।
Exploratory Data Analysis का समापन
यह शायद पचाने के लिए बहुत कुछ था, इसलिए आपके EDA के दौरान आपने जो देखा उसका एक छोटा सा पुनर्कथन करना कभी देर नहीं होती, जो इस ट्यूटोरियल के आगे के पाठ्यक्रम के लिए महत्वपूर्ण हो सकता है:
आपके डेटा सेट्स के कुछ वेरिएबल्स के मान आपस में काफ़ी दूर हैं। आप अगले सेक्शन में इससे निपटेंगे।
आपके पास एक आदर्श स्थिति है: डेटा सेट्स में कोई null वैल्यू नहीं हैं।
डेटा सेट में शामिल अधिकांश वाइन्स में लगभग 9% अल्कोहल है।
रेड वाइन में व्हाइट वाइन की तुलना में अधिक सल्फेट्स दिखाई देते हैं, जिसमें 1 g/\(dm^3\) से ऊपर सल्फेट्स कम हैं।
आपने देखा कि अधिकांश वाइन्स की volatile acidity 0.5 और उससे नीचे थी। इस समय, वाइन की गुणवत्ता के साथ कोई सीधा संबंध नहीं है।
अभी तक, आपने व्हाइट वाइन और रेड वाइन डेटा को अलग-अलग देखा है। कुछ वेरिएबल्स को नज़दीक से देखने पर दोनों कुछ भिन्न दिखाई देते हैं, और अन्य मामलों में, दोनों बहुत समान दिखाई देते हैं। क्या आपको लगता है कि वेरिएबल्स के आधार पर एंट्रीज़ को व्हाइट या रेड वाइन में वर्गीकृत करने का कोई तरीका हो सकता है?
पता लगाने का बस एक ही तरीका है: डेटा को प्रीप्रोसेस करें और इसे इस तरह मॉडल करें कि आप देख सकें क्या होता है!
डेटा प्रीप्रोसेस करें
अब जब आपने अपने डेटा का एक्सप्लोरेशन कर लिया है, तो अब आपने जो अंतर्दृष्टियाँ प्राप्त की हैं, उनके आधार पर कार्रवाई करने का समय है! आइए डेटा को प्रीप्रोसेस करें ताकि आप अपना न्यूरल नेटवर्क बनाना शुरू कर सकें!
# Add `type` column to `red` with value 1
___['type'] = 1
# Add `type` column to `white` with value 0
_____['type'] = 0
# Append `white` to `red`
wines = red.______(white, ignore_index=True)
आपने इस मामले में ignore_index को True सेट किया क्योंकि जब आप white को red में जोड़ रहे होते हैं, तो आप white के इंडेक्स लेबल्स को नहीं रखना चाहते: आप चाहते हैं कि लेबल्स red में जहाँ छूटे थे, वहीं से आगे बढ़ें, न कि दोनों डेटा सेट्स को जोड़ने से डुप्लीकेट इंडेक्स लेबल्स बनें।
इंटरमेज़्ज़ो: कोरिलेशन मैट्रिक्स
अब जब आपके पास पूरा डेटा सेट है, तो एक त्वरित डेटा एक्सप्लोरेशन करना भी एक अच्छा विचार है; आप पहले ही दोनों डेटा सेट्स को अलग-अलग देखकर कुछ बातें जान चुके हैं, और अब शायद कुछ और ठोस अंतर्दृष्टियाँ इकट्ठा करने का समय है।
चूँकि ग्राफ़्स की व्याख्या करना कभी-कभी कठिन हो सकता है, कोरिलेशन मैट्रिक्स प्लॉट करना भी एक अच्छा विचार है। इससे यह जल्दी पता चल जाएगा कि कौन-से वेरिएबल्स सहसंबद्ध हैं:
import seaborn as sns
corr = wines.corr()
sns.heatmap(corr,
xticklabels=corr.columns.values,
yticklabels=corr.columns.values)
sns.plt.show()
जैसा कि आप उम्मीद करेंगे, कुछ वेरिएबल्स सहसंबद्ध हैं, जैसे density और residual sugar। साथ ही volatile acidity और type एक-दूसरे से अधिक निकटता से जुड़े हुए हैं, जितना आप दोनों डेटा सेट्स को अलग-अलग देखकर मूल रूप से अनुमान लगा सकते थे, और यह भी कुछ हद तक अपेक्षित था कि free sulfur dioxide और total sulfur dioxide सहसंबद्ध होंगे।
बहुत दिलचस्प!
ट्रेन और टेस्ट सेट्स
Imbalanced डेटा आम तौर पर क्लासिफिकेशन समस्याओं की वह समस्या है जहाँ क्लासेस बराबर रूप से प्रतिनिधित्व नहीं करतीं। अधिकांश क्लासिफिकेशन डेटा सेट्स में प्रत्येक क्लास में बिल्कुल समान संख्या में इंस्टैंसेज़ नहीं होते, लेकिन छोटा अंतर अक्सर मायने नहीं रखता। इसलिए, आपको यह सुनिश्चित करना चाहिए कि वाइन की दोनों क्लासेस ट्रेनिंग मॉडल में मौजूद हों। साथ ही, दोनों वाइन टाइप्स के इंस्टैंसेज़ की मात्रा कमोबेश बराबर होनी चाहिए ताकि आपकी भविष्यवाणियाँ किसी एक क्लास का पक्ष न लें।
इस मामले में, असंतुलन प्रतीत होता है, लेकिन फिलहाल आप इसी के साथ आगे बढ़ेंगे। बाद में, आप मॉडल का मूल्यांकन कर सकते हैं और यदि यह कम प्रदर्शन करता है, तो ऑब्ज़र्वेशन्स के अंतर को पाटने के लिए अंडरसैंपलिंग या ओवरसैंपलिंग का सहारा ले सकते हैं।
अभी के लिए, sklearn.model_selection से train_test_split इम्पोर्ट करें और डेटा तथा टारगेट लेबल्स को X और y वेरिएबल्स को असाइन करें। आप देखेंगे कि train_test_split() फ़ंक्शन के इनपुट के रूप में X और y का उपयोग पूरी तरह तैयार करने के लिए आपको टारगेट लेबल्स की ऐरे को flatten करना होगा। काम शुरू करें, नीचे दिए गए DataCamp Light चंक में आरंभ करें!
आप अपना पहला न्यूरल नेटवर्क बनाने की राह पर काफ़ी आगे बढ़ चुके हैं, लेकिन अभी एक चीज़ और है जिसका आपको ध्यान रखना है! क्या आपको अब भी याद है कि जब आप white और red डेटा सेट्स के सारांश देख रहे थे, तब आपने क्या खोजा था?
हाँ, कुछ मान आपस में काफ़ी दूर थे। यहाँ कुछ स्टैंडर्डाइज़ेशन करना समझ में आता है।
डेटा को स्टैंडर्डाइज़ करें
स्टैंडर्डाइज़ेशन उन मानों से निपटने का एक तरीका है जो एक-दूसरे से बहुत दूर हैं। scikit-learn पैकेज आपको अपना डेटा स्टैंडर्डाइज़ करने का एक शानदार और तेज़ तरीका प्रदान करता है: sklearn.preprocessing से StandardScaler मॉड्यूल इम्पोर्ट करें और आप अपने ट्रेन और टेस्ट डेटा को स्केल करने के लिए तैयार हैं!
from sklearn. preprocessing import StandardScaler
scaler = StandardScaler( ) . fit( X_train)
X_train = scaler. transform( X_train)
X_test = scaler. transform( X_test) संचालित द्वारा
अब जब आपका डेटा प्रीप्रोसेस हो गया है, तो आप असली काम पर आगे बढ़ सकते हैं: वाइन्स को क्लासिफाई करने के लिए अपना खुद का न्यूरल नेटवर्क बनाना।
डेटा मॉडल करें
मॉडलिंग शुरू करने से पहले, अपने मूल प्रश्न पर वापस जाएँ: क्या आप volatile acidity या sulphates जैसी रासायनिक विशेषताओं को देखकर अनुमान लगा सकते हैं कि कोई वाइन रेड है या व्हाइट?
चूँकि आपके पास केवल दो क्लासेस हैं, यानी व्हाइट और रेड, आप एक बाइनरी क्लासिफिकेशन करने जा रहे हैं। जैसा कि आप कल्पना कर सकते हैं, “बाइनरी” का मतलब 0 या 1, हाँ या नहीं। चूँकि न्यूरल नेटवर्क्स केवल संख्यात्मक डेटा के साथ काम कर सकते हैं, आप पहले ही रेड को 1 और व्हाइट को 0 के रूप में एन्कोड कर चुके हैं।
ऐसी समस्या पर अच्छा प्रदर्शन करने वाला नेटवर्क का एक प्रकार मल्टी-लेयर परसेप्ट्रॉन है। जैसा कि आपने इस ट्यूटोरियल की शुरुआत में पढ़ा, इस प्रकार का न्यूरल नेटवर्क अक्सर फुली कनेक्टेड होता है। इसका मतलब है कि आप इस समस्या को हल करने के लिए फुली-कनेक्टेड लेयर्स के एक काफ़ी सरल स्टैक का निर्माण करना चाहते हैं। जहाँ तक आप जिस एक्टिवेशन फ़ंक्शन का उपयोग करेंगे, उसका सवाल है, Keras और न्यूरल नेटवर्क्स से परिचित होने के उद्देश्य से यहाँ सबसे आम फ़ंक्शन्स में से एक relu का उपयोग करना बेहतर है।
अब आप अपना मल्टी-लेयर परसेप्ट्रॉन बनाना कैसे शुरू करें? एक त्वरित तरीका Keras Sequential मॉडल का उपयोग करना है: यह लेयर्स का एक रैखिक स्टैक है। आप आसानी से कंस्ट्रक्टर को लेयर इंस्टैंसेज़ की लिस्ट पास करके मॉडल बना सकते हैं, जिसे आप model = Sequential() चलाकर सेटअप करते हैं।
अगला, यह सोचना बेहतर है कि मल्टी-लेयर परसेप्ट्रॉन की संरचना के बारे में, जैसा कि आपने शायद इस ट्यूटोरियल की शुरुआत में पढ़ा है: आपके पास एक इनपुट लेयर, कुछ हिडन लेयर्स और एक आउटपुट लेयर है। जब आप अपना मॉडल बना रहे होते हैं, तो इसलिए यह ध्यान में रखना महत्वपूर्ण है कि आपकी पहली लेयर को इनपुट शेप स्पष्ट करना होगा। मॉडल को यह जानना ज़रूरी है कि किस इनपुट शेप की अपेक्षा करनी है और इसलिए आप लेयर्स के डॉक्यूमेंटेशन में और उनके व्यावहारिक उदाहरणों में हमेशा input_shape, input_dim, input_length, या batch_size आर्ग्युमेंट्स पाएँगे।
इस मामले में, आपको Dense लेयर का उपयोग करना होगा, जो एक फुली कनेक्टेड लेयर है। Dense लेयर्स निम्न ऑपरेशन को इम्प्लीमेंट करती हैं: output = activation(dot(input, kernel) + bias)। ध्यान दें कि एक्टिवेशन फ़ंक्शन के बिना, आपकी Dense लेयर केवल दो रैखिक ऑपरेशन्स से बनेगी: एक डॉट प्रोडक्ट और एक एडिशन।
पहली लेयर में, activation आर्ग्युमेंट का मान relu है। अगला, आप यह भी देखते हैं कि input_shape को परिभाषित किया गया है। यह उस ऑपरेशन का input है जिसे आपने अभी देखा: मॉडल (12,) या (*, 12) आकार के इनपुट ऐरे लेता है। अंत में, आप देखते हैं कि पहली लेयर में Dense() के units आर्ग्युमेंट के लिए पहला मान 12 है, जो आउटपुट स्पेस का आयाम है और जो वास्तव में 12 हिडन यूनिट्स हैं। इसका मतलब है कि मॉडल (*, 12) आकार के ऐरे आउटपुट करेगा: यह आउटपुट स्पेस का आयाम है। यदि यह अभी पूरी तरह स्पष्ट नहीं है, तो चिंता न करें, आप इसके बारे में आगे और पढ़ेंगे!
units वास्तव में ऊपर दिए गए फॉर्मूले के kernel या वेट्स मैट्रिक्स का प्रतिनिधित्व करता है, जो लेयर द्वारा बनाए गए सभी इनपुट नोड्स को दिए गए सभी वेट्स से बना होता है। ध्यान दें कि आप नीचे दिए गए उदाहरण में कोई बायस शामिल नहीं करते, क्योंकि आपने use_bias आर्ग्युमेंट शामिल नहीं किया है और उसे TRUE पर सेट नहीं किया है, जो एक संभावना भी है।
इंटरमीडिएट लेयर भी relu एक्टिवेशन फ़ंक्शन का उपयोग करती है। इस लेयर का आउटपुट (*,8) आकार के ऐरे होंगे।
आप नेटवर्क को आकार 1 की Dense लेयर के साथ समाप्त कर रहे हैं। अंतिम लेयर भी sigmoid एक्टिवेशन फ़ंक्शन का उपयोग करेगी ताकि आपका आउटपुट वास्तव में एक probability हो; इसका मतलब है कि यह 0 और 1 के बीच का स्कोर देगा, जो यह इंगित करेगा कि सैंपल के पास टारगेट “1” होने की कितनी संभावना है, या वाइन के रेड होने की कितनी संभावना है।
# Import `Sequential` from `keras.models`
from keras.models import Sequential
# Import `Dense` from `keras.layers`
from keras.layers import Dense
# Initialize the constructor
model = Sequential()
# Add an input layer
model.add(Dense(12, activation='relu', input_shape=(11,)))
# Add one hidden layer
model.add(Dense(8, activation='relu'))
# Add an output layer
model.add(Dense(1, activation='sigmoid'))
कुल मिलाकर, आप देखते हैं कि अपने मॉडल को बनाने के लिए आपको दो प्रमुख आर्किटेक्चर निर्णय लेने की ज़रूरत है: आप कितनी लेयर्स का उपयोग करेंगे और प्रत्येक लेयर के लिए कितने “हिडन यूनिट्स” चुनेंगे।
इस मामले में, आपने अपने मॉडल की पहली लेयर के लिए 12 हिडन यूनिट्स चुने: जैसा कि आपने ऊपर पढ़ा, यह आउटपुट स्पेस का आयाम है। दूसरे शब्दों में, आप वह स्वतंत्रता निर्धारित कर रहे हैं जो आप नेटवर्क को दे रहे हैं जब वह रिप्रेजेंटेशन्स सीख रहा होता है। यदि आप अधिक हिडन यूनिट्स की अनुमति देते हैं, तो आपका नेटवर्क अधिक जटिल रिप्रेजेंटेशन्स सीखने में सक्षम होगा, लेकिन यह अधिक महँगा ऑपरेशन भी होगा जो ओवरफिटिंग के प्रति संवेदनशील हो सकता है।
याद रखें कि ओवरफिटिंग तब होता है जब मॉडल बहुत जटिल होता है: यह उस अंतर्निहित संबंध की बजाय रैंडम त्रुटि या शोर का वर्णन करेगा जिसे इसे वर्णित करना चाहिए। दूसरे शब्दों में, ट्रेनिंग डेटा को बहुत अच्छी तरह मॉडल किया गया है!
ध्यान दें कि जब आपके पास उपलब्ध ट्रेनिंग डेटा बहुत अधिक नहीं होता, तो आपको बहुत कम हिडन लेयर्स (आम तौर पर केवल एक, जैसे ऊपर के उदाहरण में) वाले छोटे नेटवर्क का उपयोग करना चाहिए।
यदि आप अभी बनाए गए मॉडल पर कुछ जानकारी प्राप्त करना चाहते हैं, तो आप output_shape एट्रिब्यूट या summary() फ़ंक्शन आदि का उपयोग कर सकते हैं। सबसे बुनियादी कुछ नीचे सूचीबद्ध हैं।
उन्हें चलाकर देखें कि आपको वास्तव में क्या परिणाम मिलते हैं और वे आपको अभी बनाए गए मॉडल के बारे में क्या बताते हैं:
# Model output shape
model.___________
# Model summary
model.__________
# Model config
model.get_config()
# List all weight tensors
model.get_weights()
कम्पाइल और फिट करें
अगला, अपने मॉडल को कम्पाइल करने और डेटा पर मॉडल को फिट करने का समय है: एक बार फिर, यह करने के लिए compile() और fit() का उपयोग करें।
model. compile ( loss= 'binary_crossentropy' ,
optimizer= 'adam' ,
metrics= [ 'accuracy' ] )
model. fit( X_train, y_train, epochs= 20 , batch_size= 1 , verbose= 1 ) संचालित द्वारा
कम्पाइल करते समय, आप मॉडल को adam ऑप्टिमाइज़र और binary_crossentropy लॉस फ़ंक्शन से कॉन्फ़िगर करते हैं। इसके अलावा, आप metrics आर्ग्युमेंट में ['accuracy'] पास करके ट्रेनिंग के दौरान एक्यूरेसी को भी मॉनिटर कर सकते हैं।
optimizer और loss वे दो आर्ग्युमेंट्स हैं जो मॉडल को कम्पाइल करना चाहते हैं तो आवश्यक हैं। सबसे लोकप्रिय ऑप्टिमाइज़ेशन एल्गोरिद्म्स में Stochastic Gradient Descent (SGD), ADAM और RMSprop शामिल हैं। आप जो भी एल्गोरिद्म चुनें, उसके आधार पर आपको कुछ पैरामीटर्स, जैसे learning rate या momentum, को ट्यून करना होगा। लॉस फ़ंक्शन का चुनाव आपके हाथ में मौजूद कार्य पर निर्भर करता है: उदाहरण के लिए, रिग्रेशन समस्या के लिए, आप आमतौर पर Mean Squared Error (MSE) का उपयोग करेंगे। जैसा कि आप इस उदाहरण में देखते हैं, आपने वाइन के रेड या व्हाइट होने की बाइनरी क्लासिफिकेशन समस्या के लिए binary_crossentropy का उपयोग किया। अंत में, मल्टी-क्लास क्लासिफिकेशन में, आप categorical_crossentropy का उपयोग करेंगे।
इसके बाद, आप X_train और y_train में सभी सैंपल्स पर 20 epochs या iterations के लिए, 1 सैंपल के बैचों में मॉडल को ट्रेन कर सकते हैं। आप verbose आर्ग्युमेंट भी निर्दिष्ट कर सकते हैं। इसे 1 पर सेट करके, आप इंगित करते हैं कि आप प्रोग्रेस बार लॉगिंग देखना चाहते हैं।
दूसरे शब्दों में, आपको मॉडल को ट्रेनिंग डेटासेट के लिए निर्दिष्ट संख्या में epochs या एक्सपोज़र्स के लिए ट्रेन करना होगा। एक epoch पूरे ट्रेनिंग सेट के एकल पास के बराबर होता है, जिसके बाद वेरिफिकेशन सेट का परीक्षण होता है। ऊपर दिए गए कोड में आपने जो बैच साइज निर्दिष्ट किया है, वह उन सैंपल्स की संख्या परिभाषित करता है जिन्हें नेटवर्क के माध्यम से प्रवाहित किया जाना है। साथ ही, ऐसा करके, आप दक्षता का अनुकूलन करते हैं क्योंकि आप यह सुनिश्चित करते हैं कि आप एक ही समय में बहुत अधिक इनपुट पैटर्न मेमोरी में लोड न करें।
वैल्यूज़ का अनुमान लगाएँ
आइए अपने मॉडल का उपयोग करें! आप इससे टेस्ट सेट के लेबल्स के लिए भविष्यवाणियाँ कर सकते हैं। बस predict() का उपयोग करें और डेटा के लेबल्स की भविष्यवाणी करने के लिए इसमें टेस्ट सेट पास करें। इस मामले में, परिणाम y_pred में संग्रहीत होता है:
y_pred = model. predict( X_test) संचालित द्वारा
अपने मॉडल का मूल्यांकन करने से पहले, आप पहले से ही एक त्वरित आइडिया प्राप्त कर सकते हैं कि y_pred और y_test कैसे तुलना करते हैं:
y_pred[ : 5 ] संचालित द्वारा
array( [ [ 0 ] ,
[ 1 ] ,
[ 0 ] ,
[ 0 ] ,
[ 0 ] ] , dtype= int32) संचालित द्वारा
y_test[ : 5 ] संचालित द्वारा
array( [ 0 , 1 , 0 , 0 , 0 ] ) संचालित द्वारा
आप देखते हैं कि ये मान मेल खाते हुए प्रतीत होते हैं, लेकिन ठोस संख्याओं के बिना यह सब क्या मायने रखता है?
मॉडल का मूल्यांकन करें
अब जब आपने अपना मॉडल बना लिया है और इसका उपयोग उस डेटा पर भविष्यवाणी करने के लिए किया है जिसे आपका मॉडल पहले नहीं देख चुका था, तो इसकी परफॉर्मेंस का मूल्यांकन करने का समय है। आप भविष्यवाणियों की तुलना वास्तविक टेस्ट लेबल्स (y_test) से विज़ुअली कर सकते हैं, या वास्तविक परफॉर्मेंस निर्धारित करने के लिए हर तरह के मेट्रिक्स का उपयोग कर सकते हैं। इस मामले में, आप यह करने के लिए evaluate() का उपयोग करेंगे। टेस्ट डेटा और टेस्ट लेबल्स पास करें और यदि आप चाहें, तो verbose आर्ग्युमेंट को 1 पर रखें। ऐसा करने पर आपको अधिक लॉग्स दिखाई देंगे।
score = model. evaluate( X_test, y_test, verbose= 1 )
print ( score) संचालित द्वारा
[ 0.025217213829228164 , 0.99487179487179489 ] संचालित द्वारा
स्कोर एक लिस्ट है जो लॉस और एक्यूरेसी के संयोजन को रखती है। इस मामले में, आप देखते हैं कि दोनों बहुत अच्छे लगते हैं, लेकिन इस मामले में यह याद रखना अच्छा है कि आपका डेटा कुछ हद तक असंतुलित था: आपके पास रेड वाइन की तुलना में व्हाइट वाइन के अधिक ऑब्ज़र्वेशन्स थे। एक्यूरेसी शायद आपके डेटा के क्लास वितरण को ही प्रतिबिंबित कर रही होगी क्योंकि यह बस white की भविष्यवाणी कर देगी क्योंकि वे ऑब्ज़र्वेशन्स प्रचुर मात्रा में मौजूद हैं!
डेटा को दोबारा व्यवस्थित करने और अलग तरीके से एक साथ रखने से पहले, अलग-अलग इवैल्यूएशन मेट्रिक्स आज़माना हमेशा एक अच्छा विचार है। इसके लिए, आप scikit-learn (जिसे आप sklearn के रूप में इम्पोर्ट करते हैं, ठीक वैसे ही जैसे आपने ट्रेन और टेस्ट सेट्स बनाते समय किया था) पर भरोसा कर सकते हैं।
इस मामले में, आप कुछ बुनियादी क्लासिफिकेशन इवैल्यूएशन तकनीकों को आज़माएँगे, जैसे:
कंफ्यूज़न मैट्रिक्स, जो भविष्यवाणियों का एक ब्रेकडाउन है जो सही भविष्यवाणियों और की गई गलत भविष्यवाणियों के प्रकारों को दिखाने वाली एक टेबल में करता है। आदर्श रूप से, आप केवल डायगोनल में संख्याएँ देखेंगे, जिसका मतलब है कि आपकी सभी भविष्यवाणियाँ सही थीं!
Precision किसी क्लासिफ़ायर की सटीकता का माप है। Precision जितना अधिक, क्लासिफ़ायर उतना अधिक सटीक।
Recall किसी क्लासिफ़ायर की पूर्णता का माप है। Recall जितना अधिक, क्लासिफ़ायर उतने अधिक मामलों को कवर करता है।
F1 Score या F-स्कोर precision और recall का वेटेड औसत है।
Kappa या Cohen’s kappa डेटा में क्लासेस के असंतुलन द्वारा सामान्यीकृत क्लासिफिकेशन एक्यूरेसी है।
from sklearn. metrics import confusion_matrix, precision_score, recall_score, f1_score, cohen_kappa_score
confusion_matrix( y_test, y_pred) संचालित द्वारा
array( [ [ 1585 , 3 ] ,
[ 8 , 549 ] ] ) संचालित द्वारा
precision_score( y_test, y_pred) संचालित द्वारा
0.994565217391 संचालित द्वारा
recall_score( y_test, y_pred) संचालित द्वारा
0.98563734290843807 संचालित द्वारा
f1_score( y_test, y_pred) संचालित द्वारा
0.99008115419296661 संचालित द्वारा
cohen_kappa_score( y_test, y_pred) संचालित द्वारा
0.98662321692498967 संचालित द्वारा
ये सभी स्कोर्स बहुत अच्छे हैं! व्हाइट वाइन टाइप की काफ़ी अधिक पंक्तियाँ होने के बावजूद आपने काफ़ी सटीक मॉडल बनाया है।
शाबाश!
कुछ और प्रयोग
आपने सफलतापूर्वक अपना पहला मॉडल बनाया है, लेकिन आप इससे और भी आगे जा सकते हैं। क्यों न निम्न चीजें आज़माएँ और देखें कि उनका क्या प्रभाव पड़ता है? जैसा कि आपने ऊपर पढ़ा, जिन दो प्रमुख आर्किटेक्चरल निर्णयों को आपको लेना होता है, वे लेयर्स और हिडन नोड्स से संबंधित होते हैं। ये शानदार शुरुआती बिंदु हैं:
आपने 1 हिडन लेयर का उपयोग किया। 2 या 3 हिडन लेयर्स का उपयोग करने का प्रयास करें;
अधिक हिडन यूनिट्स वाली या कम हिडन यूनिट्स वाली लेयर्स का उपयोग करें;
quality कॉलम को टारगेट लेबल्स के रूप में लें और बाकी डेटा (एन्कोडेड type कॉलम सहित!) को अपना डेटा बनाएं। अब आपके पास एक मल्टी-क्लास क्लासिफिकेशन समस्या है!
लेकिन एक्टिवेशन फ़ंक्शन बदलकर देखना क्यों नहीं? relu की जगह tanh एक्टिवेशन फ़ंक्शन का उपयोग करके देखें और परिणाम देखें!
वाइन क्वालिटी की भविष्यवाणी
आपका क्लासिफिकेशन मॉडल पहली रन के लिए बेहतरीन प्रदर्शन कर गया!
लेकिन मल्टी-लेयर परसेप्ट्रॉन से अधिक जटिल संरचनाएँ आज़माने और एक स्तर ऊपर जाने के अलावा आप और भी बहुत कुछ कर सकते हैं। क्यों न वाइन क्वालिटी की भविष्यवाणी करने के लिए एक न्यूरल नेटवर्क बनाने की कोशिश करें?
इस मामले में, ट्यूटोरियल मानता है कि quality एक सतत (continuous) वेरिएबल है: तब कार्य बाइनरी क्लासिफिकेशन कार्य नहीं बल्कि एक ऑर्डिनल रिग्रेशन कार्य है। यह रिग्रेशन का एक प्रकार है जिसका उपयोग एक ऑर्डिनल वेरिएबल की भविष्यवाणी करने के लिए किया जाता है: quality मान एक ऐसे मनमाने पैमाने पर मौजूद होता है जहाँ विभिन्न quality मानों के बीच सापेक्ष क्रम महत्वपूर्ण होता है। इस पैमाने में, “बहुत खराब” से “बहुत अच्छा” के लिए 0-10 का क्वालिटी स्केल ऐसा ही एक उदाहरण है।
ध्यान दें कि आप इस प्रकार की समस्या को क्लासिफिकेशन समस्या के रूप में भी देख सकते हैं और quality लेबल्स को फिक्स्ड क्लास लेबल्स मान सकते हैं।
किसी भी मामले में, इस स्थिति की सेटअप का मतलब होगा कि आपके टारगेट लेबल्स इस ट्यूटोरियल के दूसरे भाग के लिए आपके red और white DataFrames में quality कॉलम होंगे। इसके लिए कुछ अतिरिक्त प्रीप्रोसेसिंग की आवश्यकता होगी।
डेटा प्रीप्रोसेस करें
चूँकि quality वेरिएबल आपका टारगेट क्लास बन जाता है, अब आपको क्वालिटी लेबल्स को बाकी डेटा सेट से अलग करना होगा। आप wines.quality को एक अलग वेरिएबल y में रखेंगे और वाइन्स डेटा को, quality कॉलम को छोड़कर, x वेरिएबल में रखेंगे।
इसके बाद, आप डेटा को ट्रेन और टेस्ट सेट्स में विभाजित करने के लिए तैयार हैं, लेकिन आप इस मामले में इस तरीके का पालन नहीं करेंगे (हालाँकि आप कर सकते थे!)। इस ट्यूटोरियल के दूसरे भाग में, आप k-fold वैलिडेशन का उपयोग करेंगे, जिसके लिए आपको डेटा को K पार्टिशंस में विभाजित करना होगा। आमतौर पर, K को 4 या 5 पर सेट किया जाता है। इसके बाद, आप समान मॉडल्स को इंस्टेंटिएट करते हैं और प्रत्येक को एक पार्टिशन पर ट्रेन करते हैं, जबकि शेष पार्टिशन्स पर इवैल्यूएट भी करते हैं। मॉडल के लिए वैलिडेशन स्कोर तब प्राप्त K वैलिडेशन स्कोर्स का औसत होता है।
आप आगे देखेंगे कि यह कैसे करना है। फिलहाल, पहले की तरह ही, StandardScaler का उपयोग करके सुनिश्चित करें कि मॉडल में डेटा फिट करने से पहले आपका डेटा अच्छी स्थिति में है।
# Isolate target labels
y = wines.________
# Isolate data
X = wines.drop('quality', axis=_)
याद रखें कि आपको स्केलिंग फिर से करनी होगी क्योंकि आपके red, white (और परिणामस्वरूप wines) डेटा के कुछ मानों में बहुत अंतर था।
इसे नीचे दिए गए DataCamp Light चंक में आज़माएँ। आपके लिए सभी आवश्यक लाइब्रेरीज़ पहले से लोड कर दी गई हैं!
# Scale the data with `StandardScaler`
X = ________________.fit_transform(X)
अब आप फिर से वहीं पहुँच गए हैं जहाँ आप थोड़ी देर पहले थे। आप फिर से न्यूरल नेटवर्क का मॉडल बनाना शुरू कर सकते हैं!
न्यूरल नेटवर्क आर्किटेक्चर मॉडल करें
अब जब आपने डेटा को फिर से प्रीप्रोसेस कर लिया है, तो एक बार फिर न्यूरल नेटवर्क मॉडल, एक मल्टी-लेयर परसेप्ट्रॉन, का निर्माण करने का समय आ गया है। भले ही आप इसे रिग्रेशन कार्य के लिए उपयोग करेंगे, आर्किटेक्चर बहुत हद तक एक जैसा दिख सकता है, जिसमें दो Dense लेयर्स हों।
यह मत भूलिए कि पहली लेयर आपकी इनपुट लेयर है। आपको इसमें अपने इनपुट डेटा का शेप पास करना होगा। इस मामले में, आप देखते हैं कि आप input_dim का उपयोग करके Dense लेयर को इनपुट डेटा के आयाम पास करने जा रहे हैं।
# Import `Sequential` from `keras.models`
from keras.models import Sequential
# Import `Dense` from `keras.layers`
from keras.layers import Dense
# Initialize the model
model = Sequential()
# Add input layer
model.add(Dense(64, input_dim=12, activation='relu'))
# Add output layer
model.add(Dense(1))
फिर से ध्यान दें कि आप जो पहली लेयर परिभाषित करते हैं, वह इनपुट लेयर है। इस लेयर को आपके डेटा के इनपुट आयाम पता होने चाहिए। आप इनपुट आयाम पास करते हैं, जो इस मामले में 12 हैं (यह न भूलें कि आप उस Type कॉलम को भी गिन रहे हैं जिसे आपने ट्यूटोरियल के पहले भाग में जेनरेट किया था!)। आप फिर से relu एक्टिवेशन फ़ंक्शन का उपयोग करते हैं, लेकिन एक बार फिर कोई बायस शामिल नहीं है। हिडन यूनिट्स की संख्या 64 है।
आपका नेटवर्क एक सिंगल यूनिट Dense(1) के साथ समाप्त होता है, और कोई एक्टिवेशन शामिल नहीं करता। यह स्केलर रिग्रेशन के लिए एक सामान्य सेटअप है, जहाँ आप एक एकल सतत मान की भविष्यवाणी करने की कोशिश कर रहे हैं।
मॉडल को कम्पाइल करें, डेटा फिट करें
अपने मॉडल के साथ, आप इसे फिर से कम्पाइल कर सकते हैं और डेटा को इस पर फिट कर सकते हैं। लेकिन ठहरिए। क्या आपको पहले बताई गई K fold वैलिडेशन पार्टिशन्स की ज़रूरत नहीं है? बिलकुल सही।
import numpy as np
from sklearn. model_selection import StratifiedKFold
seed = 7
np. random. seed( seed)
kfold = StratifiedKFold( n_splits= 5 , shuffle= True , random_state= seed)
for train, test in kfold. split( X, Y) :
model = Sequential( )
model. add( Dense( 64 , input_dim= 12 , activation= 'relu' ) )
model. add( Dense( 1 ) )
model. compile ( optimizer= 'rmsprop' , loss= 'mse' , metrics= [ 'mae' ] )
model. fit( X[ train] , Y[ train] , epochs= 10 , verbose= 1 ) संचालित द्वारा
compile() फ़ंक्शन का उपयोग करके मॉडल को कम्पाइल करें और फिर fit() का उपयोग करके मॉडल को डेटा पर फिट करें। मॉडल को कम्पाइल करने के लिए, सुनिश्चित करें कि आप कम से कम optimizer और loss आर्ग्युमेंट्स परिभाषित करें। इस मामले में, आप rsmprop (सबसे लोकप्रिय ऑप्टिमाइज़ेशन एल्गोरिद्म्स में से एक) और mse को लॉस फ़ंक्शन के रूप में उपयोग कर सकते हैं, जो आपके जैसी रिग्रेशन समस्याओं के लिए बहुत सामान्य है।
अतिरिक्त metrics आर्ग्युमेंट वास्तव में एक फ़ंक्शन है जिसका उपयोग आपके मॉडल के प्रदर्शन का न्याय करने के लिए किया जाता है। रिग्रेशन समस्याओं के लिए, Mean Absolute Error (MAE) को मेट्रिक के रूप में लेना प्रचलित है। आप इसके बारे में अगले सेक्शन में और पढ़ेंगे।
fit() में ट्रेन डेटा और लेबल्स पास करें, तय करें कि आप कितने epochs चलाना चाहते हैं, बैच साइज क्या होगा और यदि आप चाहें, तो verbose आर्ग्युमेंट को 1 पर रखें ताकि अधिक लॉग्स मिलें क्योंकि इसमें कुछ समय लग सकता है।
मॉडल का मूल्यांकन करें
पहले की तरह, आपको अपने मॉडल का मूल्यांकन भी करना चाहिए। ऊपर के कोड में y_pred = model.predict(X[test]) जोड़ने के अलावा, sklearn के कुछ इवैल्यूएशन मेट्रिक्स का उपयोग करना भी अच्छा विचार हो सकता है, जैसा कि आपने ट्यूटोरियल के पहले भाग में किया था।
ऐसा करने के लिए, आप Mean Squared Error (MSE) और Mean Absolute Error (MAE) का उपयोग कर सकते हैं। पहला, जिसे “mean squared deviation” (MSD) भी कहा जाता है, त्रुटियों या विचलनों के वर्गों के औसत को मापता है। दूसरे शब्दों में, यह एस्टिमेटर और जो आंका जा रहा है उसके बीच अंतर को मात्रा देता है। इस तरह, आपको अपने एस्टिमेटर की गुणवत्ता के बारे में और जानकारी मिलती है: यह हमेशा गैर-नकारात्मक होता है, और शून्य के करीब वाले मान बेहतर होते हैं।
दूसरा इवैल्यूएशन माप, MAE, Mean Absolute Error का संक्षेप है: यह मापता है कि भविष्यवाणियाँ अंतिम परिणामों के कितने करीब हैं।
इन पंक्तियों को पिछले कोड चंक में जोड़ें, और इंडेंटेशन का ध्यान रखें:
mse_value, mae_value = model. evaluate( X[ test] , Y[ test] , verbose= 0 )
print ( mse_value)
0.522478731072
print ( mae_value)
0.561965950103 संचालित द्वारा
ध्यान दें कि MSE और MAE स्कोर्स के अलावा, आप R2 स्कोर या रिग्रेशन स्कोर फ़ंक्शन का भी उपयोग कर सकते हैं। यहाँ, आपको 1.0 का स्कोर लक्ष्य करना चाहिए, जो सबसे अच्छा है। हालाँकि, स्कोर नकारात्मक भी हो सकता है!
from sklearn. metrics import r2_score
r2_score( Y[ test] , y_pred)
0.3125092543 संचालित द्वारा
पहली नज़र में, ये काफ़ी खराब नंबर हैं, है ना? अच्छी बात यह है कि अब आप कोड को ऑप्टिमाइज़ करने के साथ प्रयोग कर सकते हैं ताकि परिणाम थोड़े बेहतर हो जाएँ।
अगला और अंतिम सेक्शन इसी के बारे में है!
मॉडल फाइन-ट्यूनिंग
अपने मॉडल को फाइन-ट्यून करना संभवतः वह चीज़ है जो आप बहुत करेंगे क्योंकि सभी समस्याएँ उतनी सीधी नहीं होतीं जितनी आपने इस ट्यूटोरियल के पहले भाग में देखी। जैसा कि आपने ऊपर पढ़ा, पहले से ही दो महत्वपूर्ण निर्णय हैं जिन्हें आप संभवतः समायोजित करना चाहेंगे: आप कितनी लेयर्स का उपयोग करेंगे और प्रत्येक लेयर के लिए कितने “हिडन यूनिट्स” चुनेंगे।
शुरुआत में, यह वाकई एक यात्रा होगी।
लेयर्स जोड़ना
यदि आप अपने मॉडल में एक और लेयर जोड़ें तो क्या होगा? अगर यह ऐसा दिखे तो?
model = Sequential( )
model. add( Dense( 64 , input_dim= 12 , activation= 'relu' ) )
model. add( Dense( 64 , activation= 'relu' ) )
model. add( Dense( 1 ) ) संचालित द्वारा
हिडन यूनिट्स
अपने मॉडल की आर्किटेक्चर में अधिक हिडन यूनिट्स जोड़ने का प्रभाव भी आज़माएँ और इवैल्यूएशन पर प्रभाव का अध्ययन करें, इस तरह:
model = Sequential( )
model. add( Dense( 128 , input_dim= 12 , activation= 'relu' ) )
model. add( Dense( 1 ) ) संचालित द्वारा
फिर से ध्यान दें कि, सामान्य तौर पर, चूँकि आपके पास बहुत सारा डेटा नहीं है, ओवरफिटिंग और भी बदतर हो सकती है और होगी। इसलिए आपको छोटा नेटवर्क इस्तेमाल करना चाहिए।
कुछ और प्रयोग: ऑप्टिमाइज़ेशन पैरामीटर्स
लेयर्स जोड़ने और हिडन यूनिट्स के साथ खेलने के अलावा, आप compile() फ़ंक्शन को दिए गए ऑप्टिमाइज़ेशन एल्गोरिद्म के (कुछ) पैरामीटर्स को समायोजित करने की कोशिश भी कर सकते हैं। अब तक, आपने हमेशा optimizer आर्ग्युमेंट को rmsprop जैसी स्ट्रिंग पास की है।
लेकिन हमेशा ऐसा होना ज़रूरी नहीं है!
उदाहरण के लिए, keras.models से RMSprop इम्पोर्ट करने का प्रयास करें और लर्निंग रेट lr को समायोजित करें। आप RMSprop() के अन्य पैरामीटर्स के लिए सेट किए गए डिफ़ॉल्ट मानों को भी बदल सकते हैं, लेकिन यह अनुशंसित नहीं है। आप अधिक जानकारी यहाँ पा सकते हैं।
from keras. optimizers import RMSprop
rmsprop = RMSprop( lr= 0.0001 )
model. compile ( optimizer= rmsprop, loss= 'mse' , metrics= [ 'mae' ] ) संचालित द्वारा
साथ ही, अन्य ऑप्टिमाइज़ेशन एल्गोरिद्म्स, जैसे Stochastic Gradient Descent (SGD), के साथ भी प्रयोग करने का प्रयास करें। क्या आप कोई प्रभाव देखते हैं?
from keras. optimizers import SGD, RMSprop
sgd= SGD( lr= 0.1 )
model. compile ( optimizer= sgd, loss= 'mse' , metrics= [ 'mae' ] ) संचालित द्वारा
और आगे बढ़ें!
यह ट्यूटोरियल Python और Keras के साथ आपकी डीप लर्निंग यात्रा की बस शुरुआत थी। अभी बहुत कुछ कवर करना बाकी है, तो क्यों न DataCamp का Deep Learning in Python कोर्स कर लिया जाए? इस बीच, Keras डॉक्यूमेंटेशन भी ज़रूर देखें, यदि आपने पहले से नहीं देखा है। आपको वहाँ और भी उदाहरण और सभी फ़ंक्शन्स, आर्ग्युमेंट्स, और अधिक लेयर्स आदि की जानकारी मिलेगी। जब आप Python में न्यूरल नेटवर्क्स के साथ काम करना सीख रहे होंगे, तो यह निस्संदेह एक अनिवार्य संसाधन होगा! यदि आप इसके बजाय कोई किताब पढ़ना चाहते हैं जो डीप लर्निंग (Keras के साथ) की बुनियाद और उसके व्यावहारिक उपयोग को समझाती हो, तो आपको François Chollet की Deep Learning in Python किताब ज़रूर पढ़नी चाहिए।
अब तक, हो सकता है कि आप मशीन लर्निंग के बारे में पहले से जानते हों, जो कंप्यूटर विज्ञान की एक शाखा है जो ऐसे एल्गोरिद्म के डिजाइन का अध्ययन करती है जो सीख सकते हैं। आज, आप डीप लर्निंग पर ध्यान केंद्रित करने जा रहे हैं, जो मशीन लर्निंग का एक उपक्षेत्र है और दिमाग की संरचना और कार्य से प्रेरित एल्गोरिद्म का एक सेट है। इन एल्गोरिद्म को आमतौर पर Artificial Neural Networks (ANN) कहा जाता है। डीप लर्निंग डेटा साइंस के सबसे लोकप्रिय क्षेत्रों में से एक है, जिसमें रोबोटिक्स, इमेज रिकग्निशन और आर्टिफिशियल इंटेलिजेंस (AI) में चौंकाने वाले परिणामों वाले कई केस स्टडीज़ हैं।
डीप लर्निंग मॉडल विकसित करने और उनका मूल्यांकन करने के लिए सबसे शक्तिशाली और उपयोग में आसान Python लाइब्रेरीज़ में से एक Keras है; यह तेज़ संख्यात्मक गणना लाइब्रेरीज़ Theano और TensorFlow को रैप करता है। इसका फायदा यह है कि आप न्यूरल नेटवर्क्स के साथ आसानी और मज़ेदार तरीके से शुरुआत कर सकते हैं।
आज का शुरुआती लोगों के लिए Keras ट्यूटोरियल आपको Python डीप लर्निंग की बुनियाद से परिचित कराएगा: