AI: التعلم غير الخاضع للإشراف

آخر تحديث: 2026-08-26

ماذا لو لم تكن بياناتك مُعلَّمة؟ عندما تواجه مجموعة كبيرة من سجلات سلوك المستخدمين، أو التسلسلات الجينية، أو بيانات المستشعرات - ولكنك تفتقر إلى "الإجابات الصحيحة" - يكون التعلم غير الخاضع للإشراف أداة قوية لاكتشاف الأنماط المخفية. يستكشف هذا الفصل نهجين رئيسيين - التجميع وتقليل الأبعاد - لمساعدتك على فهم المبادئ والتطبيقات العملية لخوارزمية K-Means وتحليل المكونات الرئيسية (PCA).

١. ماذا ستتعلم



2. القصة: 100,000 مستخدم—من سيساعد في تنظيمهم في مجموعات؟

(1) نقطة الألم: مع هذا الكم الهائل من المستخدمين، من الصعب أن تعرف من أين تبدأ

كان لدى فريق تسويق تشارلي 100,000 نقطة بيانات مستخدم — مبالغ الإنفاق، وتكرار الشراء، ومدة التسجيل، ووقت النشاط الأخير، والمزيد — لكن لم يكن أحد يعرف كيفية تقسيم المستخدمين إلى شرائح. بالاعتماد على الخبرة، قسم قسم التسويق المستخدمين إلى مجموعتين — "المستخدمون الجدد" و"المستخدمون الحاليون" — وأرسل لهم قسائم، لكن معدل التحويل كان 2.3% فقط. طالب الرئيس التنفيذي بزيادته إلى 5%، مما أ leaving الفريق في حيرة.

(2) نهج الذكاء الاصطناعي: استخدام التجميع للتعرف التلقائي على مجموعات المستخدمين

بعد تولي أليس المسؤولية، استخدمت خوارزمية K-Means لتجميع المستخدمين في أربع مجموعات:

معرف المجموعة الميزة النسبة المئوية الاسم
المجموعة 0 إنفاق عالٍ، تكرار منخفض 15% المشترون ذوو القيمة العالية
المجموعة 1 إنفاق منخفض، تكرار عالٍ 35% الصيادون النشطون للصفقات
المجموعة 2 إنفاق عالٍ، تكرار عالٍ 10% كبار العملاء الأساسيون
المجموعة 3 إنفاق منخفض، تكرار منخفض 40% المستخدمون غير النشطين

أرسلنا قسائم مختلفة لكل مجموعة: توصية المنتجات الجديدة للمشترين ذوي الإنفاق العالي، وإرسال قسائم خصم للصيادين النشطين للصفقات، وتقديم مزايا حصرية لكبار العملاء الأساسيين، وإرسال حزم إعادة التنشيط للمستخدمين غير النشطين. قفز معدل التحويل من 2.3% إلى 3.1% — أي زيادة بنسبة 35%.

(3) الفوائد: من "التخمين" إلى "الاعتماد على البيانات"

اكتشف تشارلي أن قوة التعلم غير الخاضع للإشراف لا تكمن في التنبؤ، بل في اكتشاف ما لم تكن تعلم بوجوده. حتى بدون تصنيفات أو معرفة مسبقة، يمكن للخوارزميات أن تكشف عن مجموعات ذات معنى في البيانات — وهذا هو قيمة التعلم غير الخاضع للإشراف.


3. التعلم غير المُشرف عليه مقابل التعلم المُشرف عليه

(1) الاختلافات الرئيسية

البُعد التعلم المُشرف عليه التعلم غير المُشرف عليه
بيانات التدريب مُعلَّمة (X → y) غير مُعلَّمة (X فقط)
الهدف التنبؤ بفئات/قيم معروفة اكتشاف البنية الأساسية للبيانات
المهام النموذجية التصنيف، الانحدار التجميع، تقليل الأبعاد، قواعد الارتباط
طرق التقييم الدقة، F1، RMSE، إلخ. معامل الكتلة، القصور الذاتي، التصور
التمثيل التوضيحي معلم يُعلم الطلاب التعرف على الحيوانات طفل يُفرّق ألعابه حسب اللون بنفسه
الخوارزميات التمثيلية أشجار القرار، SVM، الانحدار الخطي K-Means، PCA، DBSCAN

(2) لماذا نحتاج إلى التعلم غير المُشرف عليه؟



4. التجميع باستخدام خوارزمية K-Means

