আমরা এই পর্যন্ত সল্যুশন স্টেটমেন্ট, ডেটা কালেকশন ও প্রিপ্রসেসিং এবং অ্যালগরিদম সিলেকশন পর্যন্ত কাজ করেছি। এখন আমরা দেখব মডেল ট্রেইন করতে হয় কীভাবে। ফ্লোচার্ট অনুযায়ী আমরা নিচের ধাপে আছি,
- ট্রেইনিং প্রসেস সম্পর্কে আলোচনা করা
Scikit-learn
প্যাকেজ সম্পর্কে আরো ধারণালাভ করা- অ্যালগরিদম ডায়বেটিস ডেটা দিয়ে ট্রেইন করে ট্রেইনড মডেল তৈরি করা
সংজ্ঞানুযায়ী,
Letting speicifc data teach a Machine Learning Algorithm to create speicific prediction model.
তার মানে, যে ট্রেইনিংয়ের মাধ্যমে একটা মেশিন লার্নিং মডেলকে স্পেসিফিক ডেটাসেট দিয়ে ট্রেইন করে একটা স্পেসিফিক প্রেডিকশন মডেলে পরিণত করা যায় সেটাই মেশিন লার্নিং ট্রেইনিং।
স্বাভাবিক, আমি ডায়বেটিসের ডেটাসেট দিয়ে মডেল ট্রেইন করে রোদ-বৃষ্টি হওয়া প্রেডিক্ট করতে পারব না। তার জন্য আমাদের আলাদা স্পেসিফিক ডেটাসেট লাগবে।
প্রায়ই মডেল রিট্রেইন (retrain) করার প্রয়োজন হয়।
- ধরি
Pima indian dataset
কিছুদিন পর পর আপডেটেড হয় নতুন নতুন ডেটা দিয়ে (মানে অবজারভেশন অর্থাৎ নতুন নতুন Row অ্যাড হচ্ছে)। আমরা মেশিন লার্নিংয়ের বৈশিষ্ট্য অনুযায়ী জানি, যত ডেটাসেট থাকবে তত বেটার, তাই নতুন অ্যাড হওয়া ডেটাসেট দিয়ে আবার মডেল ট্রেইন করলে আমরা অবশ্যই আগের চেয়ে ভাল ফলাফল পাব।
`New Data => better predictions'
- নতুন ডেটাসেট থেকে আবারও আমরা কিছু ডেটা ট্রেইনিং আর কিছু ডেটা টেস্টিংয়ের জন্য রেখে পারফর্মেন্স ভেরিফাই করতে পারি।
ট্রেইনিংয়ের শুরুতেই যেটা করতে হবে সেটা হল ডেটাসেট ভাগ করে নিতে হবে। গড়পড়তায় আমরা সাধারণত 70% ডেটা রাখি ট্রেইনিংয়ের জন্য এবং বাকি 30% রাখি টেস্টিংয়ের জন্য।
ট্রেইনিং ডেটা অ্যালগরিদমে ফিড করার মাধ্যমে আমরা অ্যালগরিদম ট্রেইন করি। কোন অ্যালগরিদম ট্রেইন করার আসল অর্থ হল ওই স্পেসিফিক ডেটাসেট এর জন্য অ্যালগরিদমের ইন্টারনাল প্যারামিটারগুলো সেট করা। আমরা যখন ম্যাথমেটিক্যাল অ্যানালাইসিস দেখব তখন বিষয়টা ক্লিয়ার হবে।
আগে দেখি আমাদের ট্রেইনিং গোল (Training Goal) আসলে কী?
ট্রেইনিং গোল বোঝার জন্য আমরা হাইপোথেটিক্যাল ডেটাসেট নিচ্ছি। আবারও বলছি "ট্রেইনিং গোল" বোঝার জন্য আমরা আপাতত Diabetes
ডেটাসেট ব্যবহার করছি না।
ধরি, সর্দি হবে কী না, সেটা বোঝার জন্য দুইটা ইনপুট ভ্যারিয়েবল / ফিচার যথেষ্ট। ফিচার দুটো হল X & Y
। প্রতি X
এর সাপেক্ষে আমরা যদি Y
এর Scatter
প্লট করি,
এখানে নীল রংয়ের ডট গুলো দ্বারা বোঝানো হচ্ছে X ও Y এর ওই কম্বিনেশনের জন্য সর্দি হবে না এবং লাল রংয়ের ডট দিয়ে বোঝানো হয়েছে X ও Y এর ওই সকল কম্বিনেশনের জন্য সর্দি হবে।
আমরা একটা সাধারণ ডিসিশন বাউন্ডারি ড্র করতে পারি ডটগুলো আলাদা করার জন্য। এটা মূলত করে দেবে আপনার ট্রেইনড অ্যালগরিদম। উপরের ডেটাসেটের জন্য এইরকম একটি ডিসিশন বাউন্ডারি এঁকে দিতে পারে আপনার অ্যালগরিদম।
কিন্তু বাউন্ডারি ড্র করার পর দেখা যাচ্ছে নীল অংশে বেশ কিছু লাল ক্রস চলে এসেছে এবং লাল অংশে বেশ কিছু নীল বৃত্ত চলে এসেছে।
তারমানে ট্রেইনিং ১০০% নয়। কিন্তু ১০০% অ্যাকুরেসি আমাদের লক্ষ্যও নয়। এত বেশি অ্যাকুরেট মডেল তৈরি করতে গেলে Overfitting হওয়ার চান্স খুবই বেশি থাকে। Overfitting এবং Underfitting মেশিন লার্নিংয়ের গুরুত্বপূর্ণ বিষয়, তাই বরাবরের মত এগুলো নিয়েও আমরা বিস্তারিত আলোচনা পরে একসময় করে নেব।
এই ট্রেইনিং ডেটা ব্যবহার করে মডেলকে ট্রেইন করে আমরা ডিসিশন বাউন্ডারি তৈরি করিয়ে নিতে পারি। আপাতত এটাই হচ্ছে আমার ট্রেইনিং ডেটা ব্যবহারের উদ্দেশ্য।
মনে হওয়া স্বাভাবিক, যে ১০০% ডেটা আমরা কেন ট্রেইনিংয়ে কাজে লাগাচ্ছি না? কেন আমরা 70-30% এ স্প্লিট করছি?! এতে করে ট্রেইনিং ডেটা কমে গেল না? তাতে পার্ফর্মেন্স খারাপ হবে না? সব ডেটা দিয়ে ট্রেইন করলে সমস্যা কোথায়?
হ্যাঁ অনেকগুলো প্রশ্ন এবং আমার চেষ্টা থাকবে সবগুলোর জবাব দেওয়ার জন্য।
১০০% ডেটা আমরা কেন ট্রেইনিংয়ে কাজে লাগাচ্ছি না? কেন আমরা 70-30% এ স্প্লিট করছি?! এতে করে ট্রেইনিং ডেটা কমে গেল না?
প্রশ্নগুলো আসলে একই, আমরা পূর্বের আলোচনা করা একটি উদাহরণের মাধ্যমে বিষয়টা বোঝার চেষ্টা করি।
ধরি, আমি কাউকে (মনে করুন সে গুণ করতে জানে না, শুধু যোগ করতে জানে) নামতা শেখাচ্ছি। লক্ষ্য করবেন আমি 'শেখাচ্ছি' কে বোল্ড হরফে লিখেছি। তারমানে আমি তাকে নামতার লজিক শেখাচ্ছি। এবার যদি তাকে আমি,
2 X 1 = 2
2 X 2 = 4
2 X 3 = 6
2 X 4 = 8
2 X 5 = 10
2 X 6 = 12
2 X 7 = 14
2 X 8 = 16
2 X 9 = 18
2 X 10 = 20
এই ২ এর নামতা বারবার পড়িয়ে মুখস্ত করালাম। আমি যদি এখন তাকে বলি, বলত 2 X 3 = ?
সে ঝটপট উত্তর দিতে পারবে যে 2 X 3 = 6
। এখন আমি তাকে টেস্ট করার জন্য যদি বলি আচ্ছা এবার ৫ এর ঘরের নামতা বল। এবার সে আর ঝটপট উত্তর দিতে পারবে না, কোন কোন ক্ষেত্রে উত্তর দিতে নাও পারে।
এই উদাহরণ দিয়ে যেটা বুঝালাম যে, আমি তাকে আদৌ কিছু শেখাতে পারি নাই। ১০০% ডেটা সাপ্লাই দিয়ে আল্টিমেটলি আমি তাকে লজিক বের করা থেকে বিরত রাখলাম। কিন্তু আমি যদি এটা করতাম,
2 X 1 = 2
2 X 2 = 4
2 X 3 = 6
2 X 5 = 10
2 X 6 = 12
2 X 7 = 14
2 X 8 = 16
2 X 10 = 20
এখানে দুইটা ডেটা মিসিং, এবং তাকে দায়িত্ব দিলাম তুমি বের কর মিসিং ভ্যালুগুলো কী হবে? সে এবার লজিক বের করার চেষ্টা করবে। কোন মুখস্ত বুলি আওড়াবে না। শুধু তাই না, আমি আসলে তার উত্তর থেকে বের করতে পারব সে আদৌ লজিক শিখতে পেরেছে কিনা।
অর্থাৎ আমরা সব টেস্টিং ডেটা দিয়ে ভেরিফাই করতে পারি আমার তৈরিকৃত মডেল আসলেই প্রেডিক্টিভ কিনা, আমি জানি এমন কোন ডেটা আমার কাছে আছে কিন্তু আমি ট্রেইনিংয়ে সেটা প্রোভাইড করি নাই। তাতে যদি মডেল কাছাকাছি প্রেডিক্ট করতে পারে তারমানে আমি মোটামুটি সফল। কারণ আমি একটা মডেলকে ট্রেইনড করতে পেরেছি। আমার কাছে উত্তর নাই এমন প্রশ্ন জিজ্ঞাসা করে আমি কীভাবে জানব আরেকজন সঠিক উত্তর দিচ্ছে কীনা?
ফিচার সিলেকশন বা ফিচার ইঞ্জিনিয়ারিং আসলে ডেটা সায়েন্সের আলোচ্য বিশাল একটা টপিক। কারণ আগেই বলেছি, অনেক সময় ডেটাসেট এ থাকা বেশ কিছু ফিচার থাকে যেগুলো অদরকারী, সেটা বাদ দিলে প্রেডিকশন আরও ভাল হবে। এই অদরকারী ভ্যারিয়েবল ছেঁটে দিয়ে দরকারী ফিচার সিলেকশনের ভারিক্কি নাম ফিচার ইঞ্জিনিয়ারিং।
আমরা ডেটাসেট ক্লিনিংয়ের সময় ফিচার ইঞ্জিনিয়ারিং খাটিয়েছিলাম, সেটা হল কো-রিলেশন বের করে আমরা skin
ছাঁটাই করি।
- No of Pregnencies
- Glucose Concentration
- Blood Pressure
- Thickness
- Insulin
- Body Mass Index
- Diabetes Predisposition
- Age
অবশেষে আমরা থিওরি পাঠ করে ব্যাপক জ্ঞানার্জনের পর বসলাম কোডিং করতে। প্রস্তুতি নিন, আমরা এখন মডেল ট্রেইন করা শুরু করব।
ট্রেইনিংয়ের শুরুতে কী করতে হবে মনে আছে? না থাকলে সমস্যা নাই,
নিচের কোড এর মাধ্যমে আমরা 70-30% ডেটা স্প্লিট করব। ৭০% হল ট্রেইনিং ডেটা, বাকিটা টেস্টিং ডেটা। জুপিটার নোটবুক বের করে আগের করা কোডটিতে লেখা শুরু করুন।
from sklearn.cross_validation import train_test_split
feature_column_names = ['num_preg', 'glucose_conc', 'diastolic_bp', 'thickness', 'insulin', 'bmi', 'diab_prod', 'age']
predicted_class_name = ['diabetes']
# Getting feature variable values
X = data_frame[feature_column_names].values
y = data_frame[predicted_class_name].values
# Saving 30% for testing
split_test_size = 30
# Splitting using scikit-learn train_test_split function
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = split_test_size, random_state = 42)
random_state = 42
দেওয়ার মানে, প্রতিবার প্রোগ্রাম রান করলে স্প্লিটিং যেন একই জায়গা থেকে হয় সেটার গ্যারান্টি দেওয়ার জন্য।
Python 3
print("{0:0.2f}% in training set".format((len(X_train)/len(data_frame.index)) * 100))
print("{0:0.2f}% in test set".format((len(X_test)/len(data_frame.index)) * 100))
Python 2
print "{0:0.2f}% in training set".format((len(X_train)/len(data_frame.index)) * 100)
print "{0:0.2f}% in test set".format((len(X_test)/len(data_frame.index)) * 100)
আউটপুট:
69.92% in training set
30.08% in test set
কাছাকাছি!
অনেক সময় একটা কলামে হয়ত বিভিন্ন ধরণের মান আছে কিন্তু আপনি চেক করতে গিয়ে দেখলেন অনেকগুলা ভ্যালু 0 যেটা সম্ভব নয়। সেটা নিয়ে কীভাবে ডিল করবেন? একটা অ্যালগরিদম আছে যেটা দিয়ে ০ ভ্যালুগুলো রিপ্লেস করে একটা গড় ভ্যালু বসিয়ে কাজ করার মত স্টেটে নেওয়া যায়, সেটা দেখার আগে চলেন দেখি আমাদের কতগুলা ভ্যালু আসলে ০!
Python 3
print("# rows in dataframe {0}".format(len(data_frame)))
print("# rows missing glucose_conc: {0}".format(len(data_frame.loc[data_frame['glucose_conc'] == 0])))
print("# rows missing diastolic_bp: {0}".format(len(data_frame.loc[data_frame['diastolic_bp'] == 0])))
print("# rows missing thickness: {0}".format(len(data_frame.loc[data_frame['thickness'] == 0])))
print("# rows missing insulin: {0}".format(len(data_frame.loc[data_frame['insulin'] == 0])))
print("# rows missing bmi: {0}".format(len(data_frame.loc[data_frame['bmi'] == 0])))
print("# rows missing diab_pred: {0}".format(len(data_frame.loc[data_frame['diab_pred'] == 0])))
print("# rows missing age: {0}".format(len(data_frame.loc[data_frame['age'] == 0])))
Python 2
print "# rows in dataframe {0}".format(len(data_frame))
print "# rows missing glucose_conc: {0}".format(len(data_frame.loc[data_frame['glucose_conc'] == 0]))
print "# rows missing diastolic_bp: {0}".format(len(data_frame.loc[data_frame['diastolic_bp'] == 0]))
print "# rows missing thickness: {0}".format(len(data_frame.loc[data_frame['thickness'] == 0]))
print "# rows missing insulin: {0}".format(len(data_frame.loc[data_frame['insulin'] == 0]))
print "# rows missing bmi: {0}".format(len(data_frame.loc[data_frame['bmi'] == 0]))
print "# rows missing diab_pred: {0}".format(len(data_frame.loc[data_frame['diab_pred'] == 0]))
print "# rows missing age: {0}".format(len(data_frame.loc[data_frame['age'] == 0]))
আউটপুট:
# rows in dataframe 768
# rows missing glucose_conc: 5
# rows missing diastolic_bp: 35
# rows missing thickness: 227
# rows missing insulin: 374
# rows missing bmi: 11
# rows missing diab_pred: 0
# rows missing age: 0
০ ভ্যালু কে কোন ভ্যালু দিয়ে রিপ্লেস করার একটা টেকনিক হল Imputation
। ইম্পুট করার জন্য সাইকিটে অলরেডি রেডিমেড কোড দেয়া আছে, আমরা আপতত সেটা ব্যবহার করে কাজ চালিয়ে নেব।
Python 2 & 3
from sklearn.preprocessing import Imputer
#Impute with mean all 0 readings
fill_0 = Imputer(missing_values=0, strategy="mean", axis=0)
X_train = fill_0.fit_transform(X_train)
X_test = fill_0.fit_transform(X_test)
এখানে fill_0 ও কিন্তু একধরণের মডেল, যার কাজ হল 0 ভ্যালুগুলোকে mean
স্ট্র্যাটেজির মাধ্যমে একটা লজিক্যাল ভ্যালু দিয়ে রিপ্লেস করা।
আমরা এই পরিবর্তিত ট্রেইন ভ্যালু দিয়ে ট্রেইন করব এবং টেস্ট ভ্যালু দিয়ে টেস্ট করব।
কারণ সিম্পল, ওখানে কোন মিসিং ডেটা নাই।
অবশেষে আমরা সেই ম্যাজিক্যাল ফাংশন কল করার মাধ্যমে মডেল ট্রেইন করব।
Python 2 & 3
from sklearn.naive_bayes import GaussianNB
# create Gaussian Naive Bayes model object and train it with the data
nb_model = GaussianNB()
nb_model.fit(X_train, y_train.ravel())
আমরা আগেই আলোচনা করে ঠিক করেছিলাম যে আমাদের সিলেক্টেড অ্যালগরিদম হবে Naive Bayes এবং সেই অ্যালগরিদমের একটি মডেল হল Gaussian Naive Bayes। আমরা একটা ফাঁকা মডেল এর অবজেক্ট তৈরি করে নিলাম, তারপর ট্রেইনিং ভ্যালু দিয়ে fit()
ফাংশন কল করার মাধ্যমে ট্রেইন করলাম।
পরবর্তী চ্যাপ্টারে আমরা দেখব আমাদের তৈরি করা মডেল কেমন পারফর্মেন্স শো করছে!