মডেলের কার্যকারীতা (ইভ্যালুয়েশন)

জুপিটার নোটবুকের এর লিংক https://github.com/raqueeb/ml-python/blob/master/model-evaluation1.ipynb

এর আগে আলাপ করেছিলাম, আমাদের জানা দরকার - কোন ধরণের মডেল নিয়ে আমাদের কাজ ভালো হবে। পাশাপাশি ক্লাসিফায়ারের কোন টিউনিং প্যারামিটার নিয়ে কাজ করলে সবচেয়ে বেশি অ্যাক্যুরেসি আসবে, সেটা নিয়ে আলাপ করা দরকার। নিজের ডেটা দিয়ে ট্রেনিং করে 'আউট অফ স্যাম্পল ডেটা' (যেটা দিয়ে ট্রেনিং করাইনি) এর জন্য আমাদের মডেল কতটুকু তৈরি?

১. এক ডেটাসেট দিয়ে ট্রেনিং এবং ইভাল্যুয়েট করানো (বর্জনীয়)

  1. পুরো আইরিস ডেটাসেট দিয়ে মডেলকে ট্রেনিং করি।

  2. একই ডেটাসেট দিয়ে ইভ্যালুয়েট করে দেখি কী হয় তার অ্যাক্যুরেসির অবস্থা।

In [1]:
# আইরিস ডেটাসেটকে লোড করে নিচ্ছি
from sklearn.datasets import load_iris
iris = load_iris()

# X এ ফীচার আর y এ রেসপন্স রাখছি 
X = iris.data
y = iris.target

যদি "কে-নিয়ারেস্ট নেইবার্স" ক্লাসিফায়ারের নেইবার ৩ হয়

In [2]:
# আগের মতো KNeighborsClassifier ইমপোর্ট করি 
from sklearn.neighbors import KNeighborsClassifier
# মডেলকে ইনস্ট্যানশিয়েট করলাম 
knn = KNeighborsClassifier(n_neighbors=5)
# মডেলের মধ্যে সম্পৰ্ক তৈরি করি 
knn.fit(X, y)
# X এর মধ্যে যে ভ্যালুগুলো আছে সেগুলোর রেসপন্স ভ্যালু প্রেডিক্ট করি  
knn.predict(X)
Out[2]:
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])

অনেক ভ্যালু, তাই না? আচ্ছা, প্রথম পাঁচটা ভ্যালু দেখি।

In [3]:
# প্রথম পাঁচটা প্রেডিকশন 
knn.predict(X)[0:5]
Out[3]:
array([0, 0, 0, 0, 0])
In [4]:
# y_pred তে প্রেডিক্টেড রেসপন্স ভ্যালুগুলোকে স্টোর করি 
y_pred = knn.predict(X)

# আমরা কতগুলো আইটেম প্রেডিক্ট করলাম?
len(y_pred)
Out[4]:
150

প্রেডিকশনের কতোটুকু অ্যাক্যুরেসি এসেছে? এটা কিন্তু ইন্টারনাল ক্যালকুলেশন। পুরো ডেটাসেটের ওপর। এখানে score ফাংশন ব্যবহার করছি ফীচার আর টার্গেট রেসপন্সগুলোকে পাঠিয়ে।

In [5]:
knn.score(X, y)
Out[5]:
0.96666666666666667

এখানে একটু গল্প করি। এমুহুর্তে আমাদের মডেল প্রেডিক্ট করেছি জানা উত্তরের সাথে। ১৫০টা রেকর্ডের ১৫০টা টার্গেট ভ্যারিয়েবল (উত্তর) দেয়া আছে ডেটাসেটের সাথে। এখন knn.predict(X) দিয়ে বের করা প্রেডিক্টেড উত্তর মেলাতে হবে আসল উত্তরের সাথে। মেশিন লার্নিং কনভেনশন অনুযায়ী প্রেডিক্টেড উত্তরকে আমরা বলি "y_pred"। আচ্ছা, আমাদের আসল উত্তর স্টোর করা আছে কোথায়? ঠিক ধরেছেন "y" এ। মডেলের অ্যাক্যুরেসি জানবো কিভাবে? "y" এর সাথে "y_pred" তুলনা করলেই বোঝা যাবে।