(1) ما هو التجميع؟

التجميع هو عملية تجميع نقاط البيانات المتشابهة معًا ووضع النقاط المختلفة في مجموعات منفصلة. السؤال الجوهري هو: ما معنى "متشابه"؟ - يُقاس ذلك عادةً باستخدام مقياس للمسافة، الشائع منها هو المسافة الإقليدية.

(2) مخطط سير خوارزمية K-Means

خوارزمية K-Means هي أكثر خوارزميات التجميع كلاسيكية وعملية. فكرتها الأساسية هي: تقسيم البيانات إلى k مجموعات (عناقيد) بحيث يكون مجموع المسافات من كل نقطة بيانات إلى مركز مجموعتها مُصغَّرًا.

100%
flowchart TD
    A[Initialize k centroids randomly] --> B[Assign each point to nearest centroid]
    B --> C[Recalculate centroids as mean of assigned points]
    C --> D{Centroids changed?}
    D -- Yes --> B
    D -- No --> E[Converged! Output clusters]
    
    style A fill:#e1f5fe
    style E fill:#e8f5e9
    style D fill:#fff3e0

خطوات الخوارزمية:

  1. التهيئة: اختيار k نقاط عشوائيًا كمراكز بدائية (centroids).
  2. التعيين: تعيين كل نقطة بيانات إلى المجموعة التي يقع مركزها الأقرب إليها.
  3. التحديث: إعادة حساب مركز الكتلة (centroid) لكل مجموعة (عن طريق أخذ المتوسط الحسابي لجميع النقاط داخل المجموعة).
  4. التكرار: تكرار الخطوتين 2-3 حتى لا يتغير مركز الكتلة anymore أو يتم الوصول إلى الحد الأقصى لعدد التكرارات.

▶ مثال: تجميع بيانات العملاء باستخدام K-Means (الصعوبة: ⭐)

PYTHON
from sklearn.cluster import KMeans
import numpy as np

np.random.seed(42)

group_a = np.random.normal(loc=[20, 80], scale=5, size=(30, 2))
group_b = np.random.normal(loc=[80, 20], scale=5, size=(30, 2))
group_c = np.random.normal(loc=[50, 50], scale=5, size=(30, 2))
X = np.vstack([group_a, group_b, group_c])

kmeans = KMeans(n_clusters=3, random_state=42, n_init=10)
kmeans.fit(X)

print(f"Cluster centers:\n{kmeans.cluster_centers_}")
print(f"Inertia (sum of squared distances): {kmeans.inertia_:.2f}")
print(f"First 10 labels: {kmeans.labels_[:10]}")
💻 الناتج:

TEXT 📖 للعرض فقط
Cluster centers:
[[50.14 49.60]
 [20.38 79.63]
 [80.27 19.44]]
Inertia (sum of squared distances): 1310.56
First 10 labels: [1 1 1 1 1 1 1 1 1 1]

(3) مقارنة بين ثلاثة خوارزميات تجميع

البُعد K-Means التجميع الهرمي (Hierarchical) DBSCAN
يتطلب تحديد k نعم لا لا (يتطلب تحديد eps/min_samples)
شكل المجموعة كروي أي شكل أي شكل
معالجة الضوضاء ضعيف مقبول جيد (يُحدد كنقاط ضوضاء)
التعقيد الزمني O(nkt) O(n²) ~ O(n³) O(n log n)
القابلية للتوسع جيد لمجموعات البيانات الكبيرة بطيء مع مجموعات البيانات الكبيرة متوسط
التطبيقات تقسيم العملاء، ضغط الصور مجموعات البيانات الصغيرة، الهيكل الشجري كشف الشذوذ، البيانات المكانية


5. كيفية اختيار قيمة k

المشكلة الأكبر في K-Means: يجب تحديد k مسبقًا. إذا اخترت k خاطئة، فإن نتائج التجميع ستكون بلا معنى. إليك طريقتين شائعتين لمساعدتك في العثور على القيمة المثلى لـ k.

(1) طريقة المرفق (Elbow Method)

ارسم منحنى الزخم (أي مجموع المسافات التربيعية داخل المجموعات) المقابل لقيم مختلفة لـ k، وقيمة k عند "نقطة الانحناء"—مثل مرفق الذراع—بعد ذلك يقل فائدة زيادة k.

▶ مثال: رسم قاعدة الإبهام—اختيار k (الصعوبة ⭐)

PYTHON
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
import numpy as np

