في نافذة الطباعة اختر «حفظ كملف PDF» كوجهة.
تعلم الآلة، الأسبوع 8
التجميع بخوارزمية k-Means
تجميع عملاء لا تحمل بياناتهم أي تسمية: إسناد، ثم تحديث، ثم تكرار. ثم تقسيم 200 عميل إلى شرائح من أجل حملة.
الأهداف
- ▸التمييز بين التعلم الموجه (supervised learning) والتجميع (clustering)
- ▸تطبيق k-means يدويا: الإسناد إلى أقرب مركز (centroid)، ثم الانتقال إلى المتوسط، ثم التكرار
- ▸حساب مجموع المربعات داخل العناقيد (WCSS)، الذي تسميه scikit-learn
inertia_ - ▸تدريب
KMeans، وقراءةcluster_centers_وlabels_، واختيار k بطريقة الكوع (elbow method) - ▸تقسيم العملاء إلى شرائح (segments) واختيار الشريحة التي تستهدفها الحملة
- ▸شرح لماذا قد تعطي بداية مختلفة نتيجة مختلفة، وما يفعله
n_init
الأسبوع 8 من الخطة
موقع الدرس من المقرر
- ▸دفتران (notebooks): Clustering (الكتل، ثم 200 عميل من عملاء مجمع تجاري) وK_Means_Clustering_Practice (777 كلية أمريكية)
- ▸سيناريو من الواقع: تقسيم العملاء إلى شرائح من بياناتهم لتحديد من تستهدفه حملة لمنتج جديد أو عرض ترويجي (promotion) يزيد مشترياتهم
- ▸مرحلة المشروع (project milestone) هذا الأسبوع: عروض فرق المشاريع ومناقشاتها (Project Teams Presentations and Discussions)
خطة الساعتين
| الجزء | ما نفعله | الزمن |
|---|---|---|
| 1 | التجميع وخوارزمية k-means، ثم خمسة عملاء يدويا | 40 دقيقة |
| 2 | الدفتر 1: الكتل (blobs) وطريقة الكوع | 15 دقيقة |
| 3 | الدفتر 1: تقسيم العملاء إلى شرائح | 20 دقيقة |
| 4 | الدفتر 2: الكليات، ومرحلة المشروع | 15 دقيقة |
| 5 | تمارين مع الإجابات، ثم الخلاصة | 30 دقيقة |
الجزء 1
فكرة التجميع
إيجاد مجموعات من الصفوف المتشابهة، دون تسميات نتعلم منها
التعلم الموجه مقابل التجميع
| التعلم الموجه (الأسابيع من 3 إلى 7) | التجميع (هذا الأسبوع) | |
|---|---|---|
| بيانات التدريب | الخصائص (features) X وتسمية (label) y | الخصائص X فقط |
| ما يتعلمه النموذج | كيف يتنبأ بقيمة y | مجموعات من الصفوف المتشابهة |
| مثال | تتنبأ KNN بنوع زهرة iris | تجد k-means شرائح العملاء |
| التحقق من النتيجة | المقارنة بقيمة y الحقيقية | لا توجد إجابة صحيحة في العادة |
ما خوارزمية k-Means؟
- k-means
- تقسم العينات إلى k من العناقيد لا تتداخل. ويوصف كل عنقود بمتوسط (mean) عيناته: وهو مركزه.
- ▸أنت تختار k، أي عدد العناقيد
- ▸المركز في العادة ليس إحدى نقاط البيانات، لكنه يقع في الفضاء نفسه
- ▸للعملاء الموصوفين بزوج (الدخل، الإنفاق)، يكون المركز أيضا زوجا (الدخل، الإنفاق)
الخوارزمية
- 1اختر k وضع k من مراكز البداية، مثلا على k من نقاط البيانات تختارها عشوائيا
- 2الإسناد (assign): تنضم كل نقطة إلى أقرب مركز إليها (مربع المسافة الإقليدية)
- 3التحديث (update): ينتقل كل مركز إلى متوسط نقاطه
- 4كرر الإسناد والتحديث حتى لا تغير أي نقطة عنقودها
صيغتان
نقطة (x, y)، ومركز (a, b)، وعنقود فيه n من النقاط
- ▸خطوة الإسناد تستخدم d²: لا حاجة إلى الجذر التربيعي، فهو لا يغير أبدا أي المراكز هو الأقرب
- ▸خطوة التحديث تستخدم المتوسطين: المركز الجديد هو النقطة المتوسطة في عنقوده
- ▸المسافة نفسها التي استخدمتها KNN في الأسبوع 5، لكنها تقاس الآن إلى المراكز
يدويا
مثال محلول: خمسة عملاء
خمسة عملاء حقيقيون من الدفتر 1: الدخل السنوي (ألف دولار) ودرجة الإنفاق (من 1 إلى 100)
| العميل | الدخل (ألف دولار) | درجة الإنفاق |
|---|---|---|
| #11 | 19 | 14 |
| #49 | 40 | 42 |
| #62 | 46 | 55 |
| #136 | 73 | 88 |
| #190 | 103 | 85 |
التكرار 1: الإسناد
μ1 = (19, 14)، وμ2 = (46, 55)؛ والفرق = العميل ناقص المركز
| العميل | d² إلى μ1 | d² إلى μ2 | ينضم إلى |
|---|---|---|---|
| #11 | 0 + 0 = 0 | 729 + 1681 = 2410 | μ1 |
| #49 | 441 + 784 = 1225 | 36 + 169 = 205 | μ2 |
| #62 | 729 + 1681 = 2410 | 0 + 0 = 0 | μ2 |
| #136 | 2916 + 5476 = 8392 | 729 + 1089 = 1818 | μ2 |
| #190 | 7056 + 5041 = 12097 | 3249 + 900 = 4149 | μ2 |
التكرار 1: التحديث
العنقود 1: #11. العنقود 2: #49، #62، #136، #190
التكرار 2: الإسناد
μ1 = (19, 14)، وμ2 = (65.5, 67.5)
| العميل | d² إلى μ1 | d² إلى μ2 | ينضم إلى |
|---|---|---|---|
| #11 | 0 + 0 = 0 | 2162.25 + 2862.25 = 5024.5 | μ1 |
| #49 | 441 + 784 = 1225 | 650.25 + 650.25 = 1300.5 | μ1 |
| #62 | 729 + 1681 = 2410 | 380.25 + 156.25 = 536.5 | μ2 |
| #136 | 2916 + 5476 = 8392 | 56.25 + 420.25 = 476.5 | μ2 |
| #190 | 7056 + 5041 = 12097 | 1406.25 + 306.25 = 1712.5 | μ2 |
التكرار 2: التحديث
العنقود 1: #11، #49. العنقود 2: #62، #136، #190
التكرار 3: الإسناد
μ1 = (29.5, 28)، وμ2 = (74, 76)
| العميل | d² إلى μ1 | d² إلى μ2 | ينضم إلى |
|---|---|---|---|
| #11 | 110.25 + 196 = 306.25 | 3025 + 3844 = 6869 | μ1 |
| #49 | 110.25 + 196 = 306.25 | 1156 + 1156 = 2312 | μ1 |
| #62 | 272.25 + 729 = 1001.25 | 784 + 441 = 1225 | μ1 |
| #136 | 1892.25 + 3600 = 5492.25 | 1 + 144 = 145 | μ2 |
| #190 | 5402.25 + 3249 = 8651.25 | 841 + 81 = 922 | μ2 |
التكرار 3: التحديث
العنقود 1: #11، #49، #62. العنقود 2: #136، #190
التكرار 4: لا شيء يتحرك
μ1 = (35, 37)، وμ2 = (88, 86.5)
| العميل | d² إلى μ1 | d² إلى μ2 | ينضم إلى |
|---|---|---|---|
| #11 | 256 + 529 = 785 | 4761 + 5256.25 = 10017.25 | μ1 |
| #49 | 25 + 25 = 50 | 2304 + 1980.25 = 4284.25 | μ1 |
| #62 | 121 + 324 = 445 | 1764 + 992.25 = 2756.25 | μ1 |
| #136 | 1444 + 2601 = 4045 | 225 + 2.25 = 227.25 | μ2 |
| #190 | 4624 + 2304 = 6928 | 225 + 2.25 = 227.25 | μ2 |
WCSS: ما مدى تماسك العناقيد؟
N من النقاط، وd_i = المسافة من النقطة i إلى مركزها الذي تنتمي إليه
| التكرار | J بعد الإسناد | J بعد التحديث |
|---|---|---|
| 1 | 6172 | 4026 |
| 2 | 3950.5 | 2904.5 |
| 3 | 2680.75 | 1734.5 |
| 4 | 1734.5 | اكتمل التقارب |
جربها: k-Means خطوة بخطوة
الجزء 2
الدفتر 1: الكتل والكوع
نقاط مولدة أولا، لنعرف الإجابة الصحيحة
افتح الدفترين في Colab
https://colab.research.google.com/github/
jeffprosise/Machine-Learning/blob/master/
Clustering.ipynbhttps://colab.research.google.com/github/
tirthajyoti/Machine-Learning-with-Python/blob/master/
Clustering-Dimensionality-Reduction/
K_Means_Clustering_Practice.ipynbأربع كتل: اطلب 3 أو 4 أو 5 عناقيد
make_blobs(n_samples=300, centers=4, cluster_std=0.8, random_state=0)، ثم KMeans(n_clusters=k, random_state=0)

