প্র‍্যাক্টিক্যাল মেশিন লার্নিং : পার্ট - ২
project photo
author photo
Biggo RouthMar 9, 2023

আমরা মেশিন লার্নিং কি বা কেন, এসবের একটা ধারনা পেয়ে গিয়েছি। এবার আমরা একটি ডেটাসেট নিয়ে প্র‍্যাক্টিক্যালি কাজ করা শুরু করবো। তার আগে একটা জিনিস ক্লিয়ার করে রাখা ভালো আর সেটা হচ্ছে মেশিন লার্নিং মডেল রান করাতে হলে কিন্তু আমাদের কিছু লাইব্রেরী ব্যবহার করতে হয়। যেহেতু আমরা এই ব্লগে পাইথন ল্যাংগুয়েজেই কাজ করবো, সেহেতু, Numpy, Pandas, Scikit learn ইত্যাদি লাইব্রেরীগুলো সম্পর্কে নিজ থেকে একটা ছোট্ট ধারনা নিয়ে আসলে ভালো হয়। তাহলে ব্লগের সাথে কাজ করার সময় জিনিসগুলো আরও ঝালাই করে নিতে পারবে। আর ধরে নিলাম বেসিক পাইথন তোমরা সবাই জানো।

মনে হচ্ছে না যে ডেটাসেট পাবো টা কোথা থেকে? তাহলে চলো পরিচিত হওয়া যাক Kaggle সাথে। Kaggle শুধুমাত্র কোনো ডেটাসেট রিপোসিটোরি নয়, কেগেল একটা কমিউনিটি বেইসড প্লাটফর্ম যেখানে আমরা বিশ্বের সব বড় বড় ডেটা সাইন্টিস্ট, রিসার্চারদের সাথে কানেক্টেড হতে পারি, বিভিন্ন বড় বড় প্রতিযোগিতায় অংশ নিতে পারি এবং আমাদের প্রজেক্ট শেয়ার করতে পারি। আমরা কেগেলে বিভিন্ন বিষয়ের উপর ডেটাসেট পেয়ে থাকি। তোমরা kaggle এর ওয়েবসাইটে একটু ঘুরে দেখে আসো। আশা করি একটা ধারনা পেয়ে যাবে। আমরা যেহেতু স্ক্রেচ থেকে কাজ করতে চাচ্ছি, তাই আমরা খুবই সিম্পল একটা ডেটাসেট দিয়েই পথচলা শুরু করবো। House Price Prediction ডেটাসেট এক্ষেত্রে বেশ ভালো অপশন।

আমরা তো ডেটাসেট পেয়ে গেলাম, তাহলে এখন আমরা আসলে কোড কোথায় লিখবো এবং সে কোড রানই বা করাবো কোথায়, সেটা হলো প্রশ্ন। এক কথায় এখন আমাদের এনভায়রনমেন্ট সেটআপ করার পালা।

পাইথনে কোড করা বা তা রান করানোর ক্ষেত্রে গুগল কোলাব (Google Colab) জনপ্রিয় একটি IDE। মেশিন লার্নিং মডেলগুলো রান করানোর জন্য যে লাইব্রেরিগুলো দরকার সেসব গুগল কোলাব এ ইন্সটল করা রয়েছে। তাছাড়া pip রান করানোর মাধ্যমে যখন যে লাইব্রেরি দরকার তা তোমরা তোমাদের লোকাল মেশিনে নিয়ে আসতে পারো। তাছাড়া Anaconda (package management system) ইন্সটল করারমাধ্যমেও কাজটি সহজেই করে ফেলতে পারো। এই এনভায়রনমেন্ট সেটআপ নিয়ে একটি ভালো মানের ভিডিও টিউটোরিয়ালের লিংক দিয়ে দিবো যাতে তোমরা কাজটা কোনো প্রকার ঝামেলা ছাড়াই করে ফেলতে পারো।