np.random.seed(42)
X = np.vstack([
    np.random.normal(loc=[20, 80], scale=5, size=(50, 2)),
    np.random.normal(loc=[80, 20], scale=5, size=(50, 2)),
    np.random.normal(loc=[50, 50], scale=5, size=(50, 2)),
    np.random.normal(loc=[80, 80], scale=5, size=(50, 2)),
])

inertias = []
K_range = range(1, 11)
for k in K_range:
    km = KMeans(n_clusters=k, random_state=42, n_init=10)
    km.fit(X)
    inertias.append(km.inertia_)

plt.figure(figsize=(8, 5))
plt.plot(K_range, inertias, 'bo-', linewidth=2, markersize=8)
plt.xlabel('Number of clusters (k)')
plt.ylabel('Inertia')
plt.title('Elbow Method for Optimal k')
plt.axvline(x=4, color='red', linestyle='--', label='Elbow at k=4')
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('elbow_method.png', dpi=150)
plt.show()

المخرجات: (قم بتشغيل المثال لرؤية المخرجات الفعلية، أو راجع ملاحظة المخرجات المتوقعة في تعليقات الكود أعلاه.)

💡 نصية: تبحث قاعدة المرفق عن "نقطة الانحناء" في انخفاض الزخم. بعد k=4، يتباطأ انخفاض الزخم بشكل ملحوظ، مما يشير إلى أن أربعة مجموعات هي معقولة.

(2) معامل السيلويت (Silhouette Score)

يقيس معامل السيلويت تشابه كل نقطة مع مجموعتها الخاصة مقارنة بتشابهها مع أقرب المجموعات الأخرى؛ تتراوح قيمته من [-1, 1]، حيث تكون القيم الأعلى أفضل.

▶ مثال: اختيار k باستخدام درجة السيلويت (الصعوبة ⭐⭐)

PYTHON
from sklearn.metrics import silhouette_score
from sklearn.cluster import KMeans
import numpy as np

np.random.seed(42)
X = np.vstack([
    np.random.normal(loc=[20, 80], scale=5, size=(50, 2)),
    np.random.normal(loc=[80, 20], scale=5, size=(50, 2)),
    np.random.normal(loc=[50, 50], scale=5, size=(50, 2)),
    np.random.normal(loc=[80, 80], scale=5, size=(50, 2)),
])

print("k | Silhouette Score")
print("--|------------------")
for k in range(2, 8):
    km = KMeans(n_clusters=k, random_state=42, n_init=10)
    labels = km.fit_predict(X)
    score = silhouette_score(X, labels)
    print(f"{k} | {score:.4f}")
💻 المخرجات:

TEXT 📖 للعرض فقط
k | Silhouette Score
--|------------------
2 | 0.5812
3 | 0.6234
4 | 0.6891
5 | 0.5543
6 | 0.4672
7 | 0.3891
💡 نصية: تكون درجة السيلويت هي الأعلى عندما k=4، وهو ما يتوافق مع نتائج قاعدة الإبهام. التحقق المتبادل من الطريقتين يسفر عن نتائج أكثر موثوقية.

(3) مقارنة طرق تقييم التجميع

الطريقة ماذا تقيس نطاق القيم المميزات العيوب
الزخم (Inertia) كثافة داخل المجموعة ≥0؛ كلما كان أصغر، كان أفضل حساب سريع؛ مدمج في K-Means يتناقص بشكل أحادي مع زيادة k؛ لا يمكن استخدامه وحده
معامل السيلويت التماسك + التشتت [-1, 1]، كلما كان أعلى، كان أفضل يسمح بمقارنة قيم k المختلفة حساب بطيء، O(n²)
كالينسكي-هاراباز (Calinski-Harabasz) نسبة التباين بين المجموعات/داخل المجموعات ≥0؛ كلما كان أعلى، كان أفضل حساب سريع يفضل المجموعات المحدبة
ديفيز-بولدين (Davies-Bouldin) نسبة التباين داخل المجموعة / المسافة بين المجموعات ≥0؛ كلما كان أصغر، كان أفضل بديهي يفضل المجموعات المحدبة


6. تقليل الأبعاد باستخدام PCA

(1) لماذا يلزم تقليل الأبعاد؟

(2) PCA: شرح بديهي

الفكرة الأساسية لـ PCA (تحليل المكونات الرئيسية) هي تحديد الاتجاهات ذات التباين الأكبر في البيانات وتقديم البيانات عليها. التباين الأكبر يعني معلومات أكثر، والهدف هو الحفاظ على أكبر قدر ممكن من المعلومات الأصلية بعد التقديم.