- ▸k = 3 يدمج كتلتين في عنقود واحد من 151 نقطة
- ▸k = 4 يجد الكتل الأربع: 81 و74 و73 و72 نقطة
- ▸k = 5 يقطع كتلة حقيقية واحدة إلى 42 و31 نقطة
نقطة جديدة: إلى أي عنقود؟
يتنبأ نموذج k = 4 بعنقود (-0.5, 5) باستخدام kmeans.predict(point)، ثم يطبع المسافة إلى كل مركز
[array([1.46570934]), array([4.8470332]),
array([2.93542029]), array([2.52147763])]اختيار k: طريقة الكوع

- ▸نفذ الحلقة لقيم k من 1 إلى 9 وسجل
kmeans.inertia_ - ▸القصور الذاتي (inertia) ينخفض دائما مع زيادة k، فأصغر قيمة ليست الإجابة
- ▸اختر الكوع: من 3 إلى 4 ينخفض 339.24، ومن 4 إلى 5 ينخفض 40.88 فقط
- ▸إذن k = 4، وهو عدد الكتل التي جرى توليدها
جربها: شغل حلقة الكوع
الجزء 3
تقسيم العملاء إلى شرائح
سيناريو الأسبوع 8: من يحصل على الحملة؟
السيناريو
تقسيم العملاء إلى شرائح بناء على بياناتهم، لتحديد العملاء الذين تستهدفهم حملة لمنتج جديد أو عرض ترويجي يزيد نشاطهم الشرائي.
| العمود | في العملاء الـ200 |
|---|---|
Gender | Male أو Female (88 و112) |
Age | من 18 إلى 70 |
Annual Income (k$) | من 15 إلى 137 |
Spending Score (1-100) | من 1 إلى 99: مقدار إنفاق العميل |
التحميل والاستكشاف
قيمة customers.shape هي (200, 5)؛ ويعرض info() أنه لا توجد قيم مفقودة
url = ("https://raw.githubusercontent.com/"
"jeffprosise/Machine-Learning/master/"
"Data/customers.csv")
customers = pd.read_csv(url)
points = customers.iloc[:, 3:5].values
x = points[:, 0]
y = points[:, 1]
plt.scatter(x, y, s=50, alpha=0.7)
الكوع يقول 5

