ভূমিকা
এই নির্দেশিকাতে, আমরা বাস্তবায়নের উপর ফোকাস করব Scikit-Learn-এর সাথে Hierarchical Clustering Algorithm একটি বিপণন সমস্যা সমাধান করতে।
গাইড পড়ার পরে, আপনি বুঝতে পারবেন:
- হায়ারার্কিক্যাল ক্লাস্টারিং কখন প্রয়োগ করতে হবে
- এটি ক্লাস্টারিংয়ের জন্য উপযুক্ত কিনা তা বোঝার জন্য ডেটাসেটটি কীভাবে কল্পনা করবেন
- ডেটাসেটের উপর ভিত্তি করে কীভাবে বৈশিষ্ট্যগুলিকে প্রাক-প্রক্রিয়া করতে হয় এবং নতুন বৈশিষ্ট্যগুলিকে ইঞ্জিনিয়ার করতে হয়
- কিভাবে PCA ব্যবহার করে ডেটাসেটের মাত্রা কমানো যায়
- কীভাবে একটি ডেনড্রোগ্রাম ব্যবহার করবেন এবং আলাদা গোষ্ঠীতে পড়বেন
- ডেনড্রোগ্রাম এবং ক্লাস্টারিং অ্যালগরিদমে প্রয়োগ করা বিভিন্ন লিঙ্কিং পদ্ধতি এবং দূরত্ব মেট্রিক্স কী কী
- সমষ্টিগত এবং বিভাজনকারী ক্লাস্টারিং কৌশলগুলি কী এবং তারা কীভাবে কাজ করে
- কিভাবে Scikit-Learn-এর সাহায্যে অ্যাগ্লোমারেটিভ হায়ারার্কিক্যাল ক্লাস্টারিং বাস্তবায়ন করা যায়
- ক্লাস্টারিং অ্যালগরিদমগুলির সাথে কাজ করার সময় সবচেয়ে ঘন ঘন সমস্যাগুলি কী এবং কীভাবে সেগুলি সমাধান করা যায়৷
বিঃদ্রঃ: আপনি এই গাইডের সমস্ত কোড ধারণকারী নোটবুক ডাউনলোড করতে পারেন এখানে.
প্রেরণা
এমন একটি দৃশ্যের কল্পনা করুন যেখানে আপনি একটি ডেটা সায়েন্স দলের অংশ যা মার্কেটিং বিভাগের সাথে ইন্টারফেস করে। বিপণন কিছু সময়ের জন্য গ্রাহক কেনাকাটার ডেটা সংগ্রহ করছে, এবং তারা বুঝতে চায়, সংগৃহীত ডেটার উপর ভিত্তি করে, যদি থাকে গ্রাহকদের মধ্যে মিল. এই মিলগুলি গ্রাহকদেরকে গোষ্ঠীতে বিভক্ত করে এবং গ্রাহক গোষ্ঠী থাকা প্রচারাভিযান, প্রচার, রূপান্তর এবং আরও ভাল গ্রাহক সম্পর্ক গড়ে তুলতে সাহায্য করে।
কোন গ্রাহকদের অনুরূপ তা নির্ধারণে আপনি সাহায্য করতে পারেন এমন একটি উপায় আছে কি? তাদের মধ্যে একই দলের কতজন? এবং কতগুলো বিভিন্ন গ্রুপ আছে?
এই প্রশ্নের উত্তর দেওয়ার একটি উপায় হল a ব্যবহার করে থলোথলো অ্যালগরিদম, যেমন K-Means, DBSCAN, Hierarchical Clustering, ইত্যাদি। সাধারণ পরিভাষায়, ক্লাস্টারিং অ্যালগরিদম ডেটা পয়েন্টের মধ্যে মিল খুঁজে পায় এবং তাদের গ্রুপ করে।
এই ক্ষেত্রে, আমাদের মার্কেটিং ডেটা মোটামুটি ছোট। আমাদের কাছে মাত্র 200 জন গ্রাহকের তথ্য আছে। মার্কেটিং টিমের কথা বিবেচনা করে, এটা গুরুত্বপূর্ণ যে আমরা তাদের পরিষ্কারভাবে ব্যাখ্যা করতে পারি যে কীভাবে ক্লাস্টারের সংখ্যার উপর ভিত্তি করে সিদ্ধান্তগুলি নেওয়া হয়েছিল, তাই অ্যালগরিদম আসলে কীভাবে কাজ করে তা তাদের ব্যাখ্যা করা।
যেহেতু আমাদের ডেটা ছোট এবং ব্যাখ্যাযোগ্যতা একটি প্রধান কারণ, আমরা লিভারেজ করতে পারি হায়ারার্কিক্যাল ক্লাস্টারিং সমস্যাটি সমাধান করতে. এই প্রক্রিয়া নামেও পরিচিত হায়ারার্কিক্যাল ক্লাস্টারিং অ্যানালাইসিস (HCA).
HCA এর একটি সুবিধা হল এটি ব্যাখ্যাযোগ্য এবং ছোট ডেটাসেটে ভাল কাজ করে।
এই পরিস্থিতিতে বিবেচনা করা আরেকটি বিষয় হল যে HCA হল একটি তত্ত্বাবধানহীন অ্যালগরিদম ডেটা গোষ্ঠীবদ্ধ করার সময়, আমাদের কাছে যাচাই করার উপায় থাকবে না যে আমরা সঠিকভাবে সনাক্ত করছি যে একজন ব্যবহারকারী একটি নির্দিষ্ট গোষ্ঠীর (আমরা গোষ্ঠীগুলি জানি না)। আমাদের ফলাফলের সাথে তুলনা করার জন্য আমাদের জন্য কোন লেবেল নেই। যদি আমরা সঠিকভাবে গোষ্ঠীগুলিকে শনাক্ত করি, তাহলে এটি পরবর্তীতে বিপণন বিভাগ দ্বারা প্রতিদিনের ভিত্তিতে নিশ্চিত করা হবে (যেমন মেট্রিক্স যেমন ROI, রূপান্তর হার ইত্যাদি দ্বারা পরিমাপ করা হয়)।
এখন আমরা বুঝতে পেরেছি যে আমরা যে সমস্যাটি সমাধান করার চেষ্টা করছি এবং কীভাবে এটি সমাধান করা যায়, আমরা আমাদের ডেটা একবার দেখে নেওয়া শুরু করতে পারি!
সংক্ষিপ্ত অনুসন্ধানমূলক ডেটা বিশ্লেষণ
বিঃদ্রঃ: আপনি এই গাইডে ব্যবহৃত ডেটাসেট ডাউনলোড করতে পারেন এখানে.
ডেটাসেট ডাউনলোড করার পরে, লক্ষ্য করুন যে এটি একটি CSV (কমা দ্বারা পৃথক করা মান) ফাইল বলা হয় shopping-data.csv
. ডেটা অন্বেষণ এবং ম্যানিপুলেট করা সহজ করতে, আমরা এটিকে a এ লোড করব DataFrame
পান্ডা ব্যবহার করে:
import pandas as pd
path_to_file = 'home/projects/datasets/shopping-data.csv'
customer_data = pd.read_csv(path_to_file)
বিপণন বলেছে যে এটি 200 গ্রাহকের রেকর্ড সংগ্রহ করেছে। ডাউনলোড করা ডেটা 200টি সারি দিয়ে সম্পূর্ণ হয়েছে কিনা তা আমরা চেক করতে পারি shape
বৈশিষ্ট্য এটি আমাদের যথাক্রমে কতগুলি সারি এবং কলাম আছে তা আমাদের বলবে:
customer_data.shape
এর ফলে:
(200, 5)
দারুণ! আমাদের ডেটা 200টি সারি দিয়ে সম্পূর্ণ (ক্লায়েন্ট রেকর্ড) এবং আমরা 5 কলাম আছে (বৈশিষ্ট্য). বিপণন বিভাগ গ্রাহকদের কাছ থেকে কী কী বৈশিষ্ট্য সংগ্রহ করেছে তা দেখতে, আমরা এর সাথে কলামের নাম দেখতে পারি columns
বৈশিষ্ট্য এটি করতে, চালান:
customer_data.columns
উপরের স্ক্রিপ্টটি ফেরত দেয়:
Index(['CustomerID', 'Genre', 'Age', 'Annual Income (k$)',
'Spending Score (1-100)'],
dtype='object')
এখানে, আমরা দেখতে পাই যে বিপণন একটি উৎপন্ন করেছে CustomerID
, জড়ো Genre
, Age
, Annual Income
(হাজার হাজার ডলারে), এবং ক Spending Score
1 জন গ্রাহকের জন্য 100 থেকে 200 পর্যন্ত যাচ্ছে। তাদের কাছে ব্যাখ্যা চাওয়া হলে তারা বলেন, মান Spending Score
কলামটি নির্দেশ করে যে একজন ব্যক্তি 1 থেকে 100 স্কেলে কত ঘন ঘন একটি মলে অর্থ ব্যয় করেন। অন্য কথায়, যদি একজন গ্রাহকের স্কোর 0 থাকে, তবে এই ব্যক্তি কখনই অর্থ ব্যয় করেন না, এবং যদি স্কোর 100 হয়, আমরা এইমাত্র দেখেছি সর্বোচ্চ ব্যয়কারী।
আমাদের ডেটাসেটে ব্যবহারকারীদের খরচ করার অভ্যাস পরিদর্শন করার জন্য এই স্কোরের বিতরণের দিকে দ্রুত নজর দেওয়া যাক। সেখানেই পান্ডারা hist()
পদ্ধতি সাহায্য করতে আসে:
customer_data['Spending Score (1-100)'].hist()
হিস্টোগ্রাম দেখে আমরা দেখতে পাই যে 35 টিরও বেশি গ্রাহকের মধ্যে স্কোর রয়েছে 40
এবং 60
, তাহলে 25 এর কম স্কোর আছে 70
এবং 80
. তাই আমাদের গ্রাহকদের অধিকাংশ হয় সুষম ব্যয়কারী, মাঝারি থেকে উচ্চ ব্যয়কারী দ্বারা অনুসরণ করা হয়. আমরা আরও দেখতে পারি যে একটি লাইন পরে আছে 0
, ডিস্ট্রিবিউশনের বামে, এবং 100 এর আগে আরেকটি লাইন, ডিস্ট্রিবিউশনের ডানদিকে। এই ফাঁকা স্থানগুলি সম্ভবত বোঝায় যে বিতরণে অ-ব্যয়কারী নেই, যার একটি স্কোর থাকবে 0
, এবং একটি স্কোর সঙ্গে কোন উচ্চ ব্যয়কারী আছে যে 100
.
এটি সত্য কিনা তা যাচাই করতে, আমরা বিতরণের সর্বনিম্ন এবং সর্বাধিক মানগুলি দেখতে পারি। এই মানগুলি বর্ণনামূলক পরিসংখ্যানের অংশ হিসাবে সহজেই পাওয়া যেতে পারে, তাই আমরা ব্যবহার করতে পারি describe()
অন্যান্য সাংখ্যিক মান বন্টন বোঝার জন্য পদ্ধতি:
customer_data.describe().transpose()
এটি আমাদের একটি টেবিল দেবে যেখান থেকে আমরা আমাদের ডেটাসেটের অন্যান্য মানগুলির বিতরণ পড়তে পারি:
count mean std min 25% 50% 75% max
CustomerID 200.0 100.50 57.879185 1.0 50.75 100.5 150.25 200.0
Age 200.0 38.85 13.969007 18.0 28.75 36.0 49.00 70.0
Annual Income (k$) 200.0 60.56 26.264721 15.0 41.50 61.5 78.00 137.0
Spending Score (1-100) 200.0 50.20 25.823522 1.0 34.75 50.0 73.00 99.0
আমাদের অনুমান নিশ্চিত করা হয়. দ্য min
মান Spending Score
is 1
এবং সর্বোচ্চ হল 99
. তাই আমরা নেই 0
or 100
স্কোর ব্যয়কারীদের এর পরে ট্রান্সপোজডের অন্যান্য কলামগুলি দেখে নেওয়া যাক describe
টেবিল যখন তাকান mean
এবং std
কলাম, আমরা যে জন্য দেখতে পারেন Age
দ্য mean
is 38.85
এবং std
আনুমানিক হয় 13.97
. জন্য একই ঘটবে Annual Income
, সঙ্গে একটি mean
of 60.56
এবং std
26.26
, এবং জন্য Spending Score
সঙ্গে একটি mean
of 50
এবং std
of 25.82
. সমস্ত বৈশিষ্ট্যের জন্য, mean
আদর্শ বিচ্যুতি থেকে অনেক দূরে, যা নির্দেশ করে আমাদের তথ্য উচ্চ পরিবর্তনশীলতা আছে.
আমাদের ডেটা কীভাবে পরিবর্তিত হয় তা আরও ভালভাবে বুঝতে, আসুন প্লট করি Annual Income
বিতরণ:
customer_data['Annual Income (k$)'].hist()
যা আমাদের দেবে:
হিস্টোগ্রামে লক্ষ্য করুন যে আমাদের বেশিরভাগ ডেটা, 35 জনের বেশি গ্রাহক, সংখ্যার কাছাকাছি কেন্দ্রীভূত 60
, আমাদের উপর mean
, অনুভূমিক অক্ষে। কিন্তু আমরা যখন বিতরণের শেষের দিকে এগিয়ে যাই তখন কী ঘটে? বাম দিকে যাওয়ার সময়, $60.560 গড় থেকে, পরবর্তী মানটি হল $34.300 – গড় ($60.560) বিয়োগ আদর্শ পরিবর্তন ($26.260)৷ যদি আমরা আমাদের ডাটা ডিস্ট্রিবিউশনের বাম দিকে আরও দূরে যাই তাহলে একই নিয়ম প্রযোজ্য হয়, আমরা বর্তমান মান ($26.260) থেকে স্ট্যান্ডার্ড ভ্যারিয়েশন ($34.300) বিয়োগ করি। অতএব, আমরা $8.040 মূল্যের সম্মুখীন হব। লক্ষ্য করুন কিভাবে আমাদের ডেটা দ্রুত $60k থেকে $8k এ চলে গেছে। প্রতিবার এটি "জাম্পিং" $26.260 - অনেক পরিবর্তিত, এবং সেই কারণেই আমাদের এত উচ্চ পরিবর্তনশীলতা রয়েছে।
ক্লাস্টারিং বিশ্লেষণে ডেটার পরিবর্তনশীলতা এবং আকার গুরুত্বপূর্ণ কারণ বেশিরভাগ ক্লাস্টারিং অ্যালগরিদমের দূরত্ব পরিমাপ ডেটা মাত্রার প্রতি সংবেদনশীল। আকারের পার্থক্য একটি বিন্দুকে বাস্তবের চেয়ে কাছে বা আরও দূরের বলে মনে করে, ডেটার প্রকৃত গ্রুপিংকে বিকৃত করে ক্লাস্টারিং ফলাফল পরিবর্তন করতে পারে।
এখন পর্যন্ত, আমরা আমাদের ডেটার আকার, এর কিছু বিতরণ এবং বর্ণনামূলক পরিসংখ্যান দেখেছি। পান্ডাসের সাহায্যে, আমরা আমাদের ডেটার প্রকারগুলিও তালিকাভুক্ত করতে পারি এবং দেখতে পারি যে আমাদের 200টি সারি পূর্ণ হয়েছে বা কিছু আছে কিনা null
মান:
customer_data.info()
এর ফলে:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 200 entries, 0 to 199
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 CustomerID 200 non-null int64
1 Genre 200 non-null object
2 Age 200 non-null int64
3 Annual Income (k$) 200 non-null int64
4 Spending Score (1-100) 200 non-null int64
dtypes: int64(4), object(1)
memory usage: 7.9+ KB
এখানে, আমরা কোন আছে দেখতে পারেন null
ডেটাতে মান এবং আমাদের শুধুমাত্র একটি শ্রেণীবদ্ধ কলাম আছে - Genre
. এই পর্যায়ে, ক্লাস্টারিং মডেলে যোগ করার জন্য কোন বৈশিষ্ট্যগুলি আকর্ষণীয় বলে মনে হচ্ছে তা আমাদের মনে রাখা গুরুত্বপূর্ণ। আমরা যদি আমাদের মডেলে জেনার কলাম যোগ করতে চাই, তাহলে আমাদের এর মানগুলি থেকে রূপান্তর করতে হবে শ্রেণিবদ্ধ থেকে সংখ্যাসূচক.
দেখা যাক কিভাবে Genre
আমাদের ডেটার প্রথম 5টি মান দ্রুত উঁকি দিয়ে পূরণ করা হয়:
customer_data.head()
এর ফলে:
CustomerID Genre Age Annual Income (k$) Spending Score (1-100)
0 1 Male 19 15 39
1 2 Male 21 15 81
2 3 Female 20 16 6
3 4 Female 23 16 77
4 5 Female 31 17 40
এটা শুধু আছে বলে মনে হচ্ছে Female
এবং Male
বিভাগ এর সাথে এর অনন্য মানগুলি দেখে আমরা নিশ্চিত হতে পারি unique
:
customer_data['Genre'].unique()
এটি আমাদের অনুমান নিশ্চিত করে:
array(['Male', 'Female'], dtype=object)
এখন পর্যন্ত, আমরা জানি যে আমাদের শুধুমাত্র দুটি জেনার আছে, যদি আমরা আমাদের মডেলে এই বৈশিষ্ট্যটি ব্যবহার করার পরিকল্পনা করি, Male
রূপান্তরিত হতে পারে 0
এবং Female
থেকে 1
. জেনারগুলির মধ্যে অনুপাত পরীক্ষা করাও গুরুত্বপূর্ণ, তারা ভারসাম্যপূর্ণ কিনা তা দেখতে। আমরা সঙ্গে যে করতে পারেন value_counts()
পদ্ধতি এবং তার যুক্তি normalize=True
মধ্যে শতাংশ দেখানোর জন্য Male
এবং Female
:
customer_data['Genre'].value_counts(normalize=True)
এই আউটপুট:
Female 0.56
Male 0.44
Name: Genre, dtype: float64
আমাদের ডেটাসেটে 56% মহিলা এবং 44% পুরুষ রয়েছে৷ তাদের মধ্যে পার্থক্য শুধুমাত্র 16%, এবং আমাদের ডেটা 50/50 নয় কিন্তু যথেষ্ট ভারসাম্যপূর্ণ কোনো ঝামেলা না করার জন্য। যদি ফলাফলগুলি 70/30, 60/40 হয়, তাহলে হয়ত আরও ডেটা সংগ্রহ করতে বা সেই অনুপাতকে আরও ভারসাম্যপূর্ণ করার জন্য কোনও ধরণের ডেটা বৃদ্ধির কৌশল ব্যবহার করার প্রয়োজন হতে পারে।
এখন পর্যন্ত, সব বৈশিষ্ট্য কিন্তু Age
, সংক্ষিপ্তভাবে অন্বেষণ করা হয়েছে. কি উদ্বেগ মধ্যে Age
, সাধারণত গ্রাহকদের তাদের বয়সের উপর ভিত্তি করে ভাগ করতে সক্ষম হওয়ার জন্য এটিকে বিনে ভাগ করা আকর্ষণীয়। যদি আমরা তা করি, আমাদের মডেলে যোগ করার আগে আমাদের বয়স বিভাগগুলিকে একটি সংখ্যায় রূপান্তর করতে হবে। এইভাবে, 15-20 বছর ক্যাটাগরি ব্যবহার করার পরিবর্তে, আমরা গণনা করব যে কতজন গ্রাহক আছে৷ 15-20
বিভাগ, এবং যে একটি নতুন কলাম নামক একটি সংখ্যা হবে 15-20
.
উপদেশ: এই গাইডে, আমরা শুধুমাত্র সংক্ষিপ্ত অনুসন্ধানমূলক তথ্য বিশ্লেষণ উপস্থাপন করি। তবে আপনি আরও যেতে পারেন এবং আপনার আরও এগিয়ে যাওয়া উচিত। জেনার এবং বয়সের উপর ভিত্তি করে আয়ের পার্থক্য এবং স্কোরিং পার্থক্য আছে কিনা তা আপনি দেখতে পারেন। এটি শুধুমাত্র বিশ্লেষণকে সমৃদ্ধ করে না বরং আরও ভালো মডেল ফলাফলের দিকে নিয়ে যায়। অনুসন্ধানমূলক ডেটা বিশ্লেষণে আরও গভীরে যেতে, দেখুন ইডিএ অধ্যায়ে “হ্যান্ডস-অন হাউস প্রাইস প্রেডিকশন – পাইথনে মেশিন লার্নিং" নির্দেশিত প্রকল্প।
শ্রেণীবদ্ধ – বা শ্রেণীবদ্ধ – উভয়ের সাথে কি করা যেতে পারে তা অনুমান করার পরে Genre
এবং Age
কলাম, আলোচনা করা হয়েছে কি প্রয়োগ করা যাক.
এনকোডিং ভেরিয়েবল এবং ফিচার ইঞ্জিনিয়ারিং
এর বিভাজন দ্বারা শুরু করা যাক Age
10-এর মধ্যে পরিবর্তিত হয় এমন গোষ্ঠীগুলিতে, যাতে আমাদের 20-30, 30-40, 40-50 এবং আরও অনেক কিছু থাকে। যেহেতু আমাদের সর্বকনিষ্ঠ গ্রাহক 15, আমরা 15-এ শুরু করতে পারি এবং 70-এ শেষ করতে পারি, যা ডেটাতে সবচেয়ে বয়স্ক গ্রাহকের বয়স। 15 থেকে শুরু করে এবং 70-এ শেষ, আমাদের 15-20, 20-30, 30-40, 40-50, 50-60 এবং 60-70 ব্যবধান থাকবে।
গ্রুপ বা am Age
এই ব্যবধানে মান, আমরা পান্ডা ব্যবহার করতে পারি cut()
বিনের মধ্যে কাটা এবং তারপর একটি নতুন করার জন্য বিন্যাস বরাদ্দ করার পদ্ধতি Age Groups
কলাম:
intervals = [15, 20, 30, 40, 50, 60, 70]
col = customer_data['Age']
customer_data['Age Groups'] = pd.cut(x=col, bins=intervals)
customer_data['Age Groups']
এর ফলে:
0 (15, 20]
1 (20, 30]
2 (15, 20]
3 (20, 30]
4 (30, 40]
...
195 (30, 40]
196 (40, 50]
197 (30, 40]
198 (30, 40]
199 (20, 30]
Name: Age Groups, Length: 200, dtype: category
Categories (6, interval[int64, right]): [(15, 20] < (20, 30] < (30, 40] < (40, 50] < (50, 60] < (60, 70]]
লক্ষ্য করুন যে কলামের মানগুলি দেখার সময়, একটি লাইনও রয়েছে যা নির্দিষ্ট করে যে আমাদের 6 টি বিভাগ রয়েছে এবং সমস্ত বিন করা ডেটা ব্যবধানগুলি প্রদর্শন করে। এইভাবে, আমরা আমাদের পূর্বের সংখ্যাসূচক ডেটা শ্রেণীবদ্ধ করেছি এবং একটি নতুন তৈরি করেছি Age Groups
বৈশিষ্ট্য।
এবং প্রতিটি বিভাগে আমাদের কতজন গ্রাহক আছে? আমরা কলাম গ্রুপ করে এবং এর সাথে মান গণনা করে দ্রুত জানতে পারি groupby()
এবং count()
:
customer_data.groupby('Age Groups')['Age Groups'].count()
এর ফলে:
Age Groups
(15, 20] 17
(20, 30] 45
(30, 40] 60
(40, 50] 38
(50, 60] 23
(60, 70] 17
Name: Age Groups, dtype: int64
এটা বোঝা সহজ যে বেশিরভাগ গ্রাহকের বয়স 30 থেকে 40 বছরের মধ্যে, তারপরে গ্রাহকরা 20 থেকে 30 এবং তারপরে 40 থেকে 50 বছরের মধ্যে গ্রাহকরা। এটি মার্কেটিং বিভাগের জন্যও ভাল তথ্য।
এই মুহুর্তে, আমাদের দুটি শ্রেণীগত ভেরিয়েবল আছে, Age
এবং Genre
, যা আমাদের মডেলে ব্যবহার করতে সক্ষম হওয়ার জন্য আমাদের সংখ্যায় রূপান্তর করতে হবে। সেই রূপান্তর করার বিভিন্ন উপায় আছে – আমরা পান্ডা ব্যবহার করব get_dummies()
পদ্ধতি যা প্রতিটি ব্যবধান এবং জেনারের জন্য একটি নতুন কলাম তৈরি করে এবং তারপর 0s এবং 1s দিয়ে এর মান পূরণ করে- এই ধরনের অপারেশনকে বলা হয় এক-গরম এনকোডিং. দেখা যাক কেমন লাগে:
customer_data_oh = pd.get_dummies(customer_data)
customer_data_oh
এটি আমাদের ফলাফল টেবিলের একটি পূর্বরূপ দেবে:
আউটপুট দিয়ে, কলামটি দেখতে সহজ Genre
কলামে বিভক্ত ছিল- Genre_Female
এবং Genre_Male
. গ্রাহক যখন মহিলা হয়, Genre_Female
সমান 1
, এবং যখন গ্রাহক পুরুষ হয়, এটি সমান হয় 0
.
এছাড়াও Age Groups
কলামটি 6টি কলামে বিভক্ত ছিল, প্রতিটি ব্যবধানের জন্য একটি, যেমন Age Groups_(15, 20]
, Age Groups_(20, 30]
, এবং তাই. একই ভাবে যেমন Genre
, যখন গ্রাহকের বয়স 18 বছর, Age Groups_(15, 20]
মান হয় 1
এবং অন্য সব কলামের মান হল 0
.
সার্জারির সুবিধা এক-হট এনকোডিং হল কলামের মানগুলিকে উপস্থাপন করার সরলতা, কী ঘটছে তা বোঝা সহজ - যখন অসুবিধা আমরা এখন 8টি অতিরিক্ত কলাম তৈরি করেছি, আমাদের ইতিমধ্যে যে কলামগুলি ছিল তার সাথে যোগ করার জন্য।
সতর্কতা: আপনার যদি এমন একটি ডেটাসেট থাকে যেখানে এক-হট এনকোড করা কলামের সংখ্যা সারির সংখ্যাকে ছাড়িয়ে যায়, তবে ডেটা মাত্রাগত সমস্যা এড়াতে অন্য এনকোডিং পদ্ধতি ব্যবহার করা ভাল।
এক-হট এনকোডিং আমাদের ডেটাতে 0s যোগ করে, এটিকে আরও স্পার্স করে, যা কিছু অ্যালগরিদমের জন্য সমস্যা হতে পারে যেগুলি ডেটা স্পারসিটির প্রতি সংবেদনশীল।
আমাদের ক্লাস্টারিং প্রয়োজনের জন্য, এক-হট এনকোডিং কাজ করছে বলে মনে হচ্ছে। কিন্তু ক্লাস্টার করার জন্য আমাদের জন্য সত্যিই আলাদা গ্রুপ আছে কিনা তা দেখার জন্য আমরা ডেটা প্লট করতে পারি।
বেসিক প্লটিং এবং ডাইমেনশনালিটি রিডাকশন
আমাদের ডেটাসেটে 11টি কলাম রয়েছে এবং কিছু উপায় রয়েছে যার মাধ্যমে আমরা সেই ডেটাটি কল্পনা করতে পারি। প্রথমটি হল এটিকে 10-মাত্রায় প্লট করে (সেটির সাথে সৌভাগ্য)। দশ কারণ Customer_ID
কলাম বিবেচনা করা হচ্ছে না। দ্বিতীয়টি হল আমাদের প্রাথমিক সংখ্যাসূচক বৈশিষ্ট্যগুলিকে প্লট করার মাধ্যমে, এবং তৃতীয়টি হল আমাদের 10টি বৈশিষ্ট্যকে 2-এ রূপান্তরিত করার মাধ্যমে - তাই, একটি মাত্রিকতা হ্রাস করা।
ডেটার প্রতিটি জোড়া প্লট করা
যেহেতু 10টি মাত্রা প্লট করা কিছুটা অসম্ভব, আমরা দ্বিতীয় পদ্ধতির সাথে যেতে বেছে নেব - আমরা আমাদের প্রাথমিক বৈশিষ্ট্যগুলি প্লট করব। আমরা আমাদের ক্লাস্টারিং বিশ্লেষণের জন্য তাদের মধ্যে দুটি বেছে নিতে পারি। আমাদের সমস্ত ডেটা জোড়া একত্রিত করার একটি উপায় হল একটি Seaborn এর সাথে pairplot()
:
import seaborn as sns
customer_data = customer_data.drop('CustomerID', axis=1)
sns.pairplot(customer_data)
যা প্রদর্শন করে:
এক নজরে, আমরা স্ক্যাটারপ্লটগুলিকে চিহ্নিত করতে পারি যেগুলিতে ডেটার গ্রুপ রয়েছে বলে মনে হয়৷ একটি আকর্ষণীয় বলে মনে হচ্ছে স্ক্যাটারপ্লট যা একত্রিত করে Annual Income
এবং Spending Score
. লক্ষ্য করুন যে অন্যান্য পরিবর্তনশীল স্ক্যাটারপ্লটগুলির মধ্যে কোন স্পষ্ট বিচ্ছেদ নেই। সর্বাধিক, আমরা বলতে পারি যে বিন্দুর দুটি স্বতন্ত্র ঘনত্ব রয়েছে Spending Score
vs Age
scatterplot
উভয় scatterplots গঠিত Annual Income
এবং Spending Score
মূলত একই। আমরা এটি দুইবার দেখতে পারি কারণ x এবং y-অক্ষ বিনিময় হয়েছিল। তাদের যে কোনো একটি কটাক্ষপাত করে, আমরা পাঁচটি ভিন্ন গ্রুপ হতে দেখা যাচ্ছে কি দেখতে পারেন. আসুন একটি Seaborn এর সাথে শুধুমাত্র সেই দুটি বৈশিষ্ট্য প্লট করি scatterplot()
ঘনিষ্ঠভাবে দেখতে:
sns.scatterplot(x=customer_data['Annual Income (k$)'],
y=customer_data['Spending Score (1-100)'])
কাছাকাছি দেখে, আমরা নিশ্চিতভাবে ডেটার 5টি ভিন্ন গ্রুপকে আলাদা করতে পারি। মনে হচ্ছে আমাদের গ্রাহকরা এক বছরে কত উপার্জন করে এবং তারা কত খরচ করে তার উপর ভিত্তি করে ক্লাস্টার করা যেতে পারে। এটি আমাদের বিশ্লেষণে আরেকটি প্রাসঙ্গিক পয়েন্ট। এটা গুরুত্বপূর্ণ যে আমরা আমাদের ক্লায়েন্টদের গ্রুপ করার জন্য শুধুমাত্র দুটি বৈশিষ্ট্য বিবেচনা করছি। তাদের সম্পর্কে আমাদের কাছে অন্য কোনো তথ্য সমীকরণে প্রবেশ করছে না। এটি বিশ্লেষণের অর্থ দেয় - যদি আমরা জানি যে একজন ক্লায়েন্ট কতটা উপার্জন করে এবং ব্যয় করে, তাহলে আমরা সহজেই আমাদের প্রয়োজনীয় মিল খুঁজে পেতে পারি।
দারুণ! এখন পর্যন্ত, আমাদের মডেল তৈরি করার জন্য আমাদের কাছে ইতিমধ্যে দুটি ভেরিয়েবল রয়েছে। এটি যা উপস্থাপন করে তা ছাড়াও, এটি মডেলটিকে সহজ, তুচ্ছ এবং আরও ব্যাখ্যাযোগ্য করে তোলে।
সেরা-অভ্যাস, শিল্প-স্বীকৃত মান এবং অন্তর্ভুক্ত চিট শীট সহ গিট শেখার জন্য আমাদের হ্যান্ডস-অন, ব্যবহারিক গাইড দেখুন। গুগলিং গিট কমান্ড এবং আসলে বন্ধ করুন শেখা এটা!
বিঃদ্রঃ: ডেটা সায়েন্স সাধারণত যতটা সম্ভব সহজ পদ্ধতির পক্ষে। ব্যবসার জন্য ব্যাখ্যা করা সহজ বলেই নয়, বরং এটি আরও প্রত্যক্ষ - 2টি বৈশিষ্ট্য এবং একটি ব্যাখ্যাযোগ্য মডেল সহ, মডেলটি কী করছে এবং কীভাবে কাজ করছে তা স্পষ্ট৷
PCA ব্যবহার করার পর ডেটা প্লট করা
মনে হচ্ছে আমাদের দ্বিতীয় পদ্ধতিটি সম্ভবত সেরা, তবে আসুন আমাদের তৃতীয় পদ্ধতির দিকেও নজর দেওয়া যাক। এটি উপযোগী হতে পারে যখন আমরা ডেটা প্লট করতে পারি না কারণ এটির অনেকগুলি মাত্রা রয়েছে, বা যখন কোনও ডেটা ঘনত্ব বা গ্রুপে স্পষ্ট বিচ্ছেদ নেই। যখন এই পরিস্থিতিগুলি ঘটে, তখন এটি একটি পদ্ধতির মাধ্যমে ডেটা মাত্রা হ্রাস করার চেষ্টা করার পরামর্শ দেওয়া হয় প্রধান উপাদান বিশ্লেষণ (পিসিএ).
বিঃদ্রঃ: বেশিরভাগ লোক ভিজ্যুয়ালাইজেশনের আগে মাত্রিকতা হ্রাসের জন্য PCA ব্যবহার করে। ক্লাস্টারিংয়ের আগে ডেটা ভিজ্যুয়ালাইজেশনে সাহায্য করে এমন অন্যান্য পদ্ধতি রয়েছে, যেমন ঘনত্ব-ভিত্তিক স্থানিক ক্লাস্টারিং অফ অ্যাপ্লিকেশান উইথ নয়েজ (DBSCAN) এবং স্ব-সংগঠিত মানচিত্র (এসওএম) ক্লাস্টারিং উভয়ই ক্লাস্টারিং অ্যালগরিদম, তবে ডেটা ভিজ্যুয়ালাইজেশনের জন্যও ব্যবহার করা যেতে পারে। যেহেতু ক্লাস্টারিং বিশ্লেষণের কোন সুবর্ণ মান নেই, তাই বিভিন্ন ভিজ্যুয়ালাইজেশন এবং বিভিন্ন অ্যালগরিদমের তুলনা করা গুরুত্বপূর্ণ।
PCA যতটা সম্ভব তথ্য সংরক্ষণ করার চেষ্টা করার সময় আমাদের ডেটার মাত্রা কমিয়ে দেবে। আসুন প্রথমে PCA কীভাবে কাজ করে সে সম্পর্কে একটি ধারণা নেওয়া যাক এবং তারপরে আমরা আমাদের ডেটা কতগুলি ডাটা কমিয়ে আনব তা বেছে নিতে পারি।
প্রতিটি জোড়া বৈশিষ্ট্যের জন্য, PCA দেখে যে একটি ভেরিয়েবলের বৃহত্তর মান অন্য ভেরিয়েবলের বৃহত্তর মানের সাথে মিলে যায় কিনা এবং এটি কম মানের জন্য একই কাজ করে। সুতরাং, এটি মূলত গণনা করে যে বৈশিষ্ট্যের মানগুলি একে অপরের প্রতি কতটা পরিবর্তিত হয় - আমরা এটিকে তাদের বলি সমবায়. সেই ফলাফলগুলি তারপর একটি ম্যাট্রিক্সে সংগঠিত হয়, a প্রাপ্ত করে সহভেদাংক ম্যাট্রিক্স.
কোভেরিয়েন্স ম্যাট্রিক্স পাওয়ার পর, পিসিএ বৈশিষ্ট্যগুলির একটি রৈখিক সংমিশ্রণ খুঁজে বের করার চেষ্টা করে যা এটিকে সর্বোত্তম ব্যাখ্যা করে – এটি রৈখিক মডেলের সাথে খাপ খায় যতক্ষণ না এটি ব্যাখ্যা করে এমন একটিকে চিহ্নিত করে। সর্বাধিক ভিন্নতার পরিমাণ.
বিঃদ্রঃ: PCA হল একটি রৈখিক রূপান্তর, এবং রৈখিকতা তথ্যের স্কেলে সংবেদনশীল। অতএব, PCA সর্বোত্তম কাজ করে যখন সমস্ত ডেটা মান একই স্কেলে থাকে। এটি কলাম বিয়োগ করে করা যেতে পারে গড় এর মানগুলি থেকে এবং ফলাফলটিকে এর মানক বিচ্যুতি দ্বারা ভাগ করে। যাকে বলা হয় তথ্য মানীকরণ. PCA ব্যবহার করার আগে, নিশ্চিত করুন যে ডেটা স্কেল করা হয়েছে! আপনি কিভাবে নিশ্চিত না হন, আমাদের পড়ুন "পাইথনে মেশিন লার্নিংয়ের জন্য Scikit-Learn এর সাথে ফিচার স্কেলিং ডেটা"!
সেরা রেখা (রৈখিক সংমিশ্রণ) পাওয়া গেলে, পিসিএ তার অক্ষগুলির দিকনির্দেশ পায়, যাকে বলা হয় eigenvectors, এবং এর রৈখিক সহগ, eigenvalues. eigenvectors এবং eigenvalue - বা অক্ষের দিকনির্দেশ এবং সহগ - এর সমন্বয় হল অধ্যক্ষ উপাদান PCA এর। এবং এটি হল যখন আমরা প্রতিটি বৈশিষ্ট্যের ব্যাখ্যা করা বৈচিত্রের উপর ভিত্তি করে আমাদের মাত্রার সংখ্যা বেছে নিতে পারি, কোন প্রধান উপাদানগুলিকে আমরা কতটা বৈচিত্র্য ব্যাখ্যা করে তার উপর ভিত্তি করে কোন প্রধান উপাদানগুলি রাখতে বা বাতিল করতে চাই তা বোঝার মাধ্যমে।
প্রধান উপাদানগুলি পাওয়ার পরে, পিসিএ বৈশিষ্ট্যগুলির একটি ভেক্টর তৈরি করতে আইজেনভেক্টর ব্যবহার করে যা মূল অক্ষগুলি থেকে মূল উপাদানগুলির দ্বারা উপস্থাপিতগুলির সাথে ডেটাকে পুনর্বিন্যাস করে – এভাবেই ডেটা মাত্রা হ্রাস করা হয়।
বিঃদ্রঃ: এখানে বিবেচনা করার জন্য একটি গুরুত্বপূর্ণ বিশদটি হল যে, তার রৈখিক প্রকৃতির কারণে, PCA প্রথম প্রধান উপাদানগুলিতে ব্যাখ্যা করা বেশিরভাগ বৈচিত্র্যকে কেন্দ্রীভূত করবে। সুতরাং, ব্যাখ্যা করা বৈচিত্র্যের দিকে তাকানোর সময়, সাধারণত আমাদের প্রথম দুটি উপাদান যথেষ্ট হবে। তবে এটি কিছু ক্ষেত্রে বিভ্রান্তিকর হতে পারে - তাই ক্লাস্টার করার সময় বিভিন্ন প্লট এবং অ্যালগরিদমগুলির তুলনা করার চেষ্টা করুন তারা একই ফলাফল ধারণ করে কিনা।
পিসিএ প্রয়োগ করার আগে, আমাদের এর মধ্যে একটি নির্বাচন করতে হবে Age
কলাম বা Age Groups
আমাদের পূর্বের এক-হট এনকোডেড ডেটার কলাম। যেহেতু উভয় কলাম একই তথ্য উপস্থাপন করে, তাই এটিকে দুইবার উপস্থাপন করা আমাদের ডেটা বৈচিত্রকে প্রভাবিত করে। যদি Age Groups
কলাম নির্বাচন করা হয়, সহজভাবে সরান Age
পান্ডা ব্যবহার করে কলাম drop()
পদ্ধতি এবং এটি পুনরায় বরাদ্দ করুন customer_data_oh
পরিবর্তনশীল:
customer_data_oh = customer_data_oh.drop(['Age'], axis=1)
customer_data_oh.shape
এখন আমাদের ডেটাতে 10টি কলাম রয়েছে, যার অর্থ আমরা কলাম দ্বারা একটি প্রধান উপাদান পেতে পারি এবং একটি নতুন মাত্রা প্রবর্তন আমাদের ডেটা বৈচিত্র্যের আরও ব্যাখ্যা করে কতটা পরিমাপ করে আমরা তাদের মধ্যে কতগুলি ব্যবহার করব তা চয়ন করতে পারি।
Sikit-Learn এর সাথে এটা করা যাক PCA
. আমরা প্রদত্ত প্রতিটি মাত্রার ব্যাখ্যাকৃত বৈচিত্র গণনা করব explained_variance_ratio_
, এবং তারপর তাদের ক্রমবর্ধমান সমষ্টি দেখুন cumsum()
:
from sklearn.decomposition import PCA
pca = PCA(n_components=10)
pca.fit_transform(customer_data_oh)
pca.explained_variance_ratio_.cumsum()
আমাদের ক্রমবর্ধমান ব্যাখ্যা করা বৈচিত্রগুলি হল:
array([0.509337 , 0.99909504, 0.99946364, 0.99965506, 0.99977937,
0.99986848, 0.99993716, 1. , 1. , 1. ])
আমরা দেখতে পাচ্ছি যে প্রথম মাত্রাটি 50% ডেটা ব্যাখ্যা করে এবং দ্বিতীয় মাত্রার সাথে মিলিত হলে তারা 99% শতাংশ ব্যাখ্যা করে। এর মানে হল যে প্রথম 2টি মাত্রা ইতিমধ্যেই আমাদের 99% ডেটা ব্যাখ্যা করে৷ সুতরাং আমরা 2টি উপাদান সহ একটি পিসিএ প্রয়োগ করতে পারি, আমাদের প্রধান উপাদানগুলি পেতে পারি এবং সেগুলি প্লট করতে পারি:
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
pcs = pca.fit_transform(customer_data_oh)
pc1_values = pcs[:,0]
pc2_values = pcs[:,1]
sns.scatterplot(x=pc1_values, y=pc2_values)
PCA-এর পরের ডেটা প্লটটি PCA ছাড়া ডেটার মাত্র দুটি কলাম ব্যবহার করে এমন প্লটের মতোই। লক্ষ্য করুন যে পয়েন্টগুলি যেগুলি গ্রুপ তৈরি করছে সেগুলি কাছাকাছি, এবং PCA-এর পরে আগের তুলনায় একটু বেশি ঘনীভূত।
ডেনড্রোগ্রামের সাহায্যে হায়ারার্কিক্যাল স্ট্রাকচার ভিজ্যুয়ালাইজ করা
এখন পর্যন্ত, আমরা ডেটা, এক-হট এনকোডেড ক্যাটাগরিকাল কলামগুলি অন্বেষণ করেছি, সিদ্ধান্ত নিয়েছি কোন কলামগুলি ক্লাস্টারিংয়ের জন্য উপযুক্ত, এবং ডেটা মাত্রা হ্রাস করেছে। প্লটগুলি নির্দেশ করে যে আমাদের ডেটাতে আমাদের 5টি ক্লাস্টার রয়েছে, তবে আমাদের পয়েন্টগুলির মধ্যে সম্পর্কগুলি কল্পনা করার এবং ক্লাস্টারগুলির সংখ্যা নির্ধারণে সহায়তা করার আরেকটি উপায় রয়েছে - একটি তৈরি করে ডেনড্রোগ্রাম (সাধারণত ডেন্ডোগ্রাম হিসাবে ভুল বানান)। ডেন্ড্রো মানে বৃক্ষ ল্যাটিন ভাষায়
সার্জারির ডেনড্রোগ্রাম একটি ডেটাসেটে পয়েন্ট লিঙ্ক করার ফলাফল। এটি শ্রেণিবদ্ধ ক্লাস্টারিং প্রক্রিয়ার একটি চাক্ষুষ উপস্থাপনা। এবং কিভাবে শ্রেণীবদ্ধ ক্লাস্টারিং প্রক্রিয়া কাজ করে? ভাল... এটা নির্ভর করে - সম্ভবত একটি উত্তর আপনি ইতিমধ্যে ডেটা সায়েন্সে অনেক শুনেছেন।
অনুক্রমিক ক্লাস্টারিং বোঝা
যখন হায়ারার্কিক্যাল ক্লাস্টারিং অ্যালগরিদম (HCA) পয়েন্টগুলিকে লিঙ্ক করতে এবং ক্লাস্টারগুলি খুঁজে পেতে শুরু করে, এটি প্রথমে পয়েন্টগুলিকে 2টি বড় গ্রুপে বিভক্ত করতে পারে এবং তারপর সেই দুটি গ্রুপের প্রতিটিকে ছোট 2টি গ্রুপে বিভক্ত করতে পারে, মোট 4টি গ্রুপ রয়েছে, যা হল বিভেদ সৃষ্টিকর এবং আপাদোমোস্তোক পদ্ধতির।
বিকল্পভাবে, এটি বিপরীত কাজ করতে পারে - এটি সমস্ত ডেটা পয়েন্ট দেখতে পারে, একে অপরের কাছাকাছি 2টি পয়েন্ট খুঁজে পেতে পারে, তাদের লিঙ্ক করতে পারে এবং তারপরে সেই লিঙ্কযুক্ত পয়েন্টগুলির সবচেয়ে কাছের অন্য পয়েন্টগুলি খুঁজে পেতে পারে এবং 2টি গ্রুপ তৈরি করতে পারে থেকে নীচে আপ. যা হল সমষ্টিগত পন্থা আমরা বিকাশ করব।
অ্যাগ্লোমারেটিভ হায়ারার্কিক্যাল ক্লাস্টারিং সঞ্চালনের পদক্ষেপ
সমষ্টিগত পদ্ধতিকে আরও স্পষ্ট করার জন্য, এর পদক্ষেপ রয়েছে সমষ্টিগত স্তরবিন্যাস ক্লাস্টারিং (AHC) অ্যালগরিদম:
- শুরুতে, প্রতিটি ডেটা পয়েন্টকে একটি ক্লাস্টার হিসাবে বিবেচনা করুন। অতএব, শুরুতে ক্লাস্টারের সংখ্যা হবে K - যখন K হল একটি পূর্ণসংখ্যা যা ডেটা পয়েন্টের সংখ্যাকে প্রতিনিধিত্ব করে।
- K-1 ক্লাস্টারের ফলে দুটি নিকটতম ডেটা পয়েন্টে যোগ দিয়ে একটি ক্লাস্টার তৈরি করুন।
- K-2 ক্লাস্টারের ফলে দুটি নিকটতম ক্লাস্টারে যোগদান করে আরও ক্লাস্টার তৈরি করুন।
- একটি বড় ক্লাস্টার তৈরি না হওয়া পর্যন্ত উপরের তিনটি ধাপ পুনরাবৃত্তি করুন।
বিঃদ্রঃ: সরলীকরণের জন্য, আমরা 2 এবং 3 ধাপে "দুটি নিকটতম" ডেটা পয়েন্ট বলছি। কিন্তু পয়েন্ট লিঙ্ক করার আরও উপায় আছে যা আমরা একটু পরে দেখব।
আপনি যদি ACH অ্যালগরিদমের ধাপগুলিকে উল্টে দেন, 4 থেকে 1-এ যাওয়ার ধাপগুলি হবে *ডিভিসিভ হায়ারর্কিক্যাল ক্লাস্টারিং (DHC)*.
লক্ষ্য করুন যে এইচসিএগুলি হয় বিভাজক এবং উপরে-নিচে, বা সমষ্টিগত এবং নীচে-আপ হতে পারে। টপ-ডাউন ডিএইচসি পদ্ধতিটি সবচেয়ে ভাল কাজ করে যখন আপনার কাছে কম, কিন্তু বড় ক্লাস্টার থাকে, তাই এটি গণনাগতভাবে আরও ব্যয়বহুল। অন্যদিকে, যখন আপনার অনেক ছোট ক্লাস্টার থাকে তখন নিচের-আপ AHC পদ্ধতিটি উপযুক্ত। এটি গণনাগতভাবে সহজ, আরও ব্যবহৃত এবং আরও উপলব্ধ।
বিঃদ্রঃ: হয় উপরে-নিচে বা নীচে-উপরে, ক্লাস্টারিং প্রক্রিয়ার ডেনড্রোগ্রাম উপস্থাপনা সর্বদা দুই ভাগে একটি বিভাজন দিয়ে শুরু হবে এবং প্রতিটি পৃথক বিন্দু বৈষম্যের সাথে শেষ হবে, একবার এর অন্তর্নিহিত কাঠামোটি একটি বাইনারি গাছের হয়ে গেলে।
ডেটার শ্রেণীবদ্ধ সম্পর্কগুলি কল্পনা করতে আমাদের গ্রাহক ডেটা ডেনড্রোগ্রাম প্লট করা যাক। এই সময়, আমরা ব্যবহার করব scipy
আমাদের ডেটাসেটের জন্য ডেনড্রোগ্রাম তৈরি করতে লাইব্রেরি:
import scipy.cluster.hierarchy as shc
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 7))
plt.title("Customers Dendrogram")
selected_data = customer_data_oh.iloc[:, 1:3]
clusters = shc.linkage(selected_data,
method='ward',
metric="euclidean")
shc.dendrogram(Z=clusters)
plt.show()
স্ক্রিপ্টের আউটপুট এই মত দেখায়:
উপরের স্ক্রিপ্টে, আমরা আমাদের পয়েন্টগুলির সাথে ক্লাস্টার এবং সাবক্লাস্টার তৈরি করেছি, আমাদের পয়েন্টগুলি কীভাবে লিঙ্ক করবে (প্রয়োগ করে ward
পদ্ধতি), এবং কিভাবে পয়েন্টের মধ্যে দূরত্ব পরিমাপ করা যায় ( ব্যবহার করে euclidean
মেট্রিক)।
ডেনড্রোগ্রামের প্লট দিয়ে, ডিএইচসি এবং এএইচসি-র বর্ণিত প্রক্রিয়াগুলি কল্পনা করা যেতে পারে। টপ-ডাউন অ্যাপ্রোচটি ভিজ্যুয়ালাইজ করতে ডেনড্রোগ্রামের উপরের দিক থেকে শুরু করুন এবং নিচে যান এবং বিপরীত কাজটি করুন, নিচে থেকে শুরু করুন এবং নিচের দিকের দিকে এগিয়ে যান।
সংযোগ পদ্ধতি
আরও অনেকগুলি সংযোগ পদ্ধতি রয়েছে, তারা কীভাবে কাজ করে সে সম্পর্কে আরও বোঝার মাধ্যমে, আপনি আপনার প্রয়োজনের জন্য উপযুক্ত একটি বেছে নিতে সক্ষম হবেন। তা ছাড়া, তাদের প্রতিটি প্রয়োগ করা হলে ভিন্ন ভিন্ন ফলাফল পাওয়া যাবে। ক্লাস্টারিং বিশ্লেষণের কোনো নির্দিষ্ট নিয়ম নেই, যদি সম্ভব হয়, তাহলে সমস্যার প্রকৃতি অধ্যয়ন করুন কোনটি সবচেয়ে ভালো মানানসই তা দেখতে, বিভিন্ন পদ্ধতি পরীক্ষা করুন এবং ফলাফল পরিদর্শন করুন।
কিছু সংযোগ পদ্ধতি হল:
- একক সংযোগ: এছাড়াও হিসাবে উল্লেখ করা নিকটতম প্রতিবেশী (NN). ক্লাস্টারগুলির মধ্যে দূরত্ব তাদের নিকটতম সদস্যদের মধ্যে দূরত্ব দ্বারা সংজ্ঞায়িত করা হয়।
- সম্পূর্ণ সংযোগ: এছাড়াও হিসাবে উল্লেখ করা দূরতম প্রতিবেশী (FN), দূরতম বিন্দু অ্যালগরিদম, বা Voor Hees অ্যালগরিদম. ক্লাস্টারগুলির মধ্যে দূরত্ব তাদের দূরবর্তী সদস্যদের মধ্যে দূরত্ব দ্বারা সংজ্ঞায়িত করা হয়। এই পদ্ধতিটি গণনাগতভাবে ব্যয়বহুল।
- গড় সংযোগ: এভাবেও পরিচিত ইউপিজিএমএ (পাটিগণিত গড় সহ ওজনহীন জোড়া গ্রুপ পদ্ধতি). প্রতিটি ক্লাস্টারের পয়েন্টের সংখ্যার শতাংশ গণনা করা হয় দুই ক্লাস্টারের পয়েন্টের সংখ্যার সাথে সাপেক্ষে যদি তারা একত্রিত হয়।
- ওজনযুক্ত সংযোগ: এভাবেও পরিচিত WPGMA (পাটিগণিত গড় সহ ওজনযুক্ত জোড়া গ্রুপ পদ্ধতি). দুটি ক্লাস্টারের পৃথক বিন্দু একটি ছোট এবং একটি বড় ক্লাস্টারের মধ্যে সমষ্টিগত দূরত্বে অবদান রাখে।
- সেন্ট্রোয়েড লিঙ্কেজ: এছাড়াও হিসাবে উল্লেখ করা ইউপিজিএমসি (সেন্ট্রোয়েড ব্যবহার করে ওজনহীন জোড়া গ্রুপ পদ্ধতি). সমস্ত বিন্দুর গড় (সেন্ট্রয়েড) দ্বারা সংজ্ঞায়িত একটি বিন্দু প্রতিটি ক্লাস্টারের জন্য গণনা করা হয় এবং ক্লাস্টারগুলির মধ্যে দূরত্ব হল তাদের নিজ নিজ সেন্ট্রোয়েডগুলির মধ্যে দূরত্ব।
- ওয়ার্ড সংযোগ: এভাবেও পরিচিত মিসকিউ (বর্গক্ষেত্রের যোগফলের ন্যূনতম বৃদ্ধি). এটি দুটি ক্লাস্টারের মধ্যে দূরত্ব নির্দিষ্ট করে, স্কোয়ার ত্রুটির যোগফল (ESS) গণনা করে এবং ছোট ESS-এর উপর ভিত্তি করে পরের ক্লাস্টারগুলি বেছে নেয়। ওয়ার্ডের পদ্ধতি প্রতিটি ধাপে ESS বৃদ্ধি কমিয়ে আনতে চায়। অতএব, ত্রুটি কমানো.
দূরত্ব মেট্রিক্স
সংযোগের পাশাপাশি, আমরা কিছু সর্বাধিক ব্যবহৃত দূরত্ব মেট্রিক্সও নির্দিষ্ট করতে পারি:
- ইউক্লিডিয়ান: এছাড়াও হিসাবে উল্লেখ করা পিথাগোরিয়ান বা সরলরেখা দূরত্ব এটি মহাকাশের দুটি বিন্দুর মধ্যে দূরত্ব গণনা করে, তাদের মধ্যবর্তী একটি রেখার অংশের দৈর্ঘ্য পরিমাপ করে। এটি পিথাগোরিয়ান উপপাদ্য ব্যবহার করে এবং দূরত্বের মান ফলাফল (গ) সমীকরণের:
$$
c^2 = a^2 + b^2
$$
- ম্যানহাটন: বলা সিটি-ব্লক, ট্যাক্সিক্যাব দূরত্ব এটি দুটি বিন্দুর সমস্ত মাত্রার পরিমাপের মধ্যে পরম পার্থক্যের সমষ্টি। যদি এই মাত্রা দুটি হয়, তবে এটি একটি ব্লকে হাঁটার সময় ডান এবং তারপর বামে তৈরি করার মতো।
- মিনকোভস্কি: এটি ইউক্লিডীয় এবং ম্যানহাটান উভয় দূরত্বের একটি সাধারণীকরণ। এটি মিনকোস্কি মেট্রিকের ক্রম অনুসারে পরম পার্থক্যের উপর ভিত্তি করে দূরত্ব গণনা করার একটি উপায় p. যদিও এটি যে কোনো জন্য সংজ্ঞায়িত করা হয় p> 0, এটি 1, 2, এবং ∞ (অসীম) ছাড়া অন্য মানের জন্য খুব কমই ব্যবহৃত হয়। Minkowski দূরত্ব ম্যানহাটন দূরত্ব হিসাবে একই যখন P = 1, এবং একই যখন ইউক্লিডীয় দূরত্ব P = 2.
$$
Dleft(X,Yright) = left(sum_{i=1}^n |x_i-y_i|^pright)^{frac{1}{p}}
$$
- চেবিশেভ: এভাবেও পরিচিত দাবাবোর্ড দূরত্ব এটি Minkowski দূরত্বের চরম কেস। যখন আমরা প্যারামিটারের মান হিসাবে অসীম ব্যবহার করি p (p = ∞), আমরা একটি মেট্রিক দিয়ে শেষ করি যা স্থানাঙ্কগুলির মধ্যে সর্বাধিক পরম পার্থক্য হিসাবে দূরত্বকে সংজ্ঞায়িত করে।
- কোসাইন্: এটি দুটি ক্রমবিন্দু বা ভেক্টরের মধ্যে কৌণিক কোসাইন দূরত্ব। কোসাইন সাদৃশ্য হল ভেক্টরের বিন্দু গুণফলকে তাদের দৈর্ঘ্যের গুণফল দিয়ে ভাগ করা হয়।
- জ্যাকার্ড: বিন্দুর সসীম সেটের মধ্যে সাদৃশ্য পরিমাপ করে। একে প্রতিটি সেটের (ছেদ) সাধারণ বিন্দুতে বিন্দুর মোট সংখ্যা (কার্ডিনালিটি) হিসাবে সংজ্ঞায়িত করা হয়, উভয় সেটের (ইউনিয়ন) মোট পয়েন্টের মোট বিন্দুর সংখ্যা (কার্ডিনালিটি) দ্বারা ভাগ করা হয়।
- জেনসেন-শ্যানন: Kullback-Leibler ডাইভারজেন্সের উপর ভিত্তি করে। এটি পয়েন্টের সম্ভাব্যতা বণ্টন বিবেচনা করে এবং সেই বিতরণগুলির মধ্যে সাদৃশ্য পরিমাপ করে। এটি সম্ভাব্যতা তত্ত্ব এবং পরিসংখ্যানের একটি জনপ্রিয় পদ্ধতি।
আমরা পছন্দ করেছি পাটক এবং ইউক্লিডিয়ান ডেনড্রোগ্রামের জন্য কারণ তারা সবচেয়ে বেশি ব্যবহৃত পদ্ধতি এবং মেট্রিক। এগুলি সাধারণত ভাল ফলাফল দেয় যেহেতু ওয়ার্ডগুলি ত্রুটিগুলি হ্রাস করার উপর ভিত্তি করে পয়েন্ট লিঙ্ক করে, এবং ইউক্লিডীয় নিম্ন মাত্রায় ভাল কাজ করে।
এই উদাহরণে, আমরা মার্কেটিং ডেটার দুটি বৈশিষ্ট্য (কলাম) এবং 200টি পর্যবেক্ষণ বা সারি নিয়ে কাজ করছি। যেহেতু পর্যবেক্ষণের সংখ্যা বৈশিষ্ট্যের সংখ্যা (200 > 2) থেকে বড়, তাই আমরা একটি নিম্ন-মাত্রিক স্থানে কাজ করছি।
যখন বৈশিষ্ট্য সংখ্যা (চ) পর্যবেক্ষণের সংখ্যার চেয়ে বড় (এন) - বেশিরভাগ হিসাবে লেখা চ >> এন, এর মানে হল যে আমরা একটি উচ্চ মাত্রিক স্থান.
যদি আমরা আরও বৈশিষ্ট্যগুলি অন্তর্ভুক্ত করি, যাতে আমাদের 200 টিরও বেশি বৈশিষ্ট্য থাকে, ইউক্লিডীয় দূরত্ব খুব ভাল কাজ নাও করতে পারে, কারণ এটি একটি খুব বড় স্থানের সমস্ত ছোট দূরত্ব পরিমাপ করতে অসুবিধা হবে যা কেবল বড় হয়। অন্য কথায়, ইউক্লিডীয় দূরত্ব পদ্ধতির ডেটা নিয়ে কাজ করতে অসুবিধা হয় স্বল্পতা. এটি একটি সমস্যা যা বলা হয় মাত্রিকতার অভিশাপ. দূরত্বের মানগুলি এত ছোট হবে, যেন তারা বৃহত্তর স্থানে "পাতলা" হয়ে যায়, যতক্ষণ না তারা 0 হয়ে যায় বিকৃত হয়।
বিঃদ্রঃ: আপনি যদি কখনও একটি ডেটাসেটের সাথে মুখোমুখি হন f>> পি, আপনি সম্ভবত অন্যান্য দূরত্ব মেট্রিক্স ব্যবহার করবেন, যেমন মহলনোবিস দূরত্ব বিকল্পভাবে, আপনি ব্যবহার করে ডেটাসেটের মাত্রাও কমাতে পারেন প্রধান উপাদান বিশ্লেষণ (পিসিএ). বিশেষ করে জৈবিক সিকোয়েন্সিং ডেটা ক্লাস্টার করার সময় এই সমস্যাটি ঘন ঘন হয়।
আমরা ইতিমধ্যেই মেট্রিক্স, লিঙ্কেজ এবং সেগুলির প্রতিটি কীভাবে আমাদের ফলাফলগুলিকে প্রভাবিত করতে পারে তা নিয়ে আলোচনা করেছি৷ আসুন এখন ডেনড্রোগ্রাম বিশ্লেষণ চালিয়ে যাওয়া যাক এবং দেখুন কিভাবে এটি আমাদের ডেটাসেটে ক্লাস্টারের সংখ্যার ইঙ্গিত দিতে পারে।
একটি ডেনড্রোগ্রামে একটি আকর্ষণীয় সংখ্যক ক্লাস্টার খুঁজে বের করা হল সবচেয়ে বড় অনুভূমিক স্থান খোঁজার মতো যেখানে কোনো উল্লম্ব রেখা নেই (দীর্ঘতম উল্লম্ব রেখা সহ স্থান)। এর মানে হল যে ক্লাস্টারগুলির মধ্যে আরও বিচ্ছেদ রয়েছে।
আমরা একটি অনুভূমিক রেখা আঁকতে পারি যা সেই দীর্ঘতম দূরত্বের মধ্য দিয়ে যায়:
plt.figure(figsize=(10, 7))
plt.title("Customers Dendogram with line")
clusters = shc.linkage(selected_data,
method='ward',
metric="euclidean")
shc.dendrogram(clusters)
plt.axhline(y = 125, color = 'r', linestyle = '-')
অনুভূমিক রেখাটি সনাক্ত করার পরে, আমরা গণনা করি কতবার আমাদের উল্লম্ব রেখাগুলি এটি দ্বারা অতিক্রম করেছে – এই উদাহরণে, 5 বার। সুতরাং 5 তাদের মধ্যে সবচেয়ে দূরত্ব রয়েছে এমন ক্লাস্টারের সংখ্যার একটি ভাল ইঙ্গিত বলে মনে হচ্ছে।
বিঃদ্রঃ: ডেনড্রোগ্রাম শুধুমাত্র একটি রেফারেন্স হিসাবে বিবেচনা করা উচিত যখন ক্লাস্টারের সংখ্যা নির্বাচন করতে ব্যবহৃত হয়। এটি সহজেই সেই সংখ্যাটি বন্ধ করে দিতে পারে এবং সংযোগের ধরন এবং দূরত্বের মেট্রিক্স দ্বারা সম্পূর্ণভাবে প্রভাবিত হয়৷ একটি গভীরভাবে ক্লাস্টার বিশ্লেষণ পরিচালনা করার সময়, বিভিন্ন সংযোগ এবং মেট্রিক্স সহ ডেনড্রোগ্রামগুলি দেখার পরামর্শ দেওয়া হয় এবং প্রথম তিনটি লাইনের সাথে উৎপন্ন ফলাফলগুলি দেখার পরামর্শ দেওয়া হয় যেখানে ক্লাস্টারগুলির মধ্যে তাদের মধ্যে সবচেয়ে বেশি দূরত্ব রয়েছে।
একটি সমষ্টিগত স্তরবিন্যাস ক্লাস্টারিং বাস্তবায়ন
মূল ডেটা ব্যবহার করে
এখন পর্যন্ত আমরা আমাদের ডেটাসেটের জন্য প্রস্তাবিত সংখ্যক ক্লাস্টার গণনা করেছি যা আমাদের প্রাথমিক বিশ্লেষণ এবং আমাদের PCA বিশ্লেষণের সাথে সমর্থন করে। এখন আমরা Scikit-Learn ব্যবহার করে আমাদের সমষ্টিগত শ্রেণিবিন্যাস ক্লাস্টারিং মডেল তৈরি করতে পারি AgglomerativeClustering
এবং এর সাথে মার্কেটিং পয়েন্টের লেবেল খুঁজে বের করুন labels_
:
from sklearn.cluster import AgglomerativeClustering
clustering_model = AgglomerativeClustering(n_clusters=5, affinity='euclidean', linkage='ward')
clustering_model.fit(selected_data)
clustering_model.labels_
এর ফলে:
array([4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3,
4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 1,
4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 0, 2, 0, 2,
1, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 2, 1, 2, 0, 2, 0, 2, 0, 2,
0, 2, 0, 2, 0, 2, 1, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2,
0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2,
0, 2])
আমরা এই বিন্দু পেতে অনেক তদন্ত করেছি. এবং এই লেবেল মানে কি? এখানে, আমাদের ডেটার প্রতিটি পয়েন্ট 0 থেকে 4 পর্যন্ত একটি গ্রুপ হিসাবে লেবেল করা আছে:
data_labels = clustering_model.labels_
sns.scatterplot(x='Annual Income (k$)',
y='Spending Score (1-100)',
data=selected_data,
hue=data_labels,
pallete="rainbow").set_title('Labeled Customer Data')
এটি আমাদের চূড়ান্ত ক্লাস্টারাইজড ডেটা। আপনি পাঁচটি ক্লাস্টার আকারে রঙ-কোডেড ডেটা পয়েন্ট দেখতে পারেন।
নীচের ডানদিকে ডেটা পয়েন্টগুলি (লেবেল: 0
, বেগুনি ডেটা পয়েন্ট) উচ্চ বেতন কিন্তু কম খরচের গ্রাহকদের অন্তর্গত। এই গ্রাহকরা সাবধানে তাদের অর্থ ব্যয়.
একইভাবে, উপরের ডানদিকে গ্রাহকরা (লেবেল: 2
, সবুজ তথ্য পয়েন্ট), উচ্চ বেতন এবং উচ্চ খরচ সঙ্গে গ্রাহকদের হয়. এই ধরনের গ্রাহকদের কোম্পানি লক্ষ্য করে.
মাঝখানে গ্রাহকরা (লেবেল: 1
, নীল ডেটা পয়েন্ট) হল গড় আয় এবং গড় খরচ সহ। সবচেয়ে বেশি সংখ্যক গ্রাহক এই বিভাগের অন্তর্গত। কোম্পানিগুলি এই গ্রাহকদের লক্ষ্য করতে পারে যে তারা বিপুল সংখ্যায় রয়েছে।
নীচে বাম দিকে গ্রাহকরা (লেবেল: 4
, লাল) গ্রাহকদের কম বেতন এবং কম খরচ হয়, তারা প্রমোশনের মাধ্যমে আকৃষ্ট হতে পারে।
এবং অবশেষে, উপরের বামে গ্রাহকরা (লেবেল: 3
, কমলা ডেটা পয়েন্ট) হল উচ্চ আয় এবং কম খরচ, যা আদর্শভাবে মার্কেটিং দ্বারা লক্ষ্য করা হয়।
PCA থেকে ফলাফল ব্যবহার করে
যদি আমরা একটি ভিন্ন পরিস্থিতিতে থাকতাম, যেখানে আমাদের ডেটার মাত্রা কমাতে হবে। আমরা সহজেই ক্লাস্টারাইজড পিসিএ ফলাফল প্লট করতে পারি। এটি অন্য একটি সমষ্টিগত ক্লাস্টারিং মডেল তৈরি করে এবং প্রতিটি প্রধান উপাদানের জন্য একটি ডেটা লেবেল প্রাপ্ত করে করা যেতে পারে:
clustering_model_pca = AgglomerativeClustering(n_clusters=5, affinity='euclidean', linkage='ward')
clustering_model_pca.fit(pcs)
data_labels_pca = clustering_model_pca.labels_
sns.scatterplot(x=pc1_values,
y=pc2_values,
hue=data_labels_pca,
palette="rainbow").set_title('Labeled Customer Data Reduced with PCA')
লক্ষ্য করুন যে উভয় ফলাফল খুব অনুরূপ। মূল পার্থক্য হল মূল ডেটা সহ প্রথম ফলাফল ব্যাখ্যা করা অনেক সহজ। এটি দেখতে পরিষ্কার যে গ্রাহকদের তাদের বার্ষিক আয় এবং ব্যয়ের স্কোর দ্বারা পাঁচটি গ্রুপে ভাগ করা যেতে পারে। যদিও, PCA পদ্ধতিতে, আমরা আমাদের সমস্ত বৈশিষ্ট্যগুলিকে বিবেচনায় নিচ্ছি, যতটা আমরা তাদের প্রত্যেকের দ্বারা ব্যাখ্যা করা বৈচিত্র্যের দিকে তাকাতে পারি, এটি উপলব্ধি করা একটি কঠিন ধারণা, বিশেষ করে যখন একটি মার্কেটিং বিভাগে রিপোর্ট করা হয়।
আমাদের ডেটা যত কম রূপান্তর করতে হবে, তত ভাল।
যদি আপনার কাছে একটি খুব বড় এবং জটিল ডেটাসেট থাকে যাতে আপনাকে ক্লাস্টারিংয়ের আগে একটি মাত্রিকতা হ্রাস করতে হবে - PCA-এর ব্যবহার ব্যাক আপ করতে এবং প্রক্রিয়াটির ব্যাখ্যাযোগ্যতা বাড়ানোর জন্য প্রতিটি বৈশিষ্ট্য এবং তাদের অবশিষ্টাংশগুলির মধ্যে রৈখিক সম্পর্ক বিশ্লেষণ করার চেষ্টা করুন। প্রতি জোড়া বৈশিষ্ট্যগুলির একটি লিনিয়ার মডেল তৈরি করে, আপনি বৈশিষ্ট্যগুলি কীভাবে ইন্টারঅ্যাক্ট করে তা বুঝতে সক্ষম হবেন।
ডেটা ভলিউম এত বড় হলে, বৈশিষ্ট্যগুলির জোড়া প্লট করা অসম্ভব হয়ে পড়ে, আপনার ডেটার একটি নমুনা নির্বাচন করুন, যতটা সম্ভব ভারসাম্যপূর্ণ এবং স্বাভাবিক বিতরণের কাছাকাছি এবং প্রথমে নমুনার বিশ্লেষণটি করুন, এটি বুঝুন, সূক্ষ্ম সুর করুন এটি - এবং এটি পরে পুরো ডেটাসেটে প্রয়োগ করুন।
আপনি সর্বদা আপনার ডেটার প্রকৃতি (লিনিয়ার, নন-লিনিয়ার) অনুসারে বিভিন্ন ক্লাস্টারিং ভিজ্যুয়ালাইজেশন কৌশল বেছে নিতে পারেন এবং প্রয়োজনে সেগুলিকে একত্রিত বা পরীক্ষা করতে পারেন।
উপসংহার
লেবেলবিহীন ডেটার ক্ষেত্রে ক্লাস্টারিং কৌশলটি খুব সহজ হতে পারে। যেহেতু বাস্তব জগতের বেশিরভাগ ডেটা লেবেলবিহীন এবং ডেটা টীকা করার জন্য বেশি খরচ হয়, তাই ক্লাস্টারিং কৌশলগুলি লেবেলবিহীন ডেটা লেবেল করতে ব্যবহার করা যেতে পারে।
এই নির্দেশিকায়, আমরা একটি বাস্তব তথ্য বিজ্ঞান সমস্যা নিয়ে এসেছি, যেহেতু ক্লাস্টারিং কৌশলগুলি ব্যাপকভাবে বিপণন বিশ্লেষণে (এবং জৈবিক বিশ্লেষণেও) ব্যবহৃত হয়। আমরা একটি ভাল শ্রেণিবিন্যাস ক্লাস্টারিং মডেল এবং কীভাবে ডেনড্রোগ্রামগুলি পড়তে হয় এবং PCA একটি প্রয়োজনীয় পদক্ষেপ কিনা তা নিয়ে প্রশ্ন তোলার জন্য তদন্তের অনেক পদক্ষেপ ব্যাখ্যা করেছি। আমাদের মূল উদ্দেশ্য হল কিছু সমস্যা এবং বিভিন্ন পরিস্থিতিতে যেখানে আমরা শ্রেণীবদ্ধ ক্লাস্টারিং খুঁজে পেতে পারি তা কভার করা হয়েছে।
শুভ ক্লাস্টারিং!
- blockchain
- সি ++
- থলোথলো
- কোড
- coingenius
- তথ্য বিজ্ঞান
- ডেটা ভিজ্যুয়ালাইজেশন
- জাভা
- matplotlib
- অ ছত্রাকযুক্ত টোকেন
- খোলা সমুদ্র
- পান্ডাস
- পিএইচপি
- Plato
- প্লেটো এআই
- প্লেটো ডেটা ইন্টেলিজেন্স
- প্লেটো গেম
- প্লেটো ব্লকচেইন
- প্লেটোডাটা
- প্লেটোগেমিং
- বহুভুজ
- পাইথন
- প্রতিক্রিয়া
- scikit-শিখতে
- সমুদ্রজাত
- স্মার্ট চুক্তি
- সোলানা
- Stackabuse
- ভাইপার
- Web3
- zephyrnet