এনভায়রনমেন্ট সেটআপ করার কাজটাও তাহলে আমরা শেষ করে ফেললাম। কি বলো? কাজের দিকে এগোনো যাক তাহলে!

Google Colab setup Tutorial

Anaconda setup Tutorial

ডেটাসেট পর্যালোচনাঃ

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

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

তাই, ঠিকমতো ফিচার সিলেকশন না হলে বা ঠিকমতো ডেটাগুলোকে ট্রেইনিং এর জন্য ফরমেটিং না করলে ইভালুয়েশনে ভুল হবে আর ইভালুয়েশনে ভুল হলে ওভার-অল মডেল পার্ফরম্যান্স ভালো হবে না। তাই বলা যায় "Understanding dataset is very important"।

আমরা যেহেতু Kaggle এর House Price Prediction ডেটাসেট নিয়েছি কাজ করার জন্য, এই ডেটাসেটের ফিচারগুলো নিয়ে মূলত কাজ করতে হবে। ফিচারগুলোর মধ্যে ডেট, প্রাইজ, বেডরুমের সংখ্যা, তলার সংখ্যা ইত্যাদি ফিচারগুলো রয়েছে। আর আরেকটা জিনিস হচ্ছে মেশিন লার্নিং এ ডেটাসেট এর ফরমেট হিসেবে সবচেয়ে বেশি ব্যবহৃত হয় CSV ফরমেট। আমাদের কাজের জন্য সিলেক্ট করা ডেটাসেটটিও সিএসভি ফরমেটে আছে। আমরা এই ডেটাসেটের উপর মেশিন লার্নিং মডেল রান করিয়ে হাউজ প্রাইজ প্রিডিক্ট করবো। যেহেতু আমরা সুপারভাইজড মেশিন লার্নিং দিয়েই কাজটা করবো সেহেতু এখানে প্রাইজটা (Price) হচ্ছে টারগেট ভ্যারিয়েবল এবং বাকিগুলো হচ্ছে ফিচার।

এবার মূল কাজে হাত দেয়া যাক। সবার প্রথমে যেটা করে নিতে হবে সেটা হচ্ছে ডেটা প্রিপ্রসেসিং।

ডেটা প্রিপ্রসেসিংঃ

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

চলো এবার কোডে যাওয়া যাক।

1import pandas as pd
2
3# import the dataset
4raw_dataset = pd.read_csv('./data.csv')
5
6# turning dataset into a pandas dataframe
7dataframe = pd.DataFrame(raw_dataset)
8
9# head(x) method returns the first 'x' rows of the dataframe
10dataframe.head(5)
project photo

তোমরা লক্ষ্য করে দেখলেই দেখবে এই লেখাতে বলেছিলাম আমাদের কিছু লাইব্রেরির দরকার পরবে। আশা করি তোমরা তা নিয়ে কিছু ধারনা নিয়ে রেখেছো। তাহলে বোঝতেই পারছো এবার আমাদের লাইব্রেরি ইম্পোর্ট করার পালা। প্রথমেই আমাদের যে লাইব্রেরি ইম্পোর্ট করে নিতে হবে সেটা হচ্ছে পান্ডাস (Pandas)। কারন ডেটাসেট ইম্পোর্ট করতে হলে আমাদের পান্ডাস-এর একটি ফাংশন "read_csv()" এর সাহায্য নিতে হবে। এই ফাংশনটি সিএসভি ফাইলের পাথটাকে প্যারামিটার হিসেবে নিয়ে ওই সিএসভি ফাইলটাকে প্রোগ্রামের মধ্যে লোড করে। তারপর, ডেটাফ্রেম মেথডটি ব্যবহার করে আমরা ডেটাসেটের একটা কপি বানিয়ে নেই। বলতে পারবে কেনো এমনটা করা হয়? যাতে অরিজিনাল ডেটাসেটটিতে কোনোভাবে পরিবর্তন না আসে।