আরেকটা গল্প করি। এটা পাইথন মেশিন লার্নিং গুরু সেবাস্টিয়ান রাখশা'এর একটা উত্তর। প্রিয় সাইট "কোৱা" থেকে নেয়া। এখানে y_true হচ্ছে সত্যি উত্তর আর y_pred হচ্ছে প্রেডিক্টেড উত্তর। y_pred এ স্টোর করছি আমাদের ক্লাস প্রেডিকশন। প্রতিটা ক্লাসের অ্যাক্যুরেসি বের করার জন্য দুটো মেথড ব্যবহার করা যেতে পারে। একটা হচ্ছে ক্লাসিফায়ারের স্কোর মেথড মানে knn.score(X, y) আরেকটা accuracy_score(X, y)। নিচের উদাহরণে y_true হচ্ছে আসল উত্তর, আর y_pred হচ্ছে প্রেডিকশন। নিচের উদাহরণটা দেখুন। y_true সত্যিকারের ডেটা থেকে প্রেডিক্টেড y_pred এর মধ্যে ১০টা ভ্যালুর মধ্যে একটাই ভুল হয়েছে। সেকারণে accuracy_score হচ্ছে ৯০%।

In [6]:
from sklearn.metrics import accuracy_score
import numpy as np
y_true = np.array([0, 0, 0, 1, 1, 1, 2, 2, 2, 2])
y_pred1 = np.array([0, 0, 0, 1, 1, 1, 2, 2 , 2, 0])
accuracy_score(y_true, y_pred1)
Out[6]:
0.90000000000000002

এখন আসি আমাদের আইরিস ডেটাসেটের অ্যাক্যুরেসিতে। এটা আসবে আমাদের কতো শতাংশ প্রেডিকশন (y_pred) সত্যিকারের ভ্যালু (y) এর সাথে মিলেছে। এখানে আমরা metrics মডিউল ইমপোর্ট করে নিয়ে আসছি sklearn থেকে। এরপর y, y_pred ক্লাসকে পাঠিয়ে দিচ্ছি accuracy_score এর কাছে ক্লাসিফায়ারের কার্যকারীতা মানে অ্যাক্যুরেসি বের করার জন্য।

In [7]:
# compute classification accuracy for the logistic regression model
from sklearn import metrics
print(metrics.accuracy_score(y, y_pred))
0.966666666667

তাই বলে কী এটা হবে না? যেহেতু ট্রেনিং এবং টেস্ট একই ডেটাসেটে, আমরা এই জিনিষকে বলতে পারি "ট্রেনিং অ্যাক্যুরেসি"।

In [8]:
import numpy as np
# print("Test set score: {:.2f}".format(np.mean(y_pred == y)))
np.mean(y_pred == y)
Out[8]:
0.96666666666666667

যদি "কে-নিয়ারেস্ট নেইবার্স" ক্লাসিফায়ারের নেইবার ১ হয়

In [9]:
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=1)
knn.fit(X, y)
y_pred = knn.predict(X)
print(metrics.accuracy_score(y, y_pred))
1.0

এখানে চিন্তার অংকে খোরাক আছে। অ্যাক্যুরেসি ১ মানে ১০০% ঠিক প্রেডিক্ট করতে পেরেছে মডেল। এটা প্রশ্ন ফাঁসের মতো জিনিস। সেটা আমরা চাইবো না। চাইবো এমন একটা জেনারেলাইজড মডেল, যেটা যেকোন নতুন ডেটা দিয়ে কাজ করতে পারবে ভালো অ্যাক্যুরেসি দিয়ে। এগুলো ট্রেনিং ডেটা দিয়ে "ওভারফিটিং" হয়ে যায়।

এখন একটা কাজ করি। বলুনতো এখানে কী ভুল আছে? আপনার সামনে রয়েছে ইন্টারনেট ব্রাউজার। গুগল করে দেখুন, কী বলতে চেয়েছি এখানে? নতুন রাস্তা দেখতে হবে কনফিউশন ম্যাট্রিক্স নিয়ে। কনফিউশন ম্যাট্রিক্স কেন দরকার? এখানে পুরোটাই ট্রেনিং ডেটা।

In [10]:
#import confusion_matrix
from sklearn.metrics import confusion_matrix
confusion_matrix(y,y_pred)
Out[10]:
array([[50,  0,  0],
       [ 0, 50,  0],
       [ 0,  0, 50]], dtype=int64)