تخيل مجموعة من النقاط ثلاثية الأبعاد مرتبة في شكل "كروي مسطح" - يقوم PCA بتحديد المحور الأطول (الأكثر تبايناً) ويقدم البيانات على ذلك المحور، محولاً الأبعاد الثلاثة إلى بُعد واحد مع تقليل فقدان المعلومات إلى أدنى حد.

▶ مثال: تقليل الأبعاد إلى 2D باستخدام PCA وتصور النتائج (الصعوبة: ⭐⭐)

PYTHON
from sklearn.decomposition import PCA
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
import numpy as np

iris = load_iris()
X = iris.data
y = iris.target

pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)

print(f"Original shape: {X.shape}")
print(f"After PCA:      {X_pca.shape}")
print(f"Explained variance ratio: {pca.explained_variance_ratio_}")
print(f"Total variance explained: {pca.explained_variance_ratio_.sum():.4f}")

plt.figure(figsize=(8, 6))
for target, color, label in zip([0, 1, 2], ['red', 'blue', 'green'], iris.target_names):
    plt.scatter(X_pca[y == target, 0], X_pca[y == target, 1],
                c=color, label=label, alpha=0.7, edgecolors='k', s=60)
plt.xlabel(f'PC1 ({pca.explained_variance_ratio_[0]:.1%} variance)')
plt.ylabel(f'PC2 ({pca.explained_variance_ratio_[1]:.1%} variance)')
plt.title('PCA: Iris Dataset Reduced to 2D')
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('pca_iris.png', dpi=150)
plt.show()
💻 الإخراج:

TEXT 📖 للعرض فقط
Original shape: (150, 4)
After PCA:      (150, 2)
Explained variance ratio: [0.9246 0.0530]
Total variance explained: 0.9776
💡 نصيحة: تقليل 4 أبعاد إلى 2 لا يزال يحافظ على 97.8% من المعلومات! المكونان الرئيسيان يرويان "معظم القصة".

(3) مقارنة بين طرق تقليل الأبعاد

الطريقة النوع المفهوم الأساسي يحافظ على البنية العامة يحافظ على البنية المحلية قابلية التفسير السيناريوهات القابلة للتطبيق
PCA خطي اتجاه التباين الأقصى جيد ضعيف عالية (أوزان الميزات قابلة للتفسير) تقليل الأبعاد السريع، تقليل الضوضاء
t-SNE غير خطي الحفاظ على احتمالية المجاورة ضعيف جيد منخفضة التصور (2D/3D)
UMAP غير خطي الحفاظ على البنية الطوبولوجية مقبول جيد منخفضة التصور، البيانات الضخمة
Autoencoder غير خطي ضغط بالشبكات العصبية يدرك البنية يدرك البنية متوسطة تقليل أبعاد الصور/النصوص


7. مقدمة في تصور t-SNE

تُعد PCA طريقة تقليل أبعاد خطية تتفوق في الحفاظ على البنية العامة ولكنها تميل إلى "تسطيح" العلاقات غير الخطية. تم تصميم t-SNE (التضمين الجار العشوائي الموزع t) خصيصًا للتصور ويتفوق في الحفاظ على بنى الحيويات المحلية - حيث تظل النقاط المتشابهة قريبة من بعضها البعض في الفضاء ثنائي الأبعاد.

▶ مثال: تصور البيانات عالية الأبعاد باستخدام t-SNE (الصعوبة: ⭐⭐)

PYTHON
from sklearn.manifold import TSNE
from sklearn.datasets import load_digits
import matplotlib.pyplot as plt
import numpy as np

digits = load_digits()
X = digits.data
y = digits.target

print(f"Original shape: {X.shape}")  # 64-dimensional handwritten digits

tsne = TSNE(n_components=2, random_state=42, perplexity=30)
X_tsne = tsne.fit_transform(X)

plt.figure(figsize=(10, 8))
scatter = plt.scatter(X_tsne[:, 0], X_tsne[:, 1], c=y, cmap='tab10',
                      alpha=0.7, edgecolors='k', s=30)
plt.colorbar(scatter, label='Digit Class')
plt.title('t-SNE: 64D Handwritten Digits → 2D')
plt.xlabel('t-SNE Dimension 1')
plt.ylabel('t-SNE Dimension 2')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('tsne_digits.png', dpi=150)
plt.show()