- ▸الحلقة نفسها، قيم k من 1 إلى 9، على الدخل والإنفاق
- ▸من 4 إلى 5 ينخفض 29231.33 (من 73679.79 إلى 44448.46)
- ▸من 5 إلى 6 ينخفض 5589.50 فقط
- ▸يقسم الدفتر العملاء إلى خمسة عناقيد
خمس شرائح
KMeans(n_clusters=5, random_state=0)؛ والنقاط الحمراء هي المراكز

أي شريحة تحصل على العرض الترويجي؟
مراكز الشرائح الخمس
| العنقود | متوسط الدخل (ألف دولار) | متوسط الإنفاق | العملاء |
|---|---|---|---|
| 0 | 55.30 | 49.52 | 81 |
| 1 | 86.54 | 82.13 | 39 |
| 2 | 88.20 | 17.11 | 35 |
| 3 | 26.30 | 20.91 | 23 |
| 4 | 25.73 | 79.36 | 22 |
بناء قائمة الحملة
df = customers.copy()
df['Cluster'] = kmeans.predict(points)
cluster = kmeans.predict(np.array([[120, 20]]))[0]
clustered_df = df[df['Cluster'] == cluster]
clustered_df['CustomerID'].valuesالتقسيم على الخصائص الأربع كلها
الجنس والعمر والدخل والإنفاق؛ مع استبعاد CustomerID
from sklearn.preprocessing import LabelEncoder
df = customers.copy()
encoder = LabelEncoder()
df['Gender'] = encoder.fit_transform(df['Gender'])
points = df.iloc[:, 1:5].values
kmeans = KMeans(n_clusters=5, random_state=0)
kmeans.fit(points)
شرائح الخصائص الأربع
حلقة التقرير في الدفتر، صف لكل عنقود
| العنقود | متوسط العمر | متوسط الدخل | متوسط الإنفاق |
|---|---|---|---|
| 0 | 54.06 | 40.46 | 36.72 |
| 1 | 32.69 | 86.54 | 82.13 |
| 2 | 25.25 | 25.83 | 76.92 |
| 3 | 41.65 | 88.74 | 16.76 |
| 4 | 33.40 | 58.06 | 48.77 |
بداية مختلفة، نتيجة مختلفة
يعرض الدفتر المحفوظ أعمارا أخرى للخلية نفسها: 45.22، 32.69، 43.09، 40.67، 25.52
- ▸البداية عشوائية (
init='k-means++')، ويثبتهاrandom_state - ▸
n_init= عدد البدايات التي يشغلها النموذج؛ ويحتفظ منها بالتشغيل صاحب أصغر قصور ذاتي - ▸منذ scikit-learn 1.4 تعني القيمة الافتراضية
n_init='auto'بداية واحدة
| الإعداد | القصور الذاتي | أحجام العناقيد |
|---|---|---|
| بداية واحدة (الافتراضي) | 82657.05 | 50, 39, 24, 34, 53 |
n_init=10 | 75399.62 | 23, 39, 79, 23, 36 |
الجزء 4
الدفتر 2: الكليات
هل تستطيع k-means أن تجد الكليات الخاصة والحكومية دون التسميات؟
777 كلية، وعنقودان
- ▸
Private(YesأوNo) و17 عددا:Apps، وF.Undergrad، وOutstate، وExpend، ... - ▸565 كلية خاصة و212 كلية حكومية
- ▸تجميع الكليات على الأعداد الـ17 وحدها، ثم المقارنة بالعمود
Private - ▸لا توجد تسميات في التجميع الحقيقي؛ أما هنا فهي تتيح لنا تقييم النتيجة

