ভূমিকা
মাঝে মাঝে বিভ্রান্ত রৈখিক রিগ্রেশনের নতুনদের দ্বারা - শব্দটি ভাগ করার কারণে প্রত্যাগতি - পণ্য সরবরাহ সংশ্লেষণ থেকে অনেক আলাদা রৈখিক রিগ্রেশনের. যদিও লিনিয়ার রিগ্রেশন 2, 2.45, 6.77 বা এর মতো মানগুলির পূর্বাভাস দেয় ক্রমাগত মান, এটি তৈরি একটি প্রত্যাগতি অ্যালগরিদম, পণ্য সরবরাহ সংশ্লেষণ 0 বা 1, 1 বা 2 বা 3 এর মতো মানগুলির পূর্বাভাস দেয়, যা হয়৷ পৃথক মান, এটি তৈরি একটি শ্রেণীবিন্যাস অ্যালগরিদম হ্যাঁ, এটা বলা হয় প্রত্যাগতি কিন্তু একটি শ্রেণীবিন্যাস অ্যালগরিদম একটি মুহূর্ত যে আরও।
অতএব, যদি আপনার ডেটা বিজ্ঞানের সমস্যায় ক্রমাগত মান জড়িত থাকে, তাহলে আপনি একটি প্রয়োগ করতে পারেন প্রত্যাগতি অ্যালগরিদম (রৈখিক রিগ্রেশন তাদের মধ্যে একটি)। অন্যথায়, যদি এতে ইনপুট, বিচ্ছিন্ন মান বা শ্রেণীবদ্ধকরণ জড়িত থাকে, আপনি একটি আবেদন করতে পারেন শ্রেণীবিন্যাস অ্যালগরিদম (লজিস্টিক রিগ্রেশন তাদের মধ্যে একটি)।
এই গাইডে, আমরা স্কিট-লার্ন লাইব্রেরির সাথে পাইথনে লজিস্টিক রিগ্রেশন করব। আমরাও ব্যাখ্যা করব কেন শব্দটি "রিগ্রেশন" নামটিতে উপস্থিত রয়েছে এবং কীভাবে লজিস্টিক রিগ্রেশন কাজ করে।
এটি করার জন্য, আমরা প্রথমে ডেটা লোড করব যা শ্রেণীবদ্ধ, ভিজ্যুয়ালাইজড এবং প্রাক-প্রক্রিয়া করা হবে। তারপর, আমরা একটি লজিস্টিক রিগ্রেশন মডেল তৈরি করব যা সেই ডেটা বুঝতে পারবে। এই মডেলটি তারপর মূল্যায়ন করা হবে, এবং নতুন ইনপুটের উপর ভিত্তি করে মান ভবিষ্যদ্বাণী করার জন্য নিযুক্ত করা হবে।
প্রেরণা
আপনি যে কোম্পানির জন্য কাজ করেন সে একটি তুর্কি কৃষি খামারের সাথে একটি অংশীদারিত্ব করেছে৷ এই অংশীদারিত্বের সাথে কুমড়ার বীজ বিক্রি করা জড়িত। কুমড়োর বীজ মানুষের পুষ্টির জন্য খুবই গুরুত্বপূর্ণ। এগুলিতে কার্বোহাইড্রেট, চর্বি, প্রোটিন, ক্যালসিয়াম, পটাসিয়াম, ফসফরাস, ম্যাগনেসিয়াম, আয়রন এবং জিঙ্কের একটি ভাল অনুপাত রয়েছে।
ডেটা সায়েন্স দলে, আপনার কাজটি শুধুমাত্র ডেটা ব্যবহার করে কুমড়োর বীজের প্রকারের মধ্যে পার্থক্য বলা - বা শ্রেণীকরণের কাজ বীজের ধরন অনুযায়ী তথ্য।
তুর্কি খামার দুটি কুমড়া বীজ ধরনের সঙ্গে কাজ করে, একটি বলা হয় সার্সেভেলিক এবং অন্যান্য উরগুপ সিভরিসি.
কুমড়া বীজ শ্রেণীবদ্ধ করতে, আপনার দল 2021 কাগজ অনুসরণ করেছে "কুমড়া বীজের শ্রেণীবিভাগে মেশিন লার্নিং পদ্ধতির ব্যবহার (Cucurbita pepo L.)। জেনেটিক রিসোর্স এবং ক্রপ বিবর্তন" কোকলু, সারিগিল এবং ওজবেক থেকে - এই কাগজে, ছবিগুলি থেকে বীজ পরিমাপের ছবি তোলা এবং বের করার জন্য একটি পদ্ধতি রয়েছে।
কাগজে বর্ণিত প্রক্রিয়াটি শেষ করার পরে, নিম্নলিখিত পরিমাপগুলি বের করা হয়েছিল:
- ফোন - একটি কুমড়া বীজের সীমানার মধ্যে পিক্সেলের সংখ্যা
- ঘের - একটি কুমড়া বীজের পিক্সেল পরিধি
- প্রধান অক্ষ দৈর্ঘ্য – এছাড়াও একটি কুমড়া বীজের পিক্সেল পরিধি
- ক্ষুদ্র অক্ষ দৈর্ঘ্য - একটি কুমড়া বীজের ছোট অক্ষ দূরত্ব
- ছিট - একটি কুমড়া বীজের উদ্ভটতা
- উত্তল এলাকা - কুমড়ার বীজ দ্বারা গঠিত অঞ্চলে ক্ষুদ্রতম উত্তল শেলের পিক্সেলের সংখ্যা
- ব্যাপ্তি - বাউন্ডিং বক্স পিক্সেলের সাথে একটি কুমড়া বীজ এলাকার অনুপাত
- সমতুল্য ব্যাস – কুমড়ার বীজের ক্ষেত্রফলের গুণের বর্গমূলকে চার দিয়ে ভাগ করে পাই
- সংহতি - একই পরিধি সহ বৃত্তের ক্ষেত্রফলের তুলনায় কুমড়া বীজের ক্ষেত্রফলের অনুপাত
- ঘনত্ব - কুমড়ার বীজের উত্তল এবং উত্তল অবস্থা
- গোল আকৃতি - কুমড়ার বীজের ডিম্বাকৃতি তার প্রান্তের বিকৃতি বিবেচনা না করে
- অনুপাত - কুমড়া বীজের অনুপাত
এই পরিমাপ আপনি সঙ্গে কাজ আছে. পরিমাপ ছাড়াও, আছে শ্রেণী দুই ধরনের কুমড়া বীজের জন্য লেবেল।
বীজ শ্রেণীবদ্ধ করা শুরু করতে, আসুন ডেটা আমদানি করি এবং এটি দেখতে শুরু করি।
ডেটাসেট বোঝা
বিঃদ্রঃ: আপনি কুমড়ো ডেটাসেট ডাউনলোড করতে পারেন এখানে.
ডেটাসেট ডাউনলোড করার পরে, আমরা এটি ব্যবহার করে একটি ডেটাফ্রেম কাঠামোতে লোড করতে পারি pandas
লাইব্রেরি যেহেতু এটি একটি এক্সেল ফাইল তাই আমরা ব্যবহার করব read_excel()
পদ্ধতি:
import pandas as pd
fpath = 'dataset/pumpkin_seeds_dataset.xlsx'
df = pd.read_excel(fpath)
একবার ডেটা লোড হয়ে গেলে, আমরা ব্যবহার করে প্রথম 5 সারিগুলিতে দ্রুত উঁকি দিতে পারি head()
পদ্ধতি:
df.head()
এর ফলে:
Area Perimeter Major_Axis_Length Minor_Axis_Length Convex_Area Equiv_Diameter Eccentricity Solidity Extent Roundness Aspect_Ration Compactness Class
0 56276 888.242 326.1485 220.2388 56831 267.6805 0.7376 0.9902 0.7453 0.8963 1.4809 0.8207 Çerçevelik
1 76631 1068.146 417.1932 234.2289 77280 312.3614 0.8275 0.9916 0.7151 0.8440 1.7811 0.7487 Çerçevelik
2 71623 1082.987 435.8328 211.0457 72663 301.9822 0.8749 0.9857 0.7400 0.7674 2.0651 0.6929 Çerçevelik
3 66458 992.051 381.5638 222.5322 67118 290.8899 0.8123 0.9902 0.7396 0.8486 1.7146 0.7624 Çerçevelik
4 66107 998.146 383.8883 220.4545 67117 290.1207 0.8187 0.9850 0.6752 0.8338 1.7413 0.7557 Çerçevelik
এখানে, আমরা তাদের নিজ নিজ কলামে সব পরিমাপ আছে, আমাদের বৈশিষ্ট্য, এবং এছাড়াও শ্রেণী কলাম, আমাদের লক্ষ্য, যা ডেটাফ্রেমের শেষটি। আমরা কত পরিমাপ আমরা ব্যবহার করে দেখতে পারেন shape
অ্যাট্রিবিউট:
df.shape
আউটপুট হয়:
(2500, 13)
আকৃতির ফলাফল আমাদের বলে যে ডেটাসেটে 2500টি এন্ট্রি (বা সারি) এবং 13টি কলাম রয়েছে। যেহেতু আমরা জানি একটি টার্গেট কলাম আছে - এর মানে আমাদের 12টি ফিচার কলাম আছে।
আমরা এখন লক্ষ্য পরিবর্তনশীল, কুমড়া বীজ অন্বেষণ করতে পারেন Class
. যেহেতু আমরা সেই পরিবর্তনশীলের ভবিষ্যদ্বাণী করব, তাই আমাদের কাছে প্রতিটি কুমড়োর বীজের কতগুলি নমুনা রয়েছে তা দেখতে আকর্ষণীয়। সাধারণত, আমাদের ক্লাসে দৃষ্টান্তের সংখ্যার মধ্যে পার্থক্য যত কম হবে, আমাদের নমুনা তত বেশি ভারসাম্যপূর্ণ হবে এবং আমাদের ভবিষ্যদ্বাণী তত ভাল হবে।
এই পরিদর্শন প্রতিটি বীজ নমুনা সঙ্গে গণনা দ্বারা করা যেতে পারে value_counts()
পদ্ধতি:
df['Class'].value_counts()
উপরের কোড প্রদর্শন করে:
Çerçevelik 1300
Ürgüp Sivrisi 1200
Name: Class, dtype: int64
আমরা দেখতে পাচ্ছি যে 1300 টি নমুনা রয়েছে সার্সেভেলিক বীজ এবং 1200 নমুনা উরগুপ সিভরিসি বীজ. লক্ষ্য করুন যে তাদের মধ্যে পার্থক্য হল 100টি নমুনা, একটি খুব ছোট পার্থক্য, যা আমাদের জন্য ভাল এবং নির্দেশ করে যে নমুনার সংখ্যা পুনরায় ভারসাম্য করার প্রয়োজন নেই।
এর সাথে আমাদের বৈশিষ্ট্যগুলির বর্ণনামূলক পরিসংখ্যানও দেখুন describe()
ডেটা কতটা ভালোভাবে বিতরণ করা হয়েছে তা দেখার পদ্ধতি। আমরা এর সাথে ফলস্বরূপ টেবিলটিও স্থানান্তর করব T
পরিসংখ্যান জুড়ে তুলনা করা সহজ করতে:
df.describe().T
ফলাফল টেবিল হল:
count mean std min 25% 50% 75% max
Area 2500.0 80658.220800 13664.510228 47939.0000 70765.000000 79076.00000 89757.500000 136574.0000
Perimeter 2500.0 1130.279015 109.256418 868.4850 1048.829750 1123.67200 1203.340500 1559.4500
Major_Axis_Length 2500.0 456.601840 56.235704 320.8446 414.957850 449.49660 492.737650 661.9113
Minor_Axis_Length 2500.0 225.794921 23.297245 152.1718 211.245925 224.70310 240.672875 305.8180
Convex_Area 2500.0 81508.084400 13764.092788 48366.0000 71512.000000 79872.00000 90797.750000 138384.0000
Equiv_Diameter 2500.0 319.334230 26.891920 247.0584 300.167975 317.30535 338.057375 417.0029
Eccentricity 2500.0 0.860879 0.045167 0.4921 0.831700 0.86370 0.897025 0.9481
Solidity 2500.0 0.989492 0.003494 0.9186 0.988300 0.99030 0.991500 0.9944
Extent 2500.0 0.693205 0.060914 0.4680 0.658900 0.71305 0.740225 0.8296
Roundness 2500.0 0.791533 0.055924 0.5546 0.751900 0.79775 0.834325 0.9396
Aspect_Ration 2500.0 2.041702 0.315997 1.1487 1.801050 1.98420 2.262075 3.1444
Compactness 2500.0 0.704121 0.053067 0.5608 0.663475 0.70770 0.743500 0.9049
টেবিলের দিকে তাকিয়ে, তুলনা করার সময় গড় এবং আদর্শ চ্যুতি (std
) কলাম, এটি দেখা যায় যে বেশিরভাগ বৈশিষ্ট্যের একটি গড় রয়েছে যা আদর্শ বিচ্যুতি থেকে অনেক দূরে। এটি নির্দেশ করে যে ডেটা মানগুলি গড় মানের চারপাশে কেন্দ্রীভূত নয়, তবে এটির চারপাশে আরও ছড়িয়ে ছিটিয়ে রয়েছে - অন্য কথায়, তাদের রয়েছে উচ্চ পরিবর্তনশীলতা.
এছাড়াও, যখন তাকান সর্বনিম্ন (min
) এবং সর্বাধিক (max
) কলাম, কিছু বৈশিষ্ট্য, যেমন Area
, এবং Convex_Area
, ন্যূনতম এবং সর্বোচ্চ মানের মধ্যে বড় পার্থক্য আছে। এর মানে হল যে সেই কলামগুলিতে খুব ছোট ডেটা এবং খুব বড় ডেটা মান রয়েছে, বা উচ্চতর প্রশস্ততা ডেটা মানগুলির মধ্যে।
উচ্চ পরিবর্তনশীলতা, উচ্চ প্রশস্ততা, এবং বিভিন্ন পরিমাপ ইউনিট সহ বৈশিষ্ট্য সহ, আমাদের বেশিরভাগ ডেটা সমস্ত বৈশিষ্ট্য বা সত্তার জন্য একই স্কেল থাকলে উপকৃত হবে আঁশযুক্ত. ডেটা স্কেলিং ডেটাকে গড়ের চারপাশে কেন্দ্রীভূত করবে এবং এর বৈচিত্র কমিয়ে দেবে।
এই দৃশ্যটি সম্ভবত ইঙ্গিত করে যে ডেটাতে বহিরাগত এবং চরম মান রয়েছে। সুতরাং, কিছু থাকা ভাল বাইরের চিকিত্সা ডাটা স্কেল করার পাশাপাশি।
কিছু মেশিন লার্নিং অ্যালগরিদম আছে, উদাহরণস্বরূপ, গাছ-ভিত্তিক অ্যালগরিদম যেমন এলোমেলো বন শ্রেণীবিভাগ, যা উচ্চ ডেটা বৈচিত্র্য, আউটলায়ার এবং চরম মান দ্বারা প্রভাবিত হয় না। পণ্য সরবরাহ সংশ্লেষণ ভিন্ন, এটি একটি ফাংশনের উপর ভিত্তি করে যা আমাদের মানগুলিকে শ্রেণীবদ্ধ করে এবং সেই ফাংশনের প্যারামিটারগুলি সেই মানগুলির দ্বারা প্রভাবিত হতে পারে যা সাধারণ ডেটা প্রবণতার বাইরে এবং উচ্চ বৈচিত্র্য রয়েছে৷
আমরা লজিস্টিক রিগ্রেশন সম্পর্কে আরও কিছু বুঝতে পারব যখন আমরা এটি বাস্তবায়ন করতে পারব। আপাতত, আমরা আমাদের ডেটা অন্বেষণ চালিয়ে যেতে পারি।
বিঃদ্রঃ: কম্পিউটার সায়েন্সে একটি জনপ্রিয় কথা আছে: "আবর্জনা ভিতরে, আবর্জনা আউট" (GIGO), যা মেশিন লার্নিংয়ের জন্য উপযুক্ত। এর মানে হল যে যখন আমাদের কাছে আবর্জনা ডেটা থাকে - পরিমাপ যা নিজেদের মধ্যে ঘটনা বর্ণনা করে না, যে ডেটা বোঝা যায় নি এবং অ্যালগরিদম বা মডেলের ধরন অনুযায়ী ভালভাবে প্রস্তুত করা হয়নি, সম্ভবত একটি ভুল আউটপুট তৈরি করবে যা কাজ করবে না প্রতিদিনের ভিত্তিতে।
অন্বেষণ করা, ডেটা বোঝা এবং নির্বাচিত মডেল কীভাবে কাজ করে তা এত গুরুত্বপূর্ণ কেন এটি একটি কারণ। এটি করার মাধ্যমে, আমরা আমাদের মডেলে আবর্জনা ফেলা এড়াতে পারি - পরিবর্তে এটিতে মূল্য দেওয়া এবং মূল্য আউট করা।
ডেটা ভিজ্যুয়ালাইজ করা
এখন পর্যন্ত, বর্ণনামূলক পরিসংখ্যান সহ, আমাদের কাছে ডেটার কিছু গুণাবলীর কিছুটা বিমূর্ত স্ন্যাপশট রয়েছে। আরেকটি গুরুত্বপূর্ণ পদক্ষেপ হল এটিকে কল্পনা করা এবং উচ্চ বৈচিত্র্য, প্রশস্ততা এবং বহিঃপ্রকাশের আমাদের অনুমান নিশ্চিত করা। আমরা এখন পর্যন্ত যা পর্যবেক্ষণ করেছি তা ডেটাতে দেখায় কিনা তা দেখতে, আমরা কিছু গ্রাফ প্লট করতে পারি।
ভবিষ্যদ্বাণী করা হবে এমন দুটি শ্রেণীর সাথে বৈশিষ্ট্যগুলি কীভাবে সম্পর্কিত তা দেখতেও আকর্ষণীয়। এটা করতে, এর আমদানি করা যাক seaborn
প্যাকেজ এবং ব্যবহার করুন pairplot
প্রতিটি বৈশিষ্ট্য বন্টন, এবং বৈশিষ্ট্য প্রতি প্রতিটি শ্রেণীর পৃথকীকরণ দেখতে গ্রাফ:
import seaborn as sns
sns.pairplot(data=df, hue='Class')
বিঃদ্রঃ: উপরের কোডটি চালানোর জন্য কিছুটা সময় লাগতে পারে, যেহেতু পেয়ারপ্লট সমস্ত বৈশিষ্ট্যের স্ক্যাটারপ্লটগুলিকে একত্রিত করে (এটি করতে পারে), এবং বৈশিষ্ট্য বিতরণগুলিও প্রদর্শন করে৷
pairplot এ খুঁজছেন, আমরা দেখতে পারি যে অধিকাংশ ক্ষেত্রে পয়েন্ট Çerçevelik
ক্লাস পরিষ্কারভাবে বিন্দু থেকে পৃথক করা হয় Ürgüp Sivrisi
ক্লাস হয় এক শ্রেণীর পয়েন্ট ডানে থাকে যখন অন্যরা বাম দিকে থাকে, অথবা কিছু উপরে থাকে যখন অন্যরা নিচে থাকে। যদি আমরা ক্লাসগুলিকে আলাদা করার জন্য কোনও ধরণের বক্ররেখা বা রেখা ব্যবহার করি, তাহলে এটি দেখায় যে তাদের আলাদা করা সহজ, যদি সেগুলি মিশ্রিত হয় তবে শ্রেণিবিন্যাস একটি কঠিন কাজ হবে।
মধ্যে Eccentricity
, Compactness
এবং Aspect_Ration
কলাম, কিছু পয়েন্ট যা "বিচ্ছিন্ন" বা সাধারণ ডেটা প্রবণতা থেকে বিচ্যুত - আউটলায়ারগুলি - সহজে দেখা যায়।
চার্টের উপরের বাম থেকে নীচের ডানদিকে তির্যকটি দেখার সময়, লক্ষ্য করুন আমাদের ক্লাস অনুসারে ডেটা বিতরণগুলিও রঙ-কোডেড। বণ্টনের আকার এবং উভয় বক্ররেখার মধ্যে দূরত্ব এগুলি কতটা পৃথকীকরণযোগ্য তার অন্যান্য সূচক – একে অপরের থেকে যত এগিয়ে, তত ভাল। বেশিরভাগ ক্ষেত্রে, এগুলিকে সুপারইম্পোজ করা হয় না, যা বোঝায় যে সেগুলি আলাদা করা সহজ, এছাড়াও আমাদের কাজে অবদান রাখে।
ক্রমানুসারে, আমরা এর সাথে সমস্ত ভেরিয়েবলের বক্সপ্লটও প্লট করতে পারি sns.boxplot()
পদ্ধতি বেশিরভাগ সময়, বক্সপ্লটগুলিকে অনুভূমিকভাবে অভিমুখ করা সহায়ক, তাই বক্সপ্লটগুলির আকারগুলি বিতরণের আকারগুলির মতোই হয়, আমরা এটি দিয়ে এটি করতে পারি orient
যুক্তি:
sns.boxplot(data=df, orient='h')
উপরের প্লটে, লক্ষ্য করুন যে Area
এবং Convex_Area
অন্যান্য স্তম্ভের মাত্রার সাথে তুলনা করার সময় তাদের এত উচ্চ মাত্রা থাকে যে তারা অন্যান্য বক্সপ্লটগুলিকে স্কুইশ করে। সমস্ত বক্সপ্লট দেখতে সক্ষম হওয়ার জন্য, আমরা বৈশিষ্ট্যগুলি স্কেল করতে পারি এবং সেগুলি আবার প্লট করতে পারি।
এটি করার আগে, আসুন কেবল বুঝতে পারি যে যদি এমন বৈশিষ্ট্যগুলির মান থাকে যা অন্যান্য মানগুলির সাথে ঘনিষ্ঠভাবে সম্পর্কিত, উদাহরণস্বরূপ - যদি এমন কিছু মান থাকে যা অন্যান্য বৈশিষ্ট্যের মানগুলি বড় হওয়ার সাথে সাথে আরও বড় হয়, ইতিবাচক সম্পর্ক; অথবা যদি এমন মান থাকে যা বিপরীত করে, ছোট হয়ে যায় যখন অন্যান্য মানগুলি ছোট হয়ে যায়, একটি থাকা নেতিবাচক সম্পর্ক.
এটি দেখা গুরুত্বপূর্ণ কারণ ডেটাতে শক্তিশালী সম্পর্ক থাকার অর্থ হতে পারে যে কিছু কলাম অন্য কলাম থেকে উদ্ভূত হয়েছে বা আমাদের মডেলের সাথে একই অর্থ রয়েছে। যখন এটি ঘটে, মডেলের ফলাফলগুলি অত্যধিক মূল্যায়ন করা হতে পারে এবং আমরা বাস্তবের কাছাকাছি ফলাফল চাই৷ যদি দৃঢ় পারস্পরিক সম্পর্ক থাকে, তাহলে এর মানে হল যে আমরা বৈশিষ্ট্যের সংখ্যা কমাতে পারি এবং মডেলটিকে আরও বেশি করে কম কলাম ব্যবহার করতে পারি। parsimonious.
বিঃদ্রঃ: এর সাথে গণনা করা ডিফল্ট পারস্পরিক সম্পর্ক corr()
পদ্ধতিটি হল পিয়ারসন পারস্পরিক সম্পর্ক সহগ. এই সহগ নির্দেশিত হয় যখন ডেটা পরিমাণগত হয়, সাধারণত বিতরণ করা হয়, বহির্মুখী থাকে না এবং একটি রৈখিক সম্পর্ক থাকে।
আরেকটি পছন্দ গণনা করা হবে স্পিয়ারম্যানের পারস্পরিক সম্পর্ক সহগ. স্পিয়ারম্যানের সহগ ব্যবহার করা হয় যখন ডেটা অর্ডিনাল, নন-লিনিয়ার, কোনো ডিস্ট্রিবিউশন থাকে এবং আউটলাইয়ার থাকে। লক্ষ্য করুন যে আমাদের ডেটা সম্পূর্ণরূপে পিয়ারসন বা স্পিয়ারম্যানের অনুমানের সাথে খাপ খায় না (এছাড়াও আরও পারস্পরিক সম্পর্ক পদ্ধতি রয়েছে, যেমন কেন্ডালের)। যেহেতু আমাদের ডেটা পরিমাণগত এবং এটির রৈখিক সম্পর্ক পরিমাপ করা আমাদের জন্য গুরুত্বপূর্ণ, আমরা পিয়ারসনের সহগ ব্যবহার করব।
চলুন চলকগুলির মধ্যে পারস্পরিক সম্পর্কের দিকে নজর দেওয়া যাক এবং তারপরে আমরা ডেটা প্রাক-প্রক্রিয়া করতে যেতে পারি। আমরা এর সাথে পারস্পরিক সম্পর্ক গণনা করব corr()
পদ্ধতি এবং Seaborn এর সঙ্গে তাদের কল্পনা heatmap()
. হিটম্যাপ স্ট্যান্ডার্ড আকার ছোট হতে থাকে, তাই আমরা আমদানি করব matplotlib
(সাধারণ ভিজ্যুয়ালাইজেশন ইঞ্জিন/লাইব্রেরি যা সিবোর্নের উপরে তৈরি করা হয়েছে) এবং এর সাথে আকার পরিবর্তন করুন figsize
:
import matplotlib.pyplot as plt
plt.figure(figsize=(15, 10))
correlations = df.corr()
sns.heatmap(correlations, annot=True)
এই হিটম্যাপে, 1 বা -1 এর কাছাকাছি মানগুলি হল সেই মানগুলির প্রতি আমাদের মনোযোগ দিতে হবে৷ প্রথম ক্ষেত্রে, একটি উচ্চ ইতিবাচক সম্পর্ক এবং দ্বিতীয়টি, একটি উচ্চ নেতিবাচক সম্পর্ককে নির্দেশ করে। উভয় মান, যদি 0.8 বা -0.8 এর উপরে না হয় তবে আমাদের লজিস্টিক রিগ্রেশন মডেলের জন্য উপকারী হবে।
যখন উচ্চ পারস্পরিক সম্পর্ক যেমন এক 0.99
মধ্যে Aspec_Ration
এবং Compactness
, এর মানে হল যে আমরা শুধুমাত্র ব্যবহার করতে পারি Aspec_Ration
বা কেবল Compactness
, তাদের উভয়ের পরিবর্তে (যেহেতু তারা প্রায় সমান হবে ভবিষ্যতবক্তা একে অপরের)। জন্য একই ঝুলিতে Eccentricity
এবং Compactness
সঙ্গে একটি -0.98
পারস্পরিক সম্পর্ক, জন্য Area
এবং Perimeter
সঙ্গে একটি 0.94
পারস্পরিক সম্পর্ক, এবং কিছু অন্যান্য কলাম।
ডেটা প্রাক-প্রক্রিয়াকরণ
যেহেতু আমরা ইতিমধ্যেই কিছু সময়ের জন্য ডেটা অন্বেষণ করেছি, আমরা এটিকে প্রাক-প্রক্রিয়া শুরু করতে পারি। আপাতত, ক্লাসের পূর্বাভাসের জন্য সমস্ত বৈশিষ্ট্য ব্যবহার করা যাক। একটি প্রথম মডেল, একটি বেসলাইন পাওয়ার পরে, আমরা তারপরে কিছু উচ্চ সম্পর্কযুক্ত কলামগুলি সরিয়ে ফেলতে পারি এবং এটিকে বেসলাইনের সাথে তুলনা করতে পারি।
বৈশিষ্ট্য কলাম আমাদের হবে X
ডেটা এবং ক্লাস কলাম, আমাদের y
লক্ষ্য তথ্য:
y = df['Class']
X = df.drop(columns=['Class'], axis=1)
শ্রেণীগত বৈশিষ্ট্যগুলিকে সংখ্যাসূচক বৈশিষ্ট্যগুলিতে পরিণত করা৷
আমাদের সম্পর্কে Class
কলাম - এর মানগুলি সংখ্যা নয়, এর মানে আমাদেরও তাদের রূপান্তর করতে হবে। এই রূপান্তর করার অনেক উপায় আছে; এখানে, আমরা ব্যবহার করব replace()
পদ্ধতি এবং প্রতিস্থাপন Çerçevelik
থেকে 0
এবং Ürgüp Sivrisi
থেকে 1
.
y = y.replace('Çerçevelik', 0).replace('Ürgüp Sivrisi', 1)
ম্যাপিং মনে রাখবেন! আপনার মডেল থেকে ফলাফল পড়ার সময়, আপনি অন্তত আপনার মনে এইগুলিকে আবার রূপান্তর করতে চাইবেন, অথবা অন্য ব্যবহারকারীদের জন্য ক্লাসনামে ফিরে আসতে চাইবেন৷
ট্রেন এবং টেস্ট সেটে ডেটা ভাগ করা
আমাদের অন্বেষণে, আমরা লক্ষ্য করেছি যে বৈশিষ্ট্যগুলির স্কেলিং প্রয়োজন৷ যদি আমরা এখন স্কেলিং করি, বা একটি স্বয়ংক্রিয় পদ্ধতিতে, আমরা সমগ্রের সাথে মানগুলি স্কেল করব X
এবং y
. যে ক্ষেত্রে, আমরা পরিচয় করিয়ে দিতে চাই তথ্য ফাঁস, যেহেতু শীঘ্রই হতে যাওয়া পরীক্ষার সেটের মানগুলি স্কেলিংকে প্রভাবিত করবে৷ ডেটা ফাঁস হল অপূরণীয় ফলাফল এবং এমএল মডেলের অলীক উচ্চ কর্মক্ষমতার একটি সাধারণ কারণ।
স্কেলিং সম্পর্কে চিন্তা করা দেখায় যে আমাদের প্রথমে বিভক্ত করতে হবে X
এবং y
ডেটা আরও ট্রেন এবং পরীক্ষা সেটে এবং তারপরে ফিট প্রশিক্ষণ সেটে একটি স্কেলার, এবং রুপান্তর ট্রেন এবং টেস্ট সেট উভয়ই (পরীক্ষা সেট না করেই এটি করে এমন স্কলারকে প্রভাবিত করে)। এর জন্য, আমরা Scikit-Learns ব্যবহার করব train_test_split()
পদ্ধতি:
from sklearn.model_selection import train_test_split
SEED = 42
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=.25,
random_state=SEED)
বিন্যাস test_size=.25
আমরা নিশ্চিত করছি যে আমরা 25% ডেটা পরীক্ষার জন্য এবং 75% প্রশিক্ষণের জন্য ব্যবহার করছি। এটি বাদ দেওয়া যেতে পারে, একবার এটি ডিফল্ট বিভক্ত, কিন্তু পাইথনিক কোড লেখার উপায় পরামর্শ দেয় যে "অন্তর্ভুক্ত থেকে স্পষ্ট হওয়া ভাল"।
বিঃদ্রঃ: বাক্যটি "অন্তর্ভুক্তের চেয়ে সুস্পষ্ট ভাল" একটি রেফারেন্স পাইথনের জেন, বা PEP20। এটি পাইথন কোড লেখার জন্য কিছু পরামর্শ দেয়। যদি সেই পরামর্শগুলি অনুসরণ করা হয়, কোডটি বিবেচনা করা হয় পাইথনিক. আপনি এটি সম্পর্কে আরও জানতে পারেন এখানে.
ট্রেন এবং পরীক্ষার সেটে ডেটা বিভক্ত করার পরে, প্রতিটি সেটে কতগুলি রেকর্ড রয়েছে তা দেখা একটি ভাল অনুশীলন। যে দিয়ে করা যেতে পারে shape
অ্যাট্রিবিউট:
X_train.shape, X_test.shape, y_train.shape, y_test.shape
এটি প্রদর্শন করে:
((1875, 12), (625, 12), (1875,), (625,))
আমরা দেখতে পাচ্ছি যে বিভক্ত হওয়ার পরে, আমাদের কাছে প্রশিক্ষণের জন্য 1875টি এবং পরীক্ষার জন্য 625টি রেকর্ড রয়েছে।
স্কেলিং ডেটা
আমাদের ট্রেন এবং পরীক্ষার সেট প্রস্তুত হয়ে গেলে, আমরা Scikit-Learn-এর মাধ্যমে ডেটা স্কেল করতে এগিয়ে যেতে পারি StandardScaler
বস্তু (বা লাইব্রেরি দ্বারা প্রদত্ত অন্যান্য স্কেলার)। ফুটো এড়াতে, স্ক্যালার লাগানো হয় X_train
ডেটা এবং ট্রেনের মানগুলি তারপর ট্রেন এবং পরীক্ষা ডেটা উভয় স্কেল - বা রূপান্তর করতে ব্যবহৃত হয়:
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
যেহেতু আপনি সাধারণত কল করবেন:
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)
প্রথম দুটি লাইন একটি একবচন দিয়ে ভেঙে ফেলা যেতে পারে fit_transform()
কল, যা সেটের স্কেলারের সাথে ফিট করে এবং একে একে রূপান্তরিত করে। ডেটা স্কেলিং করার পরে পার্থক্য দেখতে আমরা এখন বক্সপ্লট গ্রাফগুলি পুনরুত্পাদন করতে পারি।
বিবেচনা করে স্কেলিং কলামের নামগুলি সরিয়ে দেয়, প্লট করার আগে, আমরা ভিজ্যুয়ালাইজেশনের সুবিধার্থে আবার কলামের নাম সহ একটি ডেটাফ্রেমে ট্রেনের ডেটা সংগঠিত করতে পারি:
column_names = df.columns[:12]
X_train = pd.DataFrame(X_train, columns=column_names)
sns.boxplot(data=X_train, orient='h')
আমরা অবশেষে আমাদের বক্সপ্লট সব দেখতে পারি! লক্ষ্য করুন যে তাদের সকলেরই বহির্মুখী, এবং বৈশিষ্ট্যগুলি যা স্বাভাবিক থেকে আরও একটি বিতরণ উপস্থাপন করে (যার বক্ররেখা হয় বাম বা ডান দিকে তির্যক), যেমন Solidity
, Extent
, Aspect_Ration
, এবং Compactedness
, একই যে উচ্চতর পারস্পরিক সম্পর্ক ছিল.
IQR পদ্ধতির মাধ্যমে বহিরাগতদের অপসারণ করা
আমরা ইতিমধ্যে জানি যে লজিস্টিক রিগ্রেশন বহিরাগতদের দ্বারা প্রভাবিত হতে পারে। তাদের চিকিৎসার অন্যতম উপায় হল একটি পদ্ধতি যা বলা হয় ইন্টারকোয়ার্টাইল রেঞ্জ or আইকিউআর. IQR পদ্ধতির প্রাথমিক ধাপ হল আমাদের ট্রেনের ডেটাকে চার ভাগে ভাগ করা, যাকে বলা হয় কোয়ার্টাইল। প্রথম চতুর্থাংশ, Q1, ডেটার 25% পরিমাণ, দ্বিতীয়টি, Q2, 50% থেকে, তৃতীয়, Q3, 75% থেকে, এবং শেষটি, Q4, 100% পর্যন্ত। বক্সপ্লটের বাক্সগুলিকে IQR পদ্ধতি দ্বারা সংজ্ঞায়িত করা হয় এবং এটি এর একটি ভিজ্যুয়াল উপস্থাপনা।
একটি অনুভূমিক বক্সপ্লট বিবেচনা করলে, বাম দিকের উল্লম্ব রেখাটি ডেটার 25%, মাঝখানে উল্লম্ব রেখা, 50% ডেটা (বা মধ্যমা) এবং ডানদিকে শেষ উল্লম্ব রেখা, 75% ডেটা চিহ্নিত করে . উল্লম্ব রেখা দ্বারা সংজ্ঞায়িত উভয় বর্গক্ষেত্র যত বেশি আকারে - বা মধ্যবর্তী উল্লম্ব রেখাটি মাঝখানে তত বেশি - মানে আমাদের ডেটা স্বাভাবিক বিতরণের কাছাকাছি বা কম তির্যক, যা আমাদের বিশ্লেষণের জন্য সহায়ক।
IQR বক্স ছাড়াও এর উভয় পাশে অনুভূমিক রেখা রয়েছে। এই লাইনগুলি দ্বারা সংজ্ঞায়িত সর্বনিম্ন এবং সর্বাধিক বন্টন মান চিহ্নিত করে৷
$$
ন্যূনতম = Q1 – 1.5*IQR
$$
এবং
$$
সর্বোচ্চ = Q3 + 1.5*IQR
$$
IQR হল ঠিক Q3 এবং Q1 (বা Q3 - Q1) এর মধ্যে পার্থক্য এবং এটি ডেটার সবচেয়ে কেন্দ্রীয় বিন্দু। এই কারণেই IQR খোঁজার সময়, আমরা ডেটার প্রান্তে বা সর্বনিম্ন এবং সর্বাধিক পয়েন্টগুলিতে আউটলায়ারগুলিকে ফিল্টার করি। আইকিউআর পদ্ধতির ফলাফল কী হবে তা বক্স প্লট আমাদের এক ঝলক দেয়।
আমরা পান্ডা ব্যবহার করতে পারি quantile()
আমাদের কোয়ান্টাইল খুঁজে বের করার পদ্ধতি, এবং iqr
থেকে scipy.stats
প্রতিটি কলামের জন্য ইন্টারকোয়ার্টাইল ডেটা পরিসীমা পেতে প্যাকেজ:
from scipy.stats import iqr
Q1 = X_train.quantile(q=.25)
Q3 = X_train.quantile(q=.75)
IQR = X_train.apply(iqr)
এখন আমাদের কাছে Q1, Q3, এবং IQR আছে, আমরা মধ্যকের কাছাকাছি মানগুলি ফিল্টার করতে পারি:
minimum = X_train < (Q1-1.5*IQR)
maximum = X_train > (Q3+1.5*IQR)
filter = ~(minimum | maximum).any(axis=1)
X_train = X_train[filter]
আমাদের প্রশিক্ষণের সারিগুলি ফিল্টার করার পরে, আমরা দেখতে পারি তাদের মধ্যে কতগুলি এখনও ডেটাতে রয়েছে৷ shape
:
X_train.shape
এর ফলে:
(1714, 12)
আমরা দেখতে পাচ্ছি যে ফিল্টার করার পরে সারির সংখ্যা 1875 থেকে 1714 এ চলে গেছে। এর মানে হল যে 161 সারিতে আউটলিয়ার বা 8.5% ডেটা রয়েছে।
বিঃদ্রঃ: এটি পরামর্শ দেওয়া হয় যে বহিরাগতদের ফিল্টারিং, NaN মান অপসারণ এবং অন্যান্য ক্রিয়া যা ফিল্টারিং এবং ক্লিনজিং ডেটার নিচে বা 10% পর্যন্ত থাকে। আপনার ফিল্টারিং বা অপসারণ আপনার ডেটার 10% এর বেশি হলে অন্যান্য সমাধানের কথা ভাবার চেষ্টা করুন।
Outliers অপসারণ করার পরে, আমরা মডেলে ডেটা অন্তর্ভুক্ত করার জন্য প্রায় প্রস্তুত। মডেল ফিটিংয়ের জন্য, আমরা ট্রেন ডেটা ব্যবহার করব। X_train
ফিল্টার করা হয়, কিন্তু কি সম্পর্কে y_train
?
y_train.shape
এই আউটপুট:
(1875,)
লক্ষ্য করুন y_train
এখনও 1875 সারি আছে. আমাদের সংখ্যার সাথে মেলাতে হবে y_train
এর সংখ্যার সারি X_train
সারি এবং শুধু নির্বিচারে নয়। আমাদের অপসারণ করা কুমড়োর বীজের উদাহরণগুলির y-মানগুলি অপসারণ করতে হবে, যা সম্ভবত ছড়িয়ে ছিটিয়ে রয়েছে y_train
সেট ফিল্টার করা হয়েছে X_train
stil এর মূল সূচক রয়েছে এবং সূচকের ফাঁক রয়েছে যেখানে আমরা আউটলিয়ারগুলিকে সরিয়ে দিয়েছি! আমরা তারপর সূচক ব্যবহার করতে পারেন X_train
ডেটাফ্রেমে সংশ্লিষ্ট মান অনুসন্ধান করতে y_train
:
y_train = y_train.iloc[X_train.index]
যে করার পরে, আমরা দেখতে পারেন y_train
আবার আকার:
y_train.shape
কোন আউটপুট:
(1714,)
সেরা-অভ্যাস, শিল্প-স্বীকৃত মান এবং অন্তর্ভুক্ত চিট শীট সহ গিট শেখার জন্য আমাদের হ্যান্ডস-অন, ব্যবহারিক গাইড দেখুন। গুগলিং গিট কমান্ড এবং আসলে বন্ধ করুন শেখা এটা!
এখন, y_train
এছাড়াও 1714 সারি আছে এবং তারা একই X_train
সারি আমরা অবশেষে আমাদের লজিস্টিক রিগ্রেশন মডেল তৈরি করতে প্রস্তুত!
লজিস্টিক রিগ্রেশন মডেল বাস্তবায়ন
কঠিন অংশ সম্পন্ন হয়! প্রিপ্রসেসিং সাধারণত মডেল ডেভেলপমেন্টের চেয়ে বেশি কঠিন, যখন এটি Scikit-Learn-এর মতো লাইব্রেরি ব্যবহার করার ক্ষেত্রে আসে, যা ML মডেলের প্রয়োগকে মাত্র কয়েকটি লাইনে স্ট্রিমলাইন করেছে।
প্রথমত, আমরা আমদানি করি LogisticRegression
ক্লাস এবং এটিকে ইনস্ট্যান্টিয়েট করুন, একটি তৈরি করুন LogisticRegression
বস্তু:
from sklearn.linear_model import LogisticRegression
logreg = LogisticRegression(random_state=SEED)
দ্বিতীয়ত, আমরা আমাদের ট্রেনের ডেটা ফিট করি logreg
সঙ্গে মডেল fit()
পদ্ধতি, এবং এর সাথে আমাদের পরীক্ষার ডেটা ভবিষ্যদ্বাণী করুন predict()
পদ্ধতি, হিসাবে ফলাফল সংরক্ষণ y_pred
:
logreg.fit(X_train.values, y_train)
y_pred = logreg.predict(X_test)
আমরা ইতিমধ্যে আমাদের মডেলের সাথে ভবিষ্যদ্বাণী করেছি! এর মধ্যে প্রথম 3টি সারি দেখি X_train
আমরা কোন ডেটা ব্যবহার করেছি তা দেখতে:
X_train[:3]
উপরের কোড আউটপুট:
Area Perimeter Major_Axis_Length Minor_Axis_Length Convex_Area Equiv_Diameter Eccentricity Solidity Extent Roundness Aspect_Ration Compactness
0 -1.098308 -0.936518 -0.607941 -1.132551 -1.082768 -1.122359 0.458911 -1.078259 0.562847 -0.176041 0.236617 -0.360134
1 -0.501526 -0.468936 -0.387303 -0.376176 -0.507652 -0.475015 0.125764 0.258195 0.211703 0.094213 -0.122270 0.019480
2 0.012372 -0.209168 -0.354107 0.465095 0.003871 0.054384 -0.453911 0.432515 0.794735 0.647084 -0.617427 0.571137
এবং প্রথম 3 টি ভবিষ্যদ্বাণীতে y_pred
ফলাফল দেখতে:
y_pred[:3]
এর ফলে:
array([0, 0, 0])
এই তিনটি সারির জন্য, আমাদের ভবিষ্যদ্বাণী ছিল যে তারা প্রথম শ্রেণীর বীজ ছিল, Çerçevelik
.
সঙ্গে পণ্য সরবরাহ সংশ্লেষণ, পরিবর্তে চূড়ান্ত ক্লাস ভবিষ্যদ্বাণী, যেমন 0
, আমরা সারির সাথে সম্পর্কিত হওয়ার সম্ভাবনাও অনুমান করতে পারি 0
ক্লাস যখন লজিস্টিক রিগ্রেশন ডেটাকে শ্রেণীবদ্ধ করে তখন এটিই ঘটে এবং predict()
পদ্ধতি তারপর একটি "হার্ড" ক্লাস ফিরে একটি প্রান্তিক মাধ্যমে এই ভবিষ্যদ্বাণী পাস. একটি শ্রেণীর সাথে সম্পর্কিত হওয়ার সম্ভাবনার পূর্বাভাস দিতে, predict_proba()
ব্যবহৃত হয়:
y_pred_proba = logreg.predict_proba(X_test)
আসুন y সম্ভাব্যতার পূর্বাভাসের প্রথম 3টি মানও দেখে নেওয়া যাক:
y_pred_proba[:3]
কোন আউটপুট:
# class 0 class 1
array([[0.54726628, 0.45273372],
[0.56324527, 0.43675473],
[0.86233349, 0.13766651]])
এখন, তিনটি শূন্যের পরিবর্তে, আমাদের প্রতিটি ক্লাসের জন্য একটি কলাম আছে। বাম দিকের কলামে, দিয়ে শুরু 0.54726628
, হল ক্লাস সম্পর্কিত ডেটার সম্ভাব্যতা 0
; এবং ডান কলামে, দিয়ে শুরু 0.45273372
, ক্লাস সম্পর্কিত এর সম্ভাব্যতা 1
.
বিঃদ্রঃ: শ্রেণীবিভাগের এই পার্থক্য হিসাবেও পরিচিত কঠিন এবং নরম ভবিষ্যদ্বাণী হার্ড ভবিষ্যদ্বাণী বাক্সে ভবিষ্যদ্বাণীকে একটি শ্রেণিতে পরিণত করে, যখন নরম ভবিষ্যদ্বাণীগুলি আউটপুট দেয়৷ সম্ভাবনা একটি শ্রেণীর অন্তর্গত উদাহরণ.
ভবিষ্যদ্বাণীকৃত আউটপুট কীভাবে তৈরি হয়েছিল সে সম্পর্কে আরও তথ্য রয়েছে। এটা আসলে ছিল না 0
, কিন্তু ক্লাসের সুযোগ 55% 0
, এবং 45% ক্লাসের সুযোগ 1
. এই প্রথম তিনটি কিভাবে পৃষ্ঠ X_test
ডেটা পয়েন্ট, ক্লাস সম্পর্কিত 0
, 86% সম্ভাবনা সহ শুধুমাত্র তৃতীয় ডেটা পয়েন্ট সম্পর্কে সত্যিই পরিষ্কার - এবং প্রথম দুটি ডেটা পয়েন্টের জন্য এত বেশি নয়।
যখন ML পদ্ধতি ব্যবহার করে ফলাফলের সাথে যোগাযোগ করা হয় - সাধারণত একটি নরম শ্রেণী এবং সংশ্লিষ্ট সম্ভাব্যতা হিসাবে ফেরত দেওয়া ভাল "আত্মবিশ্বাস" যে শ্রেণীবিভাগের.
আমরা মডেলের গভীরে গেলে কীভাবে এটি গণনা করা হয় সে সম্পর্কে আমরা আরও কথা বলব। এই সময়ে, আমরা পরবর্তী ধাপে যেতে পারি।
ক্লাসিফিকেশন রিপোর্ট সহ মডেল মূল্যায়ন
তৃতীয় ধাপ হল পরীক্ষার ডেটাতে মডেলটি কীভাবে পারফর্ম করে তা দেখা। আমরা স্কিট-লার্ন আমদানি করতে পারি classification_report()
এবং আমাদের পাস y_test
এবং y_pred
যুক্তি হিসাবে। এর পরে, আমরা এর প্রতিক্রিয়া প্রিন্ট করতে পারি।
শ্রেণিবিন্যাস প্রতিবেদনে সর্বাধিক ব্যবহৃত শ্রেণিবিন্যাস মেট্রিক্স রয়েছে, যেমন স্পষ্টতা, প্রত্যাহার, f1-স্কোর, এবং সঠিকতা.
- স্পষ্টতা: আমাদের ক্লাসিফায়ার দ্বারা সঠিক ভবিষ্যদ্বাণীর মানগুলিকে সঠিক বলে বিবেচনা করা হয়েছে তা বোঝার জন্য। নির্ভুলতা সেই সত্যিকারের ইতিবাচক মানগুলিকে ইতিবাচক হিসাবে ভবিষ্যদ্বাণী করা যে কোনও কিছু দ্বারা ভাগ করবে:
$$
নির্ভুলতা = ফ্র্যাক{টেক্সট{ট্রু ইতিবাচক}}{টেক্সট{ট্রু ইতিবাচক} + টেক্সট{ফলস ইতিবাচক}}
$$
- প্রত্যাহার: আমাদের শ্রেণীবিভাগকারী দ্বারা কতগুলি সত্য ইতিবাচক চিহ্নিত করা হয়েছে তা বোঝার জন্য। প্রত্যাহার গণনা করা হয় সত্যিকারের ইতিবাচককে এমন কিছু দিয়ে ভাগ করে যা ইতিবাচক হিসাবে ভবিষ্যদ্বাণী করা উচিত ছিল:
$$
recall = frac{text{true positive}}{text{true positive} + text{false negative}}
$$
- F1 স্কোর: সুষম বা সুরেলা গড় নির্ভুলতা এবং প্রত্যাহার. সর্বনিম্ন মান 0 এবং সর্বোচ্চ 1। কখন
f1-score
1 এর সমান, এর অর্থ হল সমস্ত ক্লাস সঠিকভাবে ভবিষ্যদ্বাণী করা হয়েছিল - এটি বাস্তব ডেটা সহ প্রাপ্ত করা একটি খুব কঠিন স্কোর:
$$
text{f1-score} = 2* frac{text{precision} * text{recall}}{text{precision} + text{recall}}
$$
- সঠিকতা: আমাদের শ্রেণিবিন্যাসকারী কতটি ভবিষ্যদ্বাণী সঠিক হয়েছে তা বর্ণনা করে। সর্বনিম্ন নির্ভুলতার মান হল 0 এবং সর্বোচ্চ হল 1৷ এই মানটি সাধারণত 100 দ্বারা গুণ করা হয় একটি শতাংশ পেতে:
$$
নির্ভুলতা = ফ্র্যাক{টেক্সট{সঠিক ভবিষ্যদ্বাণীর সংখ্যা}}পাঠ্য{মোট ভবিষ্যদ্বাণীর সংখ্যা}}
$$
বিঃদ্রঃ: কোনো বাস্তব তথ্যের উপর 100% নির্ভুলতা পাওয়া অত্যন্ত কঠিন, যদি এটি ঘটে থাকে, তাহলে সচেতন থাকুন যে কিছু ফাঁস বা কিছু ভুল ঘটতে পারে - একটি আদর্শ নির্ভুলতার মান নিয়ে কোনো ঐক্যমত নেই এবং এটি প্রসঙ্গ-নির্ভরও। 70% এর মান, যার অর্থ হল শ্রেণীবিভাগকারী 30% ডেটাতে ভুল করবে, বা 70% এর উপরে বেশিরভাগ মডেলের জন্য যথেষ্ট হতে থাকে।
from sklearn.metrics import classification_report
cr = classification_report(y_test, y_pred)
print(cr)
তারপরে আমরা শ্রেণীবিভাগ রিপোর্ট আউটপুট দেখতে পারি:
precision recall f1-score support
0 0.83 0.91 0.87 316
1 0.90 0.81 0.85 309
accuracy 0.86 625
macro avg 0.86 0.86 0.86 625
weighted avg 0.86 0.86 0.86 625
এই আমাদের ফলাফল. লক্ষ্য করুন precision
, recall
, f1-score
, এবং accuracy
মেট্রিক্স সবই খুব বেশি, 80% এর উপরে, যা আদর্শ – কিন্তু সেই ফলাফলগুলি সম্ভবত উচ্চ পারস্পরিক সম্পর্ক দ্বারা প্রভাবিত হয়েছিল এবং দীর্ঘমেয়াদে টিকবে না।
মডেলটির নির্ভুলতা 86%, যার মানে এটি 14% সময় শ্রেণীবিভাগ ভুল করে। আমাদের কাছে সেই সামগ্রিক তথ্য রয়েছে, তবে শ্রেণির শ্রেণিবিন্যাসের ক্ষেত্রে 14% ভুল হয়েছে কিনা তা জানা আকর্ষণীয় হবে 0
বা ক্লাস 1
. কোন শ্রেণীগুলিকে কোনটি হিসাবে ভুল শনাক্ত করা হয়েছে এবং কোন ফ্রিকোয়েন্সিতে - আমরা গণনা করতে পারি এবং একটি প্লট করতে পারি বিভ্রান্তি ম্যাট্রিক্স আমাদের মডেলের ভবিষ্যদ্বাণী।
একটি বিভ্রান্তি ম্যাট্রিক্স দিয়ে মডেল মূল্যায়ন
আসুন গণনা করি এবং তারপর বিভ্রান্তি ম্যাট্রিক্স প্লট করি। এটি করার পরে, আমরা এটির প্রতিটি অংশ বুঝতে পারি। বিভ্রান্তি ম্যাট্রিক্স প্লট করতে, আমরা Scikit-Learn ব্যবহার করব confusion_matrix()
, যা আমরা থেকে আমদানি করব metrics
মডিউল।
বিভ্রান্তি ম্যাট্রিক্স একটি Seaborn ব্যবহার করে কল্পনা করা সহজ heatmap()
. সুতরাং, এটি তৈরি করার পরে, আমরা হিটম্যাপের জন্য একটি যুক্তি হিসাবে আমাদের বিভ্রান্তি ম্যাট্রিক্স পাস করব:
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot=True, fmt='d')
- বিভ্রান্তি ম্যাট্রিক্স: ম্যাট্রিক্স দেখায় প্রতিটি শ্রেণীর জন্য মডেলটি সঠিক বা ভুল কতটি নমুনা পেয়েছে। যে মানগুলি সঠিক এবং সঠিকভাবে ভবিষ্যদ্বাণী করা হয়েছিল তাকে বলা হয় সত্য ইতিবাচক, এবং যেগুলিকে ইতিবাচক হিসাবে ভবিষ্যদ্বাণী করা হয়েছিল কিন্তু ইতিবাচক ছিল না তাদের বলা হয়৷ মিথ্যা ইতিবাচক. এর একই নামকরণ সত্য নেতিবাচক এবং মিথ্যা নেতিবাচক নেতিবাচক মানগুলির জন্য ব্যবহৃত হয়;
বিভ্রান্তি ম্যাট্রিক্স প্লট দেখে, আমরা দেখতে পারি যে আমাদের আছে 287
যে মান ছিল 0
এবং হিসাবে ভবিষ্যদ্বাণী 0
- অথবা সত্য ইতিবাচক শ্রেনীর জন্য 0
(কেরসেভেলিক বীজ)। আমাদের আরো আছে 250
ক্লাসের জন্য সত্য ইতিবাচক 1
(Ürgüp Sivrisi বীজ)। প্রকৃত ধনাত্মকগুলি সর্বদা ম্যাট্রিক্স তির্যকটিতে অবস্থিত যা উপরের বাম থেকে নীচের ডানদিকে যায়।
আমরা আছে 29
মান যে অনুমিত ছিল 0
, কিন্তু হিসাবে ভবিষ্যদ্বাণী 1
(মিথ্যা ইতিবাচক) এবং 59
যে মান ছিল 1
এবং হিসাবে ভবিষ্যদ্বাণী 0
(মিথ্যা নেতিবাচক) এই সংখ্যাগুলির সাহায্যে, আমরা বুঝতে পারি যে মডেলটি যে ত্রুটিটি সবচেয়ে বেশি করে তা হল এটি মিথ্যা নেতিবাচক ভবিষ্যদ্বাণী করে। সুতরাং, এটি বেশিরভাগই একটি Ürgüp Sivrisi বীজকে Çerçevelik বীজ হিসাবে শ্রেণীবদ্ধ করতে পারে।
এই ধরনের ত্রুটি ক্লাসের 81% প্রত্যাহার দ্বারাও ব্যাখ্যা করা হয় 1
. লক্ষ্য করুন যে মেট্রিক্স সংযুক্ত আছে। এবং প্রত্যাহারে পার্থক্যটি Ürgüp Sivrisi ক্লাসের 100 কম নমুনা থাকার কারণে আসছে। এটি অন্য শ্রেণীর তুলনায় মাত্র কয়েকটি নমুনা কম থাকার একটি প্রভাব। প্রত্যাহার আরও উন্নত করতে, আপনি হয় ক্লাস ওজন নিয়ে পরীক্ষা করতে পারেন বা আরও Ürgüp Sivrisi নমুনা ব্যবহার করতে পারেন।
এখনও অবধি, আমরা বেশিরভাগ ডেটা বিজ্ঞানের ঐতিহ্যগত পদক্ষেপগুলি সম্পাদন করেছি এবং লজিস্টিক রিগ্রেশন মডেলটিকে একটি ব্ল্যাক বক্স হিসাবে ব্যবহার করেছি।
বিঃদ্রঃ: আপনি আরও যেতে চান, ব্যবহার করুন ক্রস ভ্যালিডেশন (সিভি) এবং গ্রিড অনুসন্ধান যথাক্রমে, যে মডেলটি ডেটা সম্পর্কিত সর্বাধিক সাধারণীকরণ করে এবং প্রশিক্ষণের আগে বেছে নেওয়া সেরা মডেল প্যারামিটারগুলি সন্ধান করতে, বা হাইপারপ্যারামিটার.
আদর্শভাবে, সিভি এবং গ্রিড অনুসন্ধানের সাথে, আপনি ডেটা প্রাক-প্রসেসিং পদক্ষেপ, ডেটা বিভাজন, মডেলিং এবং মূল্যায়ন করার জন্য একটি সংযুক্ত উপায়ও প্রয়োগ করতে পারেন - যা Scikit-Learn-এর মাধ্যমে সহজ করা হয়েছে। পাইপলাইনগুলি.
এখন সময় এসেছে ব্ল্যাক বক্সটি খোলার এবং এর ভিতরে দেখার, লজিস্টিক রিগ্রেশন কীভাবে কাজ করে তা বোঝার আরও গভীরে যাওয়ার।
লজিস্টিক রিগ্রেশন কিভাবে কাজ করে তার গভীরে যাওয়া
সার্জারির প্রত্যাগতি শব্দটি দুর্ঘটনাক্রমে নেই, লজিস্টিক রিগ্রেশন কী করে তা বোঝার জন্য, আমরা মনে রাখতে পারি এর ভাইবোন, লিনিয়ার রিগ্রেশন ডেটাতে কী করে। রৈখিক রিগ্রেশন সূত্র নিম্নলিখিত ছিল:
$$
y = b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n
$$
যার মধ্যে খ0 রিগ্রেশন ইন্টারসেপ্ট ছিল, খ1 সহগ এবং x1 তথ্যটি.
এই সমীকরণটি একটি সরল রেখায় পরিণত হয়েছিল যা নতুন মানগুলির পূর্বাভাস দিতে ব্যবহৃত হয়েছিল। ভূমিকা স্মরণ করে, পার্থক্য এখন আমরা নতুন মান ভবিষ্যদ্বাণী করা হবে না, কিন্তু একটি শ্রেণী. তাই যে সরলরেখা পরিবর্তন করা প্রয়োজন. লজিস্টিক রিগ্রেশনের সাথে, আমরা একটি অ-রৈখিকতা প্রবর্তন করি এবং ভবিষ্যদ্বাণীটি এখন একটি রেখার পরিবর্তে একটি বক্ররেখা ব্যবহার করে করা হয়েছে:
লক্ষ্য করুন যে যখন রৈখিক রিগ্রেশন লাইন চলতে থাকে এবং ক্রমাগত অসীম মান দিয়ে তৈরি হয়, লজিস্টিক রিগ্রেশন বক্ররেখাটি মাঝখানে ভাগ করা যেতে পারে এবং 0 এবং 1 মানের মধ্যে চরম রয়েছে। এই “S” আকৃতির কারণেই এটি ডেটাকে শ্রেণীবদ্ধ করে – যে বিন্দুগুলি সবচেয়ে কাছাকাছি বা সর্বোচ্চ প্রান্তে পড়ে সেগুলি ক্লাস 1 এর অন্তর্গত, যখন যে বিন্দুগুলি নিম্ন চতুর্ভুজ বা 0 এর কাছাকাছি, সেগুলি ক্লাস 0 এর অন্তর্গত। "S" হল 0 এবং 1, 0.5-এর মাঝামাঝি - এটি লজিস্টিক রিগ্রেশন পয়েন্টের থ্রেশহোল্ড।
আমরা ইতিমধ্যে লজিস্টিক এবং রৈখিক রিগ্রেশন মধ্যে চাক্ষুষ পার্থক্য বুঝতে, কিন্তু সূত্র সম্পর্কে কি? লজিস্টিক রিগ্রেশনের সূত্রটি নিম্নরূপ:
$$
y = b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n
$$
এটি এভাবেও লেখা যেতে পারে:
$$
y_{prob} = frac{1}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}
$$
অথবা এমনও লিখতে হবে:
$$
y_{prob} = frac{e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}
$$
উপরের সমীকরণে, আমাদের কাছে এর মানের পরিবর্তে ইনপুটের সম্ভাবনা রয়েছে। এটির লব হিসাবে 1 আছে তাই এটি 0 এবং 1 এর মধ্যে একটি মান এবং 1 প্লাস এর হর এর মধ্যে একটি মান হতে পারে, যাতে এর মান 1 এবং কিছু - এর মানে হল পুরো ভগ্নাংশের ফলাফল 1 এর চেয়ে বড় হতে পারে না .
এবং হর এর মান কি? এটাই e, প্রাকৃতিক লগারিদমের ভিত্তি (প্রায় 2.718282), লিনিয়ার রিগ্রেশনের শক্তিতে উত্থাপিত:
$$
e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
এটি লেখার আরেকটি উপায় হবে:
$$
ln বাম( frac{p}{1-p} ডানে) = {(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
সেই শেষ সমীকরণে, ln প্রাকৃতিক লগারিদম (বেস e) এবং p সম্ভাব্যতা, তাই ফলাফলের সম্ভাব্যতার লগারিদম রৈখিক রিগ্রেশন ফলাফলের মতোই।
অন্য কথায়, রৈখিক রিগ্রেশন ফলাফল এবং প্রাকৃতিক লগারিদমের সাহায্যে, আমরা একটি পরিকল্পিত শ্রেণির সাথে সম্পর্কিত একটি ইনপুট বা না হওয়ার সম্ভাবনায় পৌঁছাতে পারি।
সম্পূর্ণ লজিস্টিক রিগ্রেশন ডেরিভেশন প্রক্রিয়াটি নিম্নরূপ:
$$
p{X} = frac{e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}
$$
$$
p(1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}) = e^{(b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
$$
p + p*e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)} = e^{(b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
p
=
e
(
b
0
+
b
1
*
x
1
+
b
2
*
x
2
+
b
3
*
x
3
+
...
+
b
n
*
x
n
)
-
p
*
e
(
b
0
+
b
1
*
x
1
+
b
2
*
x
2
+
b
3
*
x
3
+
...
+
b
n
*
x
n
)
$$
frac{p}{1-p} = e^{(b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
$$
ln বাম( frac{p}{1-p} ডানে) = (b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldots + b_n * x_n)
$$
এর মানে হল যে লজিস্টিক রিগ্রেশন মডেলেরও সহগ এবং একটি ইন্টারসেপ্ট মান রয়েছে। কারণ এটি একটি লিনিয়ার রিগ্রেশন ব্যবহার করে এবং প্রাকৃতিক লগারিদমের সাথে এটিতে একটি নন-লিনিয়ার উপাদান যোগ করে (e
).
আমরা আমাদের মডেলের সহগ এবং ইন্টারসেপ্টের মান দেখতে পারি, যেভাবে আমরা লিনিয়ার রিগ্রেশনের জন্য করেছি, ব্যবহার করে coef_
এবং intercept_
বৈশিষ্ট্য:
logreg.coef_
যা 12টি বৈশিষ্ট্যের প্রতিটির সহগ প্রদর্শন করে:
array([[ 1.43726172, -1.03136968, 0.24099522, -0.61180768, 1.36538261,
-1.45321951, -1.22826034, 0.98766966, 0.0438686 , -0.78687889,
1.9601197 , -1.77226097]])
logreg.intercept_
এর ফলে:
array([0.08735782])
সহগ এবং ইন্টারসেপ্ট মান দিয়ে, আমরা আমাদের ডেটার পূর্বাভাসিত সম্ভাব্যতা গণনা করতে পারি। চলুন প্রথম পেতে X_test
মান আবার, একটি উদাহরণ হিসাবে:
X_test[:1]
এটি প্রথম সারি প্রদান করে X_test
একটি NumPy অ্যারে হিসাবে:
array([[-1.09830823, -0.93651823, -0.60794138, -1.13255059, -1.0827684 ,
-1.12235877, 0.45891056, -1.07825898, 0.56284738, -0.17604099,
0.23661678, -0.36013424]])
প্রাথমিক সমীকরণ অনুসরণ করুন:
$$
p{X} = frac{e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}
$$
পাইথনে, আমাদের আছে:
import math
lin_reg = logreg.intercept_[0] +
((logreg.coef_[0][0]* X_test[:1][0][0])+
(logreg.coef_[0][1]* X_test[:1][0][1])+
(logreg.coef_[0][2]* X_test[:1][0][2])+
(logreg.coef_[0][3]* X_test[:1][0][3])+
(logreg.coef_[0][4]* X_test[:1][0][4])+
(logreg.coef_[0][5]* X_test[:1][0][5])+
(logreg.coef_[0][6]* X_test[:1][0][6])+
(logreg.coef_[0][7]* X_test[:1][0][7])+
(logreg.coef_[0][8]* X_test[:1][0][8])+
(logreg.coef_[0][9]* X_test[:1][0][9])+
(logreg.coef_[0][10]* X_test[:1][0][10])+
(logreg.coef_[0][11]* X_test[:1][0][11]))
px = math.exp(lin_reg)/(1 +(math.exp(lin_reg)))
px
এর ফলে:
0.45273372469369133
আমরা আবার তাকান যদি predict_proba
প্রথম এর ফলাফল X_test
লাইন, আমাদের আছে:
logreg.predict_proba(X_test[:1])
এর মানে হল যে মূল লজিস্টিক রিগ্রেশন সমীকরণ আমাদের ক্লাস সম্পর্কিত ইনপুটের সম্ভাব্যতা দেয় 1
, ক্লাসের জন্য কোন সম্ভাব্যতা খুঁজে বের করতে 0
, আমরা সহজভাবে করতে পারি:
1 - px
লক্ষ্য করুন যে উভয় px
এবং 1-px
অনুরূপ predict_proba
ফলাফল এইভাবে লজিস্টিক রিগ্রেশন গণনা করা হয় এবং কেন প্রত্যাগতি এর নামের অংশ। কিন্তু পদ সম্পর্কে কি লজিস্টিক?
মেয়াদ লজিস্টিক থেকে আসে লগিট, যা আমরা ইতিমধ্যে দেখেছি একটি ফাংশন:
$$
ln বাম ( frac{p}{1-p} ডানে)
$$
আমরা শুধু এটা দিয়ে হিসাব করেছি px
এবং 1-px
. এই লগিট, এছাড়াও বলা হয় log-odds যেহেতু এটি বিজোড়ের লগারিদমের সমান যেখানে p
একটি সম্ভাবনা।
উপসংহার
এই গাইডে, আমরা সবচেয়ে মৌলিক মেশিন লার্নিং ক্লাসিফিকেশন অ্যালগরিদমগুলির মধ্যে একটি অধ্যয়ন করেছি, যেমন পণ্য সরবরাহ সংশ্লেষণ.
প্রাথমিকভাবে, আমরা Scikit-Learn-এর মেশিন লার্নিং লাইব্রেরির সাথে একটি ব্ল্যাক বক্স হিসাবে লজিস্টিক রিগ্রেশন প্রয়োগ করেছি, এবং পরে আমরা ধাপে ধাপে বুঝতে পেরেছি যে কেন এবং কোথা থেকে রিগ্রেশন এবং লজিস্টিক শব্দগুলি এসেছে তা পরিষ্কার করার জন্য।
আমরা ডেটা অন্বেষণ এবং অধ্যয়ন করেছি, বুঝতে পারি যে এটি একটি ডেটা বিজ্ঞান বিশ্লেষণের অন্যতম গুরুত্বপূর্ণ অংশ।
এখান থেকে, আমি আপনাকে সাথে খেলার পরামর্শ দেব মাল্টিক্লাস লজিস্টিক রিগ্রেশন, দুইটিরও বেশি ক্লাসের জন্য লজিস্টিক রিগ্রেশন - আপনি একই লজিস্টিক রিগ্রেশন অ্যালগরিদম প্রয়োগ করতে পারেন অন্যান্য ডেটাসেটের জন্য যেগুলির একাধিক ক্লাস রয়েছে এবং ফলাফলগুলি ব্যাখ্যা করতে পারেন৷
বিঃদ্রঃ: ডেটাসেটের একটি ভাল সংগ্রহ পাওয়া যায় এখানে তোমার সাথে খেলার জন্য।
আমি আপনাকে L1 এবং L2 অধ্যয়ন করার পরামর্শ দেব নিয়মিতকরণ, তারা মডেলের জটিলতা ধরে রাখার জন্য উচ্চতর ডেটাকে "দণ্ডিত" করার একটি উপায় যাতে এটি স্বাভাবিকের কাছাকাছি হতে পারে, যাতে অ্যালগরিদম আরও ভাল ফলাফল পেতে পারে। আমরা যে Scikit-Learn ইমপ্লিমেন্টেশন ব্যবহার করেছি, তাতে ইতিমধ্যেই ডিফল্টরূপে L2 নিয়মিতকরণ রয়েছে। আরেকটা জিনিস দেখতে হবে ভিন্ন সমাধানকারী, যেমন lbgs
, যা লজিস্টিক রিগ্রেশন অ্যালগরিদম কর্মক্ষমতা অপ্টিমাইজ করে।
এটি একটি কটাক্ষপাত করাও গুরুত্বপূর্ণ পরিসংখ্যানসংক্রান্ত লজিস্টিক রিগ্রেশনের পদ্ধতি। ইহা ছিল অনুমানের ডেটার আচরণ সম্পর্কে, এবং অন্যান্য পরিসংখ্যান সম্পর্কে যা সন্তোষজনক ফলাফলের গ্যারান্টি রাখতে হবে, যেমন:
- পর্যবেক্ষণ স্বাধীন;
- ব্যাখ্যামূলক ভেরিয়েবলের মধ্যে কোনো বহুসংখ্যা নেই;
- কোন চরম outliers আছে;
- ব্যাখ্যামূলক ভেরিয়েবল এবং প্রতিক্রিয়া ভেরিয়েবলের লগিটের মধ্যে একটি রৈখিক সম্পর্ক রয়েছে;
- নমুনার আকার যথেষ্ট বড়।
আমাদের বিশ্লেষণ এবং ডেটার চিকিত্সায় এই অনুমানগুলির মধ্যে কতগুলি ইতিমধ্যে কভার করা হয়েছিল তা লক্ষ্য করুন।
আমি আশা করি আপনি লজিস্টিক রিগ্রেশনের সমস্ত ভিন্ন পদ্ধতিতে কী অফার করে তা অন্বেষণ করতে থাকবেন!
- blockchain
- সি ++
- কোড
- coingenius
- তথ্য বিজ্ঞান
- ডেটা ভিজ্যুয়ালাইজেশন
- জাভা
- matplotlib
- অ ছত্রাকযুক্ত টোকেন
- অসাড়
- খোলা সমুদ্র
- পান্ডাস
- পিএইচপি
- Plato
- প্লেটো এআই
- প্লেটো ডেটা ইন্টেলিজেন্স
- প্লেটো গেম
- প্লেটো ব্লকচেইন
- প্লেটোডাটা
- প্লেটোগেমিং
- বহুভুজ
- পাইথন
- প্রতিক্রিয়া
- scikit-শিখতে
- সমুদ্রজাত
- স্মার্ট চুক্তি
- সোলানা
- Stackabuse
- ভাইপার
- Web3
- zephyrnet