তাহলে এবার তোমারা কোডে দেখতেই পারছো কিভাবে আমরা ডেটাসেটটি ইম্পোর্ট করে নিলাম এবং ডেটাফ্রেমে ডেটাকে রিড করালাম।

আরেকটা লাইনে দেখতে পারছো যে "head" নামে একটা ফাংশন ব্যাবহার করা হয়েছে। এটার কাজ আসলে কি হতে পারে একটু চিন্তা করে দেখো তো! নাম দেখেই বোঝা যাচ্ছে তাই না? এই ফাংশনটি একটি নাম্বার ভ্যালু নেয় প্যারামিটার হিসেবে এবং ডেটাফ্রেমের ততোটা রো (row) কে রিটার্ন করে। যেমন এখানে যেমনটা করা হয়েছে, "dataframe.head(5)" তার মানে ডেটাসেটের প্রথম ৫ টা রো কে প্রিন্ট করে দেখিয়েছে। এমনই আরেকটা ফাংশন আছে "tail()" নামে যেটি লাস্ট থেকে এভাবে রো রিটার্ন করবে। এই ফাংশনগুলো বাই ডিফল্ট ১০ টা রো কে রিটার্ন করে থাকে (প্যারামিটার হিসেবে ভ্যালু না দেয়া হলে)।

এবার প্রিপ্রসেসিং এর কাজে জাম্প করা যাক।

লক্ষ্য করে দেখলে দেখবে এই ডেটাসেটে একটি ফিচার আছে ডেট (date) নামে। আচ্ছা একটু ভেবে দেখো তো বাড়ির দামে এই ডেট ফিল্ডটা কি খুব একটা বড় ভূমিকা রাখে? অবশ্যই না। হ্যাঁ তোমরা বলবে যে সময়ের সাথে সাথে বাড়ির দাম বাড়ে বা কমে। মোস্ট অব দ্যা টাইম কমে না যদিও। কিন্তু আসলে এই ফিল্ড আমাদের এই কাজে খুব গুরুত্বপূর্ণ কোনো ফিচার নয়। তাই আমরা এই ফিচারকে এলিমিনেট করে ফেলবো। কারন, আমরা জানি যে অসামঁজস্য ফিচার রাখলে পারফরম্যান্স ডিক্রিজ করতে পারে। তাহলে নিচের কোডটিতে দেখো কিভাবে আমরা এই ডেট কলামকে ড্রপ করে ফেলেছি।

1# dropping 'date' column
2dataframe.drop('date', axis = 1, inplace = True)

তার মানে ডেটাসেট ক্লিন করে ফেলেছি তাই না?

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

ডুপ্লিকেট ডেটাকে রিমোভ করা, ডেটা নরমালাইজেশন (Normalization), ফিচার ইঞ্জিনিয়ারিং (Feature Engineering), ডেটা অগমেন্টেশন (Data augmentation) ইত্যাদি খুবই গুরুত্বপূর্ণ।

এখন আমরা যদি আমাদের ফিচারগুলোর ডেটা টাইপ দেখতে চাই তাহলে কি করবো? নিচের কোডটিতে তাই করা হয়েছে।

1# "dtypes" property returns the data type of each column
2dataframe.dtypes
project photo

ফিচারগুলোর মধ্যে "street", " state zip" and "country" হচ্ছে অব্জেক্ট টাইপ এবং বাকি কলামগুলো নিউমেরিক্যাল টাইপের (integer বা float)। আমরা জানি যে মেশিন লার্নিং অ্যালগরিদম ক্যাটেগরিক্যাল ডেটার উপর কাজ করে না। কিন্তু আবার ক্যাটেগরিক্যাল ডেটা মেশিন লার্নিং এ খুবই গুরুত্বপূর্ণ, কারণ ডেটা টাইপ ক্লাসিফাই করা বা ক্যাটেগরাইজ করাতে সাহায্য করে এই ক্যাটেগরিক্যাল ডেটা। তাই ক্যাটেগরিক্যাল ডেটাকে নিউমেরিক্যাল ডেটাতে কনভার্ট করে নিতে হয়। আর এই প্রসেসকে বলে ফিচার এনকোডিং (Feature Encoding)। এই ফিচার এনকোডিং কয়েক ধরণের হয়ে থাকে যেমম উয়ান-হট এনকোডিং (One-hot encoding), লেবেল এনকোডিং (Label Encoding) এবং বাইনারি এনকোডিং (Binary Encoding)।