المخرجات: (قم بتشغيل المثال لرؤية المخرجات الفعلية، أو راجع ملاحظة المخرجات المتوقعة في تعليقات الكود أعلاه.)

⚠️ ملاحظة: t-SNE مناسب فقط للتصور ويجب ألا يُستخدم كخطوة معالجة مسبقة للنماذج اللاحقة. كما أنه غير قابل للتكرار (تختلف النتائج بين التشغيلات)، ولا يحافظ على المسافات العامة، وبطيء حسابيًا (O(n²)). استخدم PCA أو UMAP لتقليل الأبعاد في بيئات الإنتاج.



8. التطبيقات العملية للتجميع وتقليل الأبعاد

(1) تقسيم العملاء

تستخدم قطاعات التجارة الإلكترونية والمالية والألعاب التجميع لتقسيم المستخدمين إلى مجموعات مختلفة وتطوير استراتيجيات متميزة:

الصناعة سمات التجميع نتائج التجميع الإجراءات التجارية
التجارة الإلكترونية حجم الإنفاق، التردد، وتفضيلات الفئات عملاء عالي/منخفض القيمة/معرضون لخطر التخلي قسائم مخصصة
المالية الدخل، الالتزامات، سجل الائتمان منخفض/متوسط/عالي المخاطر أسعار فائدة متدرجة
الألعاب وقت اللعب، المدفوعات، النشاط الاجتماعي الحيتان/الدلافين/المستعملون المجانيون عمليات تمييزية

(2) ضغط الصور

يمكن استخدام خوارزمية K-Means لتكميم ألوان الصور - حيث يتم تجميع ملايين الألوان في k فئات، مما يقلل بشكل كبير حجم الملف.

(3) اكتشاف الشذوذ

النقاط التي لا تنتمي إلى أي مجموعة قد تكون قيماً شاذة. النقاط التي تشير إليها DBSCAN كضوضاء، والنقاط البعيدة عن مراكز المجموعات تستحق الاهتمام.

(4) هندسة الميزات

يمكن استخدام المكونات الرئيسية المستخلصة من PCA كميزات جديدة لإدخالها في نماذج التعلم الخاضع للإشراف، مما يزيل الضوضاء ويقلل الارتباط المتعدد بين المتغيرات ويسرّع عملية التدريب.


9. مقارنة نتائج التجميع مع التسميات الأصلية

أحيانًا قد تملك تسميات، لكنك تريد معرفة ما إذا كان التجميع غير المُعلَّم قادرًا على "اكتشاف" هذه الفئات بنفسه — هذه طريقة ممتازة لاختبار جودة التجميع.

▶ مثال: مقارنة نتائج التجميع مع التسميات الأصلية (الصعوبة: ⭐⭐)

PYTHON
from sklearn.cluster import KMeans
from sklearn.datasets import load_iris
from sklearn.metrics import confusion_matrix, accuracy_score
from scipy.stats import mode
import numpy as np

iris = load_iris()
X = iris.data
y_true = iris.target

kmeans = KMeans(n_clusters=3, random_state=42, n_init=10)
y_pred = kmeans.fit_predict(X)

# Cluster labels are arbitrary, so we align them with true labels
aligned_pred = np.zeros_like(y_pred)
for i in range(3):
    mask = y_pred == i
    aligned_pred[mask] = mode(y_true[mask], keepdims=True).mode[0]

print("Confusion Matrix (cluster vs true label):")
print(confusion_matrix(y_true, aligned_pred))
print(f"\nAligned accuracy: {accuracy_score(y_true, aligned_pred):.4f}")
💻 الناتج:

TEXT 📖 للعرض فقط
Confusion Matrix (cluster vs true label):
[[50  0  0]
 [ 0 48  2]
 [ 0 14 36]]

Aligned accuracy: 0.8933
💡 نصيحة: حقق التجميع غير المُعلَّم تلقائيًا دقة في التصنيف قدرها 89.3% دون معرفة التسميات! يشير هذا إلى أن الأصناف الثلاثة للسوسن (Iris) تمتلك بالفعل بنية تجميع متميزة في فضاء الميزات.



10. قيود التعلم بدون إشراف

