Chapter 6 of 18
The invisible line every classifier draws through your data
অনেক মেশিন লার্নিং প্রবলেমই আসলে একটা সহজ প্রশ্নে গিয়ে ঠেকে: "এই জিনিসটা কোন গ্রুপের?" এই ইমেইলটা স্প্যাম, নাকি স্প্যাম না? এই ছবিটা বিড়াল, নাকি কুকুর? এই কাস্টমার কি চলে যাবে, নাকি থেকে যাবে? এই ধরনের প্রবলেম — জিনিসকে নির্দিষ্ট সংখ্যক নামযুক্ত ক্যাটাগরিতে ভাগ করা — একে বলে classification (শ্রেণীবিভাগ)।
একটা সহজ ভার্সন কল্পনা করুন: একটা মডেল যেটা একটা ফলের দুইটা সংখ্যা দেখে — এর ওজন গ্রামে, আর ব্যাস সেন্টিমিটারে — আর ঠিক করে এটা আপেল না কমলা। প্রতিটা ফলকে একটা দুই-মাত্রিক গ্রাফে একটা বিন্দু হিসেবে প্লট করুন, একটা অক্ষে ওজন, আরেকটাতে ব্যাস। আপেলগুলো গ্রাফের একটা অংশে জড়ো হয়ে থাকে; কমলাগুলো আরেকটা অংশে। একটা classifier-এর পুরো কাজই হলো একটা নতুন বিন্দু — একটা নতুন ফল যা এটা আগে দেখেনি — দেখে ঠিক করা এটা কোন জড়ো হওয়া অংশের।
Classification মানে একটা ইনপুটকে একটা নির্দিষ্ট সংখ্যক ক্যাটাগরির একটাতে বসিয়ে দেওয়া, লেবেল করা উদাহরণ থেকে মডেল যে প্যাটার্ন শিখেছে তার উপর ভিত্তি করে।
এটা regression থেকে আলাদা, যেখানে একটা মডেল একটা সংখ্যা প্রেডিক্ট করে যা একটা কন্টিনিউয়াস রেঞ্জে যেকোনো মান নিতে পারে — যেমন একটা ফলের সঠিক ওজন, বা একটা বাসার সঠিক দাম প্রেডিক্ট করা। Classification একটা ক্যাটাগরি প্রেডিক্ট করে, সংখ্যা না: "আপেল" বা "কমলা", "১৪২.৭ গ্রাম" না।
নিজেকে জিজ্ঞেস করুন: "মডেল কি একটা নির্দিষ্ট, লেবেল করা আউটকামের মধ্যে থেকে বেছে নিচ্ছে?" যদি হ্যাঁ হয় — স্প্যাম/না-স্প্যাম, বিড়াল/কুকুর/পাখি, অ্যাপ্রুভ/ডিনাই — এটা classification। মডেল যদি বরং একটা আনবাউন্ডেড সংখ্যা প্রেডিক্ট করে, সেটা regression।
একবার classification-কে গ্রাফের বিন্দুগুলোকে আলাদা অংশে ভাগ করা হিসেবে কল্পনা করলে, একটা স্বাভাবিক প্রশ্ন আসে: মডেল ঠিক কীভাবে ঠিক করে একটা অংশ কোথায় শেষ আর আরেকটা কোথায় শুরু? উত্তর হলো একটা decision boundary।
একটা decision boundary হলো সেই রেখা (বা কার্ভ, বা সারফেস, ইনপুট কয়টা তার উপর নির্ভর করে) যেটা একটা মডেল যে অংশগুলো ভিন্ন ভিন্ন ক্লাসকে দিয়েছে সেগুলোকে আলাদা করে। বাউন্ডারির একপাশে, মডেল প্রেডিক্ট করে "আপেল"। অন্যপাশে, প্রেডিক্ট করে "কমলা"। ঠিক বাউন্ডারির উপরে যেকোনো বিন্দুই একটা টস-আপ — মডেল সবচেয়ে বেশি অনিশ্চিত এটা কোন ক্লাসের।
ফলের উদাহরণে ফিরে যাই। ওজন-বনাম-ব্যাস গ্রাফে যদি এমনভাবে একটা সরল রেখা আঁকেন যাতে প্রায় প্রতিটা আপেলের বিন্দু একপাশে পড়ে আর প্রায় প্রতিটা কমলার বিন্দু অন্যপাশে পড়ে, সেই রেখাটাই মডেলের শেখা decision boundary। একদম নতুন একটা ফলকে শুধু চেক করে ক্লাসিফাই করা হয় এর বিন্দুটা রেখার কোন পাশে পড়ছে — এর চেয়ে জটিল কিছু না।
একটা decision boundary হলো ইনপুট স্পেসের সেই সীমা যেখানে একটা classifier-এর প্রেডিকশন একটা ক্লাস থেকে আরেকটাতে বদলে যায়।
এই বাউন্ডারি কোনো মানুষ চোখে দেখে হাতে আঁকে না। এটা মডেল যা weights আর bias শিখেছে তার সরাসরি, দৃশ্যমান ফলাফল — ট্রেনিংয়ের সময় weights বদলান, আর বাউন্ডারিও নিজে থেকেই মিলিয়ে সরে যায় আর নতুন আকার নেয়।
একটা প্রেডিকশন দেখলে শুধু জানতে পারবেন মডেল একটা বিন্দু নিয়ে কী ভাবছে। Decision boundary দেখলে জানতে পারবেন মডেল পুরো প্রবলেম সম্পর্কে কী শিখেছে — ক্লাসগুলো আলাদা করার সম্পূর্ণ স্ট্র্যাটেজি, একটা ছবিতে দেখানো।
একটা classifier যে সবচেয়ে সহজ ধরনের decision boundary তৈরি করতে পারে তা হলো একটা সরল রেখা (দুই মাত্রায়), একটা সমতল (তিন মাত্রায়), বা আরও সাধারণভাবে উচ্চতর মাত্রায় একটা hyperplane। একে বলা হয় linear decision boundary, আর এটা সরাসরি একটা লিনিয়ার সূত্র থেকে আসে — weight দিয়ে ইনপুট গুণ করে, যোগ করে, প্লাস একটা bias:
মডেল একটা ক্লাস প্রেডিক্ট করে যখন , আর অন্যটা প্রেডিক্ট করে যখন । বাউন্ডারিটা ঠিক সেই বিন্দুগুলোর সেট যেখানে — দুইটা আউটকামের মাঝের ভাগরেখা। একটা সিঙ্গেল পারসেপ্ট্রন, বা একটা সাধারণ logistic regression মডেল, ঠিক এই ধরনের বাউন্ডারি তৈরি করে: ইনপুট স্পেসের মধ্য দিয়ে একটা মাত্র সরল কাট।
Linear বাউন্ডারি আকর্ষণীয় কারণ এগুলো সহজ, হিসাব করা দ্রুত, আর বুঝতে সহজ — আপনি আক্ষরিক অর্থেই পড়ে ফেলতে পারেন কোন ইনপুট প্রেডিকশনকে কোন ক্লাসের দিকে ঠেলছে, শুধু প্রতিটা weight-এর সাইন আর মান দেখেই। আর অনেক বাস্তব প্রবলেমের জন্য, এগুলো ভালো কাজ করে: যদি আপেল আর কমলা সত্যিই ওজন আর ব্যাসের উপর আলাদাভাবে জড়ো হয়, একটা সরল রেখা সত্যিই এদের আলাদা করে দিতে পারে।
একটা linear বাউন্ডারি সবসময়ই একটা মাত্র সরল কাট। যদি দুইটা ক্লাসকে কোনো একটা সরল রেখা দিয়েই আলাদা না করা যায় — যতই ঘোরান বা সরান না কেন — একটা linear classifier সবসময়ই কিছু বিন্দুকে ভুল ক্লাসিফাই করবে, যতই ট্রেন করুন না কেন। এটা কোনো ট্রেনিং ব্যর্থতা না; এটা মডেলের আকৃতির একটা কঠিন সীমাবদ্ধতা।
এই সীমাবদ্ধতার ক্লাসিক উদাহরণ হলো XOR প্রবলেম: চারটা বিন্দু, দুইটা একটা ক্লাসের লেবেল করা আর দুইটা অন্যটার, এমনভাবে সাজানো যাতে কোনো একটা সরল রেখা এদের সঠিকভাবে আলাদা করতে পারে না। এই চ্যাপ্টারের নিচের দিকে ভিজ্যুয়ালাইজেশনে আপনি ঠিক এই কেসটাই দেখবেন।
যখন একটা মাত্র সরল রেখা সত্যিই ক্লাসগুলোকে আলাদা করতে পারে না, মডেলের এমন একটা বাউন্ডারি দরকার হয় যা বাঁকতে পারে, কার্ভ করতে পারে, বা আরও জটিল আকারে জড়ো হওয়া অংশগুলোর চারপাশে মুড়িয়ে যেতে পারে। এটাই একটা non-linear decision boundary।
Non-linear বাউন্ডারি আসে এমন মডেল থেকে যাদের একটা সিঙ্গেল লিনিয়ার সূত্রের চেয়ে বেশি এক্সপ্রেসিভ ক্ষমতা আছে — যেমন একটা হিডেন লেয়ার আর non-linear অ্যাক্টিভেশন ফাংশনসহ একটা নিউরাল নেটওয়ার্ক, একটা decision tree (যা স্পেসকে ধাপে-ধাপে সিরিজ কাট দিয়ে কাটে), বা non-linear kernel ব্যবহার করা একটা support vector machine। একটা সরল কাটের বদলে, এই মডেলগুলো কার্ভড বাউন্ডারি, ঢেউয়ের মতো বাউন্ডারি, একটা ক্লাস্টারের চারপাশে বন্ধ লুপ, বা একসাথে জোড়া লাগানো একাধিক সরল সেগমেন্টের বাউন্ডারি তৈরি করতে পারে।
আবার XOR প্রবলেম দেখি: আর -এ দুইটা বিন্দু একটা ক্লাসের, আর আর -এ দুইটা বিন্দু অন্যটার। এদের প্লট করলে দেখবেন দুইটা ক্লাস একে অপরের ঠিক কোনাকুনি বিপরীতে সাজানো — কোনো একটা সরল রেখাই আর দুইটাকে একপাশে রাখতে পারবে না, আর একইসাথে আর -কে অন্যপাশে রাখতে পারবে না। কিন্তু দুইটা নিউরনের মাত্র একটা হিডেন লেয়ারওয়ালা একটা নেটওয়ার্ক দুইটা সরল কাটকে একসাথে মিলিয়ে একটা বাঁকা, non-linear বাউন্ডারি তৈরি করতে পারে যা চারটা বিন্দুকেই নিখুঁতভাবে আলাদা করে।
একটা মাত্র লেয়ারের weight আর একটা bias শুধু একটা সরল কাটই আঁকতে পারে। এর উপর দ্বিতীয় একটা লেয়ার বসান, প্রথম লেয়ারের একাধিক কাটের আউটপুট মিলিয়ে, আর সেই কাটগুলোর সমন্বয় একটা কার্ভের কাছাকাছি যেতে পারে — যত বেশি নিউরন আর লেয়ার জড়িত থাকবে, নেটওয়ার্ক তত জটিল আকৃতির বাউন্ডারি তৈরি করতে পারবে।
সহজ দিয়ে শুরু করুন: প্রথমে একটা linear মডেল চেষ্টা করুন। যদি এটা এমনভাবে বারবার কিছু বিন্দুকে ভুল ক্লাসিফাই করতে থাকে যেটা স্ট্রাকচারাল মনে হয় — শুধু নয়েজ না, বরং এমন বিন্দু যা রেখা যেভাবেই ঘোরান না কেন সবসময় "ভুল" পাশে থাকে — এটা একটা লক্ষণ যে আসল বাউন্ডারি non-linear, আর একটা বেশি এক্সপ্রেসিভ মডেল চেষ্টা করে দেখার মতো।
Non-linear বাউন্ডারি বেশি শক্তিশালী, কিন্তু সেই শক্তি একটা দুই-ধারী তলোয়ার: একটা অতিরিক্ত ফ্লেক্সিবল বাউন্ডারি আসল প্যাটার্নের বদলে নয়েজি ইন্ডিভিজুয়াল বিন্দুগুলোর চারপাশে নিজেকে বাঁকিয়ে ফেলতে পারে, একটা সমস্যা যাকে বলে overfitting। লক্ষ্য কখনোই "সবচেয়ে ফ্লেক্সিবল সম্ভাব্য বাউন্ডারি" না — লক্ষ্য হলো এমন একটা বাউন্ডারি আকৃতি যা আসলেই প্রবলেমের প্রকৃত গঠনের সাথে মেলে।
এখন পর্যন্ত সবকিছুতে দুইটা ক্লাস ব্যবহার হয়েছে — আপেল বা কমলা, স্প্যাম বা না-স্প্যাম। একে বলা হয় binary classification: ঠিক দুইটা সম্ভাব্য আউটকাম, আর এদের আলাদা করার জন্য একটা decision boundary-ই যথেষ্ট।
অনেক বাস্তব প্রবলেমে দুইটার বেশি ক্যাটাগরি থাকে: একটা হাতে-লেখা ডিজিটকে থেকে পর্যন্ত ক্লাসিফাই করা (দশটা ক্লাস), একটা নিউজ আর্টিকেলকে বিষয় অনুযায়ী ক্লাসিফাই করা (রাজনীতি, খেলা, প্রযুক্তি, ইত্যাদি), বা একটা ছবিকে একশোটা ভিন্ন প্রাণীর প্রজাতির একটা হিসেবে ক্লাসিফাই করা। এটাই multi-class classification।
মূল আইডিয়া বদলায় না — মডেল এখনও ইনপুট স্পেসকে অংশে ভাগ করে, প্রতিটা ক্লাসের জন্য একটা — কিন্তু এখন শুধু দুইটার বদলে একাধিক বাউন্ডারি স্পেসকে একাধিক অংশে কাটে। ফলের গ্রাফটাই আবার কল্পনা করুন, কিন্তু এবার আপেল, কমলা, আর কলা সহ: একটা রেখা গ্রাফকে দুই ভাগে ভাগ করার বদলে, আপনার এমন বাউন্ডারি দরকার হবে যা একাধিক অংশ তৈরি করে, প্রতিটা ফলের জন্য একটা অংশ, যারা শেয়ার করা প্রান্তে একে অপরের সাথে মিলিত হয়।
| Binary Classification | Multi-class Classification | |
|---|---|---|
| ক্লাস সংখ্যা | ঠিক ২টা | ৩টা বা বেশি |
| কয়টা বাউন্ডারি লাগে | দুইটা ক্লাসকে আলাদা করতে ১টা বাউন্ডারি | একাধিক বাউন্ডারি স্পেসকে একাধিক অংশে ভাগ করে |
| সাধারণ আউটপুট | একটা মাত্র প্রোবাবিলিটি (যেমন 'স্প্যাম' হওয়ার প্রোবাবিলিটি) | প্রতিটা ক্লাসের জন্য একটা প্রোবাবিলিটি, সবগুলো যোগ করলে ১ |
| উদাহরণ | ইমেইল: স্প্যাম বা না-স্প্যাম | হাতে-লেখা ডিজিট: ০ থেকে ৯ |
বাস্তবে multi-class classification তৈরির দুইটা সাধারণ উপায় আছে। একটা হলো এমন একটা মডেল ট্রেন করা যা প্রতিটা ক্লাসের জন্য একসাথে সরাসরি একটা প্রোবাবিলিটি আউটপুট করে (নিউরাল নেটওয়ার্কে সাধারণ, softmax নামের একটা টেকনিক ব্যবহার করে)। আরেকটা হলো multi-class প্রবলেমটাকে একাধিক binary প্রবলেমে ভেঙে ফেলা — যেমন, "এটা কি ক্লাস A নাকি না," "এটা কি ক্লাস B নাকি না," এভাবে — আর এদের ফলাফল একসাথে মেলানো। যেভাবেই হোক, অন্তর্নিহিত ছবিটা একই: ইনপুট স্পেস যতগুলো ক্লাস আছে ততগুলো অংশে কাটা হয়।
"Multi-class"-কে "multi-label"-এর সাথে গুলিয়ে ফেলবেন না। Multi-class মানে প্রতিটা ইনপুট একাধিক ক্যাটাগরির ঠিক একটার — একটা ডিজিট হয় ৩ নয় ৭, কখনোই দুটোই না। Multi-label মানে একটা ইনপুট একসাথে একাধিক ক্যাটাগরির হতে পারে (একটা নিউজ আর্টিকেল একসাথে "রাজনীতি" আর "অর্থনীতি" দুটোতেই ট্যাগ করা থাকতে পারে)। এখানে বর্ণনা করা decision boundary সরাসরি multi-class প্রবলেমে প্রয়োগ হয়; multi-label প্রবলেম সাধারণত একাধিক আলাদা binary সিদ্ধান্ত হিসেবে সামলানো হয়, প্রতিটা সম্ভাব্য লেবেলের জন্য একটা করে।
নিচের ইন্টারেক্টিভ ডেমোটা ক্লাসিক XOR প্রবলেম প্লট করে: চারটা বিন্দু এমনভাবে সাজানো যাতে কোনো একটা সরল রেখা দুইটা ক্লাসকে আলাদা করতে পারে না। একটা সিঙ্গেল পারসেপ্ট্রন (যা শুধু একটা linear বাউন্ডারিই আঁকতে পারে) আর একটা ছোট 2-লেয়ার নেটওয়ার্ক (যা একটা non-linear বাউন্ডারি আঁকতে পারে) এর মধ্যে টগল করে দেখুন কীভাবে decision অংশগুলো বদলায়।
একটা সিঙ্গেল পারসেপ্ট্রন আর একটা 2-লেয়ার MLP-এর মধ্যে টগল করে দেখুন কীভাবে একটা linear মডেল XOR-এ ব্যর্থ হয় আর একটা non-linear মডেল এটা নিখুঁতভাবে সমাধান করে।
3 of 4 XOR points correctly classified. No straight line can separate XOR — this is exactly the limitation Chapter 7 covers.
দুইটা মোডের মধ্যে টগল করার সময় কয়েকটা জিনিস খেয়াল করার মতো:
এটাই সবচেয়ে স্পষ্ট উদাহরণ কেন একটা মডেলের decision boundary যে আকৃতি নিতে পারে সেটা সরাসরি এটা কী শিখতে পারবে তা সীমাবদ্ধ করে দেয়, যতই ট্রেনিং ডেটা বা ট্রেনিং সময় দিন না কেন।