একে একে দেখে নেয়া যাক এই ৩ টাইপের ফিচার এনকোডিং কে।

উয়ান-হট এনকোডিং আসলে বাইনারি ভ্যালু (0 অথবা 1) নিয়ে কাজ করে। ওই ক্যাটেগরিক্যাল ভ্যালুর উপস্থিতি থাকলে ১ আর নয়তো ০। উয়ান-হট এনকোডার প্রতিটি ভিন্ন ভিন্ন টাইপের ক্যাটেগরিক্যাল ভ্যালুর জন্য ভিন্ন ভিন্ন কলাম তৈরি করে এবং তার এক্সিসটেন্সের উপর ভিত্তি করে 0 বা 1 ভ্যালু অ্যাসাইন করে।

project photo

উয়ান-হট এনকোডিং বোঝা গেল। এবার দেখি লেবেল এনকোডিং কিভাবে কাজ করে। নাম দেখেই কিছুটা বোঝা যাচ্ছে যে ক্যাটেগরিকে লেভেলিং করা। তার মানে, প্রতিটা ক্যাটেগরিকে একটি নিউমেরিক্যাল লেভেল দিয়ে দেয়াই হচ্ছে লেভেল এনকোডিং। যেমন এখানে, "A"-কে "0", "B"-কে "1" এবং "C"-কে "2" দেওয়া হয়েছে

project photo

আর বাইনারি এনকোডিং ও কিছুটা এমনই। বাইনারি এনকোডিং এ ভিন্ন ভিন্ন ক্যাটেগরির জন্য ভিন্ন ভিন্ন বাইনারি স্ট্রিং অ্যাসাইন করা হয়।

এ সব ধরনের এনকোডারই আছে "scikit-learn" নামের লাইব্রেরির মধ্যে।

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

নিচের কোডটা একটু মনোযোগ দিয়ে দেখো। দেখো ধরতে পারো কিনা এখানে কি করা হয়েছে।

1# Getting all the columns name where dtype == object
2cat_cols = [col for col in dataframe.columns if dataframe[col].dtype == "object"]
3
4# Feature Encoding the categorical colums
5from sklearn.preprocessing import LabelEncoder
6label_encoder = LabelEncoder()
7
8# Turns categorical data into numerical data
9for col in cat_cols:
10    dataframe[col] = label_encoder.fit_transform(dataframe[col])
11    
12dataframe.head(10)
project photo

এই কোডটিতে প্রথমে "cat_cols" নামের একটি অ্যারেতে অব্জেক্ট টাইপের কলামগুলোর নাম নেয়া হয়েছে। তারপর "LabelEncoder" এর একটি ইন্সটেন্স তৈরি করে নেয়া হয়েছে যার নাম "label_encoder"। অব্জেক্ট টাইপ কলামগুলোর লিস্ট বা অ্যারেতে একটি লুপ চালিয়ে "fit_transform()" ফাংশনকে কল করে খুব সহজেই এনকোডিং এর কাজটা করে ফেলা হয়েছে।

আশা করি জিনিসটা খুব ভালোভাবেই তোমরা বুঝতে পেরেছ। আর কাজটা নিজ হাতে করে দেখতে হবে। কারন পুরো প্রসেসটা নিজ হাতে করে দেখলে প্রসেসটার উপর ভালো একটা আইডিয়া হয়ে যাবে।