القيود الوصف
لا ضمان للنتائج بدون تسميات (تسميات)، من المستحيل تحديد ما إذا كان شيء "صحيحًا" أو "خاطئًا"; يعتمد المرء فقط على حكم العمل
اختيار k ذاتي قد لا تكون نقطة الانعطاف لـ "قاعدة المرفق" واضحة، وقد تؤدي طرق مختلفة إلى استنتاجات مختلفة
حساسية للتهيئة الأولية قد تؤدي مراكز التجمع الأولية المختلفة في K-Means إلى نتائج مختلفة (يتطلب n_init > 1)
يمكنه فقط اكتشاف التجمعات المحدبة يفترض K-Means أن التجمعات كروية؛ تتطلب البيانات ذات الشكل الحلقي أو الهلالي DBSCAN
يؤدي تقليل الأبعاد إلى فقدان المعلومات يتخلص PCA من الأبعاد ذات التباين المنخفض، مما قد يؤدي إلى فقدان فروق دقيقة مهمة
تحديات في التقييم لا توجد "إجابة معيارية"; يعتمد التقييم على المعرفة بالمجال والتصور المرئي


11. مثال شامل: تقسيم العملاء باستخدام مجموعة بيانات "عميل المول"

▶ مثال: العملية الكاملة لتقسيم العملاء المدفوع بالبيانات (الصعوبة: ⭐⭐⭐)

PYTHON
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import silhouette_score

# ============================================
# الخطوة 1: تحميل واستكشاف مجموعة بيانات عميل المول
# ============================================
np.random.seed(42)
n = 200
data = {
    'CustomerID': range(1, n + 1),
    'Gender': np.random.choice(['Male', 'Female'], n),
    'Age': np.random.randint(18, 70, n),
    'Annual_Income_kUSD': np.random.randint(15, 137, n),
    'Spending_Score': np.random.randint(1, 100, n),
}
df = pd.DataFrame(data)

# حقن هيكل مجموعات واقعي
df.loc[:49, 'Annual_Income_kUSD'] = np.random.randint(15, 40, 50)
df.loc[:49, 'Spending_Score'] = np.random.randint(60, 100, 50)
df.loc[50:99, 'Annual_Income_kUSD'] = np.random.randint(70, 137, 50)
df.loc[50:99, 'Spending_Score'] = np.random.randint(60, 100, 50)
df.loc[100:149, 'Annual_Income_kUSD'] = np.random.randint(70, 137, 50)
df.loc[100:149, 'Spending_Score'] = np.random.randint(1, 40, 50)
df.loc[150:, 'Annual_Income_kUSD'] = np.random.randint(15, 40, 50)
df.loc[150:, 'Spending_Score'] = np.random.randint(1, 40, 50)

print("شكل مجموعة البيانات:", df.shape)
print(df.head(10))
print("\nالإحصاءات الوصفية:")
print(df[['Age', 'Annual_Income_kUSD', 'Spending_Score']].describe())

# ============================================
# الخطوة 2: اختيار الميزات والقياس
# ============================================
features = ['Age', 'Annual_Income_kUSD', 'Spending_Score']
X = df[features].values

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# ============================================
# الخطوة 3: طريقة المرفق للعثور على k الأمثل
# ============================================
inertias = []
silhouette_scores = []
K_range = range(2, 11)

for k in K_range:
    km = KMeans(n_clusters=k, random_state=42, n_init=10)
    labels = km.fit_predict(X_scaled)
    inertias.append(km.inertia_)
    silhouette_scores.append(silhouette_score(X_scaled, labels))

fig, axes = plt.subplots(1, 2, figsize=(14, 5))

axes[0].plot(K_range, inertias, 'bo-', linewidth=2)
axes[0].set_xlabel('عدد المجموعات (k)')
axes[0].set_ylabel('القصور الذاتي')
axes[0].set_title('طريقة المرفق')
axes[0].axvline(x=4, color='red', linestyle='--', label='المرفق عند k=4')
axes[0].legend()
axes[0].grid(True, alpha=0.3)

axes[1].plot(K_range, silhouette_scores, 'go-', linewidth=2)
axes[1].set_xlabel('عدد المجموعات (k)')
axes[1].set_ylabel('درجة التظليل')
axes[1].set_title('طريقة التظليل')
axes[1].axvline(x=4, color='red', linestyle='--', label='الأفضل عند k=4')
axes[1].legend()
axes[1].grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('mall_elbow_silhouette.png', dpi=150)
plt.show()

# ============================================
# الخطوة 4: التجميع النهائي مع k=4
# ============================================
kmeans = KMeans(n_clusters=4, random_state=42, n_init=10)
df['Cluster'] = kmeans.fit_predict(X_scaled)