ثلاث خلايا تحتاج إلى إصلاح
url = ("https://raw.githubusercontent.com/"
"tirthajyoti/Machine-Learning-with-Python/"
"master/Datasets/College_Data")
df = pd.read_csv(url, index_col=0)
df.loc['Cazenovia College', 'Grad.Rate'] = 100- ▸الملف
College_Dataليس بجوار الدفتر في Colab: اقرأه منDatasets - ▸السطر
df['Grad.Rate']['Cazenovia College'] = 100تعيين متسلسل (chained assignment): مع pandas 3 يكتفي بتحذير ويبقى المعدل 118. استخدم.loc - ▸تحتاج seaborn الآن إلى
x=وy=بالاسم، وإلىheight=بدلا منsize=فيlmplotوFacetGrid
تدريب نموذج بعنقودين
أضفنا random_state=0 ليكون التشغيل قابلا للتكرار
kmeans = KMeans(n_clusters=2, verbose=0, tol=1e-3, max_iter=300,
n_init=20, random_state=0)
kmeans.fit(df.drop('Private', axis=1))| الخاصية | العنقود 0 (669) | العنقود 1 (108) |
|---|---|---|
Apps | 1813.2 | 10363.1 |
F.Undergrad | 2188.5 | 13061.9 |
Outstate | 10395.7 | 10719.2 |
Expend | 8932.0 | 14170.5 |
مقارنة العناقيد بالتسميات
Cluster = 1 للكلية الخاصة، و0 للحكومية؛ وA = الدقة (accuracy)
print(confusion_matrix(df['Cluster'], kmeans.labels_))
# [[138 74]
# [531 34]]بدل رقمي العنقودين
1 - kmeans.labels_: المصفوفة المحفوظة في الدفتر
| العنقود 0 | العنقود 1 | |
|---|---|---|
| حكومية (0) | 74 | 138 |
| خاصة (1) | 34 | 531 |
قبل التمارين
الأخطاء الشائعة
- ▸اعتبار أرقام العناقيد ذات معنى: اقرأ المراكز
- ▸اختيار قيمة k صاحبة أصغر قصور ذاتي بدلا من الكوع
- ▸الثقة ببداية واحدة: استخدم
n_init=10أو أكثر - ▸التجميع على عمود معرف (ID)، أو تمرير أعمدة نصية دون ترميزها
- ▸تقييم العناقيد مقابل التسميات قبل مطابقة الأرقام
- ▸كتابة
df1 = dfوأنت تقصدdf1 = df.copy(): فبهذه الطريقة تسرب الخلية الأخيرة في الدفتر التسميات
مشروع فريقك
مرحلة المشروع: العروض والمناقشات
- 1المشكلة ومجموعة البيانات: الصفوف، والخصائص، والهدف
- 2كيف نظفت البيانات واستكشفتها، مع رسم أو رسمين
- 3النماذج التي بنيتها منذ الأسبوع 3، ونتائجها على مجموعة الاختبار نفسها
- 4النموذج الذي تحتفظ به، وسبب اختياره
- 5ما لا يزال ناقصا، وخطتك
الجزء 5
التمارين: دورك
نحو 30 دقيقة، والإجابات بعد كل مهمة
نحو 10 دقائق
التمرين 1: بداية مختلفة
- 1العملاء الخمسة أنفسهم، k = 2، وابدأ عند μ1 = #11 = (19, 14) وμ2 = #136 = (73, 88)
- 2نفذ الإسناد والتحديث حتى لا يغير أي عميل عنقوده
- 3اكتب العنقودين النهائيين، والمركزين، وقيمة
J - 4كم خطوة إسناد احتجت إليها، مقارنة بالمثال المحلول؟
الإجابات
التمرين 1: الإجابة
التكرار 1: المسافات إلى μ1 = (19, 14) وμ2 = (73, 88)
| العميل | d² إلى μ1 | d² إلى μ2 | ينضم إلى |
|---|---|---|---|
| #11 | 0 | 2916 + 5476 = 8392 | μ1 |
| #49 | 441 + 784 = 1225 | 1089 + 2116 = 3205 | μ1 |
| #62 | 729 + 1681 = 2410 | 729 + 1089 = 1818 | μ2 |
| #136 | 8392 | 0 | μ2 |
| #190 | 7056 + 5041 = 12097 | 900 + 9 = 909 | μ2 |
نحو 5 دقائق
التمرين 2: أي شريحة؟
عميل جديد: الدخل 100، والإنفاق 50
| العنقود | المركز (الدخل، الإنفاق) |
|---|---|
| 0 | (55.3, 49.5) |
| 1 | (86.5, 82.1) |
| 2 | (88.2, 17.1) |
| 3 | (26.3, 20.9) |
| 4 | (25.7, 79.4) |
نحو 5 دقائق
التمرين 3: تقييم عناقيد الكليات
بعد التبديل؛ A الدقة، وP_1 الضبط (precision) وR_1 الاستدعاء (recall) لصنف الكليات الخاصة
| العنقود 0 | العنقود 1 | |
|---|---|---|
| حكومية (0) | 74 | 138 |
| خاصة (1) | 34 | 531 |
نحو 10 دقائق
التمرين 4: في Colab
- 1الدفتر 1، الشرائح الخمس على الدخل والإنفاق: تنبأ بشريحة
[[100, 50], [20, 90]]باستدعاء واحد - 2أعد تشغيل نموذج الخصائص الأربع مع
n_init=10: اطبعinertia_وnp.bincount(kmeans.labels_) - 3الدفتر 2 مع
random_state=2: اطبع مصفوفة الالتباس (confusion matrix) وaccuracy_score
| المهمة | النتيجة |
|---|---|
| 1 | [1 4]: دخل مرتفع وإنفاق مرتفع، ثم دخل منخفض وإنفاق مرتفع |
| 2 | 75399.62، والأحجام [23 39 79 23 36] |
| 3 | [[74 138] [34 531]]، والدقة 0.7786: تغيرت الأسماء فقط |
الخلاصة
- 1يجد التجميع مجموعات في بيانات لا تسميات لها
- 2تكرر k-means الإسناد (أقرب مركز) والتحديث (المتوسط) حتى لا يتغير شيء
- 3يقيس WCSS (
inertia_) مدى التماسك، ولا تستطيع أي من الخطوتين رفعه - 4اختر k عند الكوع، لا عند أصغر قصور ذاتي
- 5تعتمد النتيجة على البداية: استخدم
n_init - 6أرقام العناقيد اعتباطية: اقرأ المراكز واختر أسماء الشرائح
افتح هذا الدرس
Mahmoud Abas|التجميع بخوارزمية k-Means