# ============================================
# الخطوة 5: تحليل كل مجموعة
# ============================================
cluster_summary = df.groupby('Cluster')[features].mean()
print("\nملفات المجموعات (القيم المتوسطة):")
print(cluster_summary)

cluster_counts = df['Cluster'].value_counts().sort_index()
print("\nأحجام المجموعات:")
print(cluster_counts)

# ============================================
# الخطوة 6: PCA للتصور ثنائي الأبعاد
# ============================================
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)

plt.figure(figsize=(10, 7))
colors = ['red', 'blue', 'green', 'orange']
labels_text = [
    'المجموعة 0: صغار السن وعاليو الإنفاق',
    'المجموعة 1: الأثرياء وعاليو الإنفاق',
    'المجموعة 2: الأثرياء و المنخفضو الإنفاق',
    'المجموعة 3: ذوو الميزانية المنخفضة و المنخفضو الإنفاق',
]

for i in range(4):
    mask = df['Cluster'] == i
    plt.scatter(X_pca[mask, 0], X_pca[mask, 1],
                c=colors[i], label=labels_text[i],
                alpha=0.6, edgecolors='k', s=50)

centroids_pca = pca.transform(kmeans.cluster_centers_)
plt.scatter(centroids_pca[:, 0], centroids_pca[:, 1],
            c='black', marker='X', s=200, label='مراكز التجمع')

plt.xlabel(f'المكون الرئيسي 1 ({pca.explained_variance_ratio_[0]:.1%})')
plt.ylabel(f'المكون الرئيسي 2 ({pca.explained_variance_ratio_[1]:.1%})')
plt.title('تقسيم عملاء المول (K-Means + PCA)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('mall_clusters_pca.png', dpi=150)
plt.show()

# ============================================
# الخطوة 7: التوصيات التجارية
# ============================================
print("\n=== التوصيات التجارية ===")
for i in range(4):
    row = cluster_summary.loc[i]
    count = cluster_counts[i]
    print(f"\nالمجموعة {i} ({count} عملاء):")
    print(f"  متوسط العمر: {row['Age']:.0f}، الدخل: ${row['Annual_Income_kUSD']:.0f} ألف، الإنفاق: {row['Spending_Score']:.0f}/100")
💻 الإخراج:

TEXT 📖 للعرض فقط
شكل مجموعة البيانات: (200, 5)
   CustomerID  Gender  Age  Annual_Income_kUSD  Spending_Score
0           1  Female   56                  28              86
1           2    Male   25                  32              79
2           3  Female   38                  22              93
3           4  Female   36                  37              74
4           5    Male   47                  33              68
5           6  Female   32                  27              82
6           7  Female   51                  18              88
7           8    Male   19                  38              95
8           9    Male   23                  25              71
9          10  Female   27                  39              91

الإحصاءات الوصفية:
              Age  Annual_Income_kUSD  Spending_Score
count  200.000000          200.000000      200.000000
mean    43.475000           60.720000       50.115000
std     15.441418           41.082376       31.494432
min     18.000000           15.000000         1.000000
max     69.000000          136.000000        99.000000

ملفات المجموعات (القيم المتوسطة):
             Age  Annual_Income_kUSD  Spending_Score
Cluster                                           
0        41.34           26.82           80.44
1        43.88           99.24           78.32
2        44.92          101.58           19.44
3        43.36           26.24           21.12

أحجام المجموعات:
0    50
1    50
2    50
3    50
Name: Cluster, dtype: int64

=== التوصيات التجارية ===

المجموعة 0 (50 عميل):
  متوسط العمر: 41، الدخل: $27 ألف، الإنفاق: 80/100

المجموعة 1 (50 عميل):
  متوسط العمر: 44، الدخل: $99 ألف، الإنفاق: 78/100

المجموعة 2 (50 عميل):
  متوسط العمر: 45، الدخل: $102 ألف، الإنفاق: 19/100

المجموعة 3 (50 عميل):
  متوسط العمر: 43، الدخل: $26 ألف، الإنفاق: 21/100

❓ أسئلة شائعة

س كيف يتم تقييم جودة نتائج التجميع؟
ج عندما لا تتوفر تسميات، استخدم المقاييس الداخلية: درجة الكتلة الظلية ([-1,1]، حيث الأعلى هو الأفضل)،مؤشر كالينسكي-هاراباز (حيث الأعلى هو الأفضل)، ومؤشر ديفيز-بولدان (حيث الأقل هو الأفضل). عندما تكون التسميات متوفرة، قارن النتائج مع التسميات الحقيقية (احسب الدقة بعد المحاذاة). الطريقة الأكثر موثوقية هي التحقق من صحة العمل—تأكد مما إذا كانت نتائج الت궈يع تتوافق مع الحدس التجاري ويمكن تنفيذها عمليًا.
س كيف يتم اختيار قيمة k للـ K-Means؟
ج أولاً، استخدم "قاعدة المرفق" لتحديد نقطة الانعطاف في مخطط القصور الذاتي، ثم قم بالتحقق من صحة النتائج باستخدام درجة الكتلة الظلية. إذا أنتجت الطريقتان نتائج متسقة، يمكنك استخدام تلك القيمة بثقة؛ إذا لم تكن كذلك، فضل الاحتياجات التجارية—it’s easier to develop差异化 strategies for 4 clusters than for 8. k ليست مسألة رياضية؛ إنها مسألة تجارية.
س هل تقليل الأبعاد باستخدام PCA يؤدي إلى فقدان المعلومات؟
ج نعم، ولكن المعلومات "المفقودة" ليست بالضرورة سيئة. يقوم PCA بفرز الأبعاد حسب التباين من الأعلى إلى الأقل؛ التخلص من الأبعاد ذات التباين المنخفض يعادل التخلص من الضوضاء. المفتاح هو مقدار التباين المحتفظ به—عادة، يكفي الاحتفاظ بنسبة 85% أو أكثر. استخدم pca.explained_variance_ratio_ لعرض مساهمة كل مكوون رئيسي، ثم قرر كم عدد المكونات التي تريد الاحتفاظ بها.
س ما هي التطبيقات العملية للتعلم غير الخاضع للإشراف؟
ج خمسة سيناريوهات نموذجية: ① تقسيم العملاء (التسويق الشخصي) ② كشف الشذوذ (كشف الاحتيال) ③ تقليل الأبعاد (هندسة الميزات) ④ ضغط الصور (كمون الألوان) ⑤ البدء البارد في أنظمة التوصية (التجميع أولاً عند عدم توفر بيانات سلوكية). في جوهره، هو "تحليل استكشافي"—أولاً فحص كيف يبدو البيانات، ثم قرر ماذا تفعل بها.
س أيهما أصعب، التجميع أم التصنيف؟
ج التجميع أصعب لأنه لا يوجد "إجابة صحيحة." التصنيف له تسميات، لذا يمكنك قياس الدقة لتحديد الأداء؛ التجميع ليس له تسميات،因此 يعتمد التقييم على المقاييس الداخلية وحكم العمل. علاوة على ذلك، فإن K-Means حساس لتهيئة البداية، واختيار k ذاتي، وهو مناسب فقط للتجمعات محدبة التصميم. التصنيف مثل "اختبار بإجابة معيارية"، بينما التجميع مثل "سؤال مفتوح بدون إجابة معيارية."

📖 ملخص


📝 تمارين

  1. مشكلة أساسية (الصعوبة ⭐): استخدم sklearn.datasets.make_blobs لإنشاء 3 مجموعات من البيانات، قم بإجراء تجميع K-Means، ثم ارسم مخططًا مبعثرًا (باستخدام ألوان مختلفة لكل مجموعة ووضع علامات على مراكز المجموعات).

  2. مشكلة متقدمة (الصعوبة ⭐⭐): ارسم مخطط Rule of Thumbs ومخطط Silhouette score للبيانات أعلاه لتحديد القيمة المثلى لـ k. ثم، قم بتجميع البيانات عمدًا باستخدام k=2 و k=8 على التوالي، قارن بين النتائج، واشرح لماذا يؤدي اختيار القيمة الخاطئة لـ k إلى نتائج أسوأ.

  3. تحدي (الصعوبة: ⭐⭐⭐): قم بتحميل مجموعة بيانات الأرقام المكتوبة بخط اليد (أبعاد 64) باستخدام sklearn.datasets.load_digits. أولاً، استخدم PCA لتقليلها إلى تصور ثنائي الأبعاد، ثم استخدم t-SNE لتقليلها إلى تصور ثنائي الأبعاد، وقارن بين نتائج الطريقتين. اكتب تحليلًا: ما هي السمات الهيكلية التي يحافظ عليها PCA و t-SNE على التوالي؟ أيهما أكثر ملاءمة لتصور هذه المجموعة من البيانات؟

Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%