📖 الدرس السابع: التعلم غير الخاضع للإشراف
Clustering، PCA، وAnomalyDetection
📖
الدرس السابع
⏱️
90-120 دقيقة
🎓
متقدم
💻
مشروع شامل
🎯 أهداف الدرس
- فهم مفهوم التعلم غير الخاضع للإشراف وتطبيقاته العملية
- إتقان خوارزميات التجميع (Clustering) مثل K-Means وDBSCAN وHierarchical
- تعلم تقنيات تقليل الأبعاد (Dimensionality Reduction) باستخدام PCA وt-SNE
- تطبيق كشف الشذوذ (Anomaly Detection) للبيانات غير الطبيعية
- بناء مشروع عملي شامل: تحليل سلوك العملاء وتجميعهم
- فهم كيفية تقييم نتائج التعلم غير الخاضع للإشراف
🔍 1. مقدمة: ما هو التعلم غير الخاضع للإشراف؟
📊 حقائق مذهلة:
- 80% من بيانات العالم غير مُصنفة - هنا يأتي دور التعلم غير الخاضع للإشراف
- Netflix وSpotify وAmazon تستخدم التجميع لتوصية المحتوى
- البنوك تكشف 95% من عمليات الاحتيال باستخدام Anomaly Detection
- Google وFacebook يستخدمان PCA لضغط الصور وتسريع المعالجة
- تحليل الجينات الطبية يعتمد بشكل أساسي على التجميع
🎯 الفرق الأساسي:
| الخاصية | التعلم الخاضع للإشراف | التعلم غير الخاضع للإشراف |
|---|---|---|
| البيانات | مُصنفة مسبقاً (X, y) | غير مُصنفة (X فقط) |
| الهدف | التنبؤ بالنتائج | اكتشاف الأنماط |
| التقييم | دقة، F1-Score | Silhouette، Inertia |
| الاستخدام | التصنيف، الانحدار | التجميع، تقليل الأبعاد |
💡 نصيحة مهمة
🎯 2. خوارزميات التجميع (Clustering)
🔵 1. K-Means Clustering
الأكثر شيوعاً واستخداماً - يقسم البيانات إلى K مجموعات:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
import seaborn as sns
# إنشاء بيانات تجريبية لتحليل العملاء
np.random.seed(42)
n_customers = 1000
# بيانات العملاء: العمر، الراتب، نقاط الولاء
ages = np.random.normal(35, 12, n_customers)
salaries = np.random.normal(50000, 15000, n_customers)
loyalty_points = np.random.normal(500, 200, n_customers)
# دمج البيانات
customer_data = np.column_stack([ages, salaries, loyalty_points])
# تطبيق K-Means
kmeans = KMeans(n_clusters=4, random_state=42, n_init=10)
customer_clusters = kmeans.fit_predict(customer_data)
# عرض النتائج
print(f"مراكز المجموعات:")
for i, center in enumerate(kmeans.cluster_centers_):
print(f"المجموعة {i+1}: العمر={center[0]:.1f}, الراتب={center[1]:.0f}, النقاط={center[2]:.0f}")
# تصور النتائج
plt.figure(figsize=(12, 8))
colors = ['red', 'blue', 'green', 'orange']
for i in range(4):
cluster_data = customer_data[customer_clusters == i]
plt.scatter(cluster_data[:, 0], cluster_data[:, 1],
c=colors[i], label=f'المجموعة {i+1}', alpha=0.6)
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1],
c='black', marker='x', s=200, linewidths=3, label='المراكز')
plt.xlabel('العمر')
plt.ylabel('الراتب')
plt.title('تجميع العملاء باستخدام K-Means')
plt.legend()
plt.show()
# تحليل المجموعات
for i in range(4):
cluster_customers = customer_data[customer_clusters == i]
print(f"
المجموعة {i+1} ({len(cluster_customers)} عميل):")
print(f" متوسط العمر: {cluster_customers[:, 0].mean():.1f} سنة")
print(f" متوسط الراتب: {cluster_customers[:, 1].mean():.0f} ريال")
print(f" متوسط نقاط الولاء: {cluster_customers[:, 2].mean():.0f} نقطة")
🔍 2. DBSCAN - كشف المجموعات ذات الكثافة
ممتاز للبيانات التي تحتوي على ضوضاء وأشكال غير منتظمة:
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler
# تحضير البيانات (تطبيع مهم جداً لـ DBSCAN)
scaler = StandardScaler()
customer_data_scaled = scaler.fit_transform(customer_data)
# تطبيق DBSCAN
dbscan = DBSCAN(eps=0.5, min_samples=10)
dbscan_clusters = dbscan.fit_predict(customer_data_scaled)
# تحليل النتائج
n_clusters = len(set(dbscan_clusters)) - (1 if -1 in dbscan_clusters else 0)
n_noise = list(dbscan_clusters).count(-1)
print(f"عدد المجموعات المكتشفة: {n_clusters}")
print(f"عدد النقاط الشاذة: {n_noise}")
print(f"نسبة النقاط الشاذة: {n_noise/len(customer_data)*100:.1f}%")
# تصور النتائج
plt.figure(figsize=(12, 8))
unique_labels = set(dbscan_clusters)
colors = plt.cm.Spectral(np.linspace(0, 1, len(unique_labels)))
for k, col in zip(unique_labels, colors):
if k == -1:
# النقاط الشاذة باللون الأسود
class_member_mask = (dbscan_clusters == k)
xy = customer_data[class_member_mask]
plt.scatter(xy[:, 0], xy[:, 1], c='black', marker='x', s=50, label='شاذة')
else:
class_member_mask = (dbscan_clusters == k)
xy = customer_data[class_member_mask]
plt.scatter(xy[:, 0], xy[:, 1], c=[col], s=50, alpha=0.6, label=f'مجموعة {k}')
plt.xlabel('العمر')
plt.ylabel('الراتب')
plt.title('تجميع العملاء باستخدام DBSCAN')
plt.legend()
plt.show()
🌳 3. Hierarchical Clustering
from sklearn.cluster import AgglomerativeClustering
from scipy.cluster.hierarchy import dendrogram, linkage
import matplotlib.pyplot as plt
# تطبيق Hierarchical Clustering
hierarchical = AgglomerativeClustering(n_clusters=4, linkage='ward')
hierarchical_clusters = hierarchical.fit_predict(customer_data)
# إنشاء Dendrogram
plt.figure(figsize=(15, 8))
linkage_matrix = linkage(customer_data[:100], method='ward') # عينة صغيرة للوضوح
dendrogram(linkage_matrix, truncate_mode='level', p=5)
plt.title('Dendrogram للتجميع الهرمي')
plt.xlabel('فهرس العينة أو (حجم المجموعة)')
plt.ylabel('المسافة')
plt.show()
print(f"تم تجميع العملاء إلى {len(set(hierarchical_clusters))} مجموعات")
📉 3. تقليل الأبعاد (Dimensionality Reduction)
🎯 1. Principal Component Analysis (PCA)
الأكثر شيوعاً - يجد الاتجاهات الأكثر أهمية في البيانات:
from sklearn.decomposition import PCA
from sklearn.datasets import load_digits
import matplotlib.pyplot as plt
# تحميل بيانات الأرقام المكتوبة يدوياً (64 بُعد)
digits = load_digits()
X_digits = digits.data
y_digits = digits.target
print(f"الشكل الأصلي للبيانات: {X_digits.shape}")
print(f"كل صورة تحتوي على {X_digits.shape[1]} بكسل (8x8)")
# تطبيق PCA لتقليل الأبعاد من 64 إلى 2
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_digits)
print(f"الشكل بعد PCA: {X_pca.shape}")
print(f"نسبة التباين المحفوظة: {pca.explained_variance_ratio_.sum():.3f}")
print(f"المكون الأول يفسر: {pca.explained_variance_ratio_[0]:.3f} من التباين")
print(f"المكون الثاني يفسر: {pca.explained_variance_ratio_[1]:.3f} من التباين")
# تصور النتائج
plt.figure(figsize=(12, 8))
colors = plt.cm.tab10(np.linspace(0, 1, 10))
for i in range(10):
mask = y_digits == i
plt.scatter(X_pca[mask, 0], X_pca[mask, 1],
c=[colors[i]], label=f'الرقم {i}', alpha=0.6)
plt.xlabel(f'المكون الأول ({pca.explained_variance_ratio_[0]:.1%} من التباين)')
plt.ylabel(f'المكون الثاني ({pca.explained_variance_ratio_[1]:.1%} من التباين)')
plt.title('تصور الأرقام المكتوبة يدوياً باستخدام PCA')
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.show()
# تحليل أهمية المكونات
plt.figure(figsize=(10, 6))
cumsum_variance = np.cumsum(pca.explained_variance_ratio_)
plt.plot(range(1, len(cumsum_variance)+1), cumsum_variance, 'bo-')
plt.xlabel('عدد المكونات')
plt.ylabel('نسبة التباين المحفوظة التراكمية')
plt.title('أهمية المكونات في PCA')
plt.grid(True, alpha=0.3)
plt.show()
🎨 2. t-SNE للتصور المتقدم
from sklearn.manifold import TSNE
# تطبيق t-SNE (على عينة صغيرة لأنه بطيء)
sample_size = 1000
sample_indices = np.random.choice(len(X_digits), sample_size, replace=False)
X_sample = X_digits[sample_indices]
y_sample = y_digits[sample_indices]
# t-SNE يحتاج وقت أطول لكن نتائج أفضل للتصور
tsne = TSNE(n_components=2, random_state=42, perplexity=30)
X_tsne = tsne.fit_transform(X_sample)
# تصور النتائج
plt.figure(figsize=(12, 8))
for i in range(10):
mask = y_sample == i
plt.scatter(X_tsne[mask, 0], X_tsne[mask, 1],
c=[colors[i]], label=f'الرقم {i}', alpha=0.7)
plt.xlabel('t-SNE المكون الأول')
plt.ylabel('t-SNE المكون الثاني')
plt.title('تصور الأرقام المكتوبة يدوياً باستخدام t-SNE')
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.show()
🚨 4. كشف الشذوذ (Anomaly Detection)
🔍 1. Isolation Forest
from sklearn.ensemble import IsolationForest
import numpy as np
# إنشاء بيانات تحتوي على شذوذ
np.random.seed(42)
normal_data = np.random.normal(0, 1, (950, 2))
anomaly_data = np.random.uniform(-4, 4, (50, 2))
all_data = np.vstack([normal_data, anomaly_data])
# تطبيق Isolation Forest
iso_forest = IsolationForest(contamination=0.05, random_state=42)
anomaly_labels = iso_forest.fit_predict(all_data)
# تحليل النتائج
n_anomalies = (anomaly_labels == -1).sum()
print(f"عدد الشذوذات المكتشفة: {n_anomalies}")
print(f"نسبة الشذوذ: {n_anomalies/len(all_data)*100:.1f}%")
# تصور النتائج
plt.figure(figsize=(10, 8))
normal_mask = anomaly_labels == 1
anomaly_mask = anomaly_labels == -1
plt.scatter(all_data[normal_mask, 0], all_data[normal_mask, 1],
c='blue', alpha=0.6, label='بيانات طبيعية')
plt.scatter(all_data[anomaly_mask, 0], all_data[anomaly_mask, 1],
c='red', alpha=0.8, label='شذوذات', s=100, marker='x')
plt.xlabel('المتغير الأول')
plt.ylabel('المتغير الثاني')
plt.title('كشف الشذوذ باستخدام Isolation Forest')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
📊 2. One-Class SVM
from sklearn.svm import OneClassSVM
# تطبيق One-Class SVM
one_class_svm = OneClassSVM(nu=0.05, kernel='rbf', gamma='scale')
svm_labels = one_class_svm.fit_predict(all_data)
# مقارنة النتائج
svm_anomalies = (svm_labels == -1).sum()
print(f"Isolation Forest اكتشف: {n_anomalies} شذوذ")
print(f"One-Class SVM اكتشف: {svm_anomalies} شذوذ")
# حساب التطابق
agreement = (anomaly_labels == svm_labels).sum()
print(f"نسبة التطابق بين الطريقتين: {agreement/len(all_data)*100:.1f}%")
📊 5. مشروع عملي شامل: تحليل سلوك العملاء
الآن سنطبق كل ما تعلمناه في مشروع حقيقي لتحليل سلوك العملاء في متجر إلكتروني:
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
from sklearn.metrics import silhouette_score
import matplotlib.pyplot as plt
import seaborn as sns
# إنشاء بيانات عملاء واقعية
np.random.seed(42)
n_customers = 2000
# إنشاء بيانات متنوعة للعملاء
customer_data = {
'customer_id': range(1, n_customers + 1),
'age': np.random.normal(40, 15, n_customers).astype(int),
'annual_income': np.random.normal(60000, 20000, n_customers),
'spending_score': np.random.randint(1, 101, n_customers),
'purchase_frequency': np.random.poisson(12, n_customers),
'avg_order_value': np.random.normal(150, 50, n_customers),
'days_since_last_purchase': np.random.exponential(30, n_customers),
'total_purchases': np.random.poisson(25, n_customers),
'returns_count': np.random.poisson(2, n_customers),
'support_tickets': np.random.poisson(1, n_customers)
}
# تحويل إلى DataFrame
df = pd.DataFrame(customer_data)
# تنظيف البيانات
df['age'] = np.clip(df['age'], 18, 80)
df['annual_income'] = np.clip(df['annual_income'], 20000, 150000)
df['avg_order_value'] = np.clip(df['avg_order_value'], 10, 500)
print("📊 معلومات أساسية عن البيانات:")
print(df.describe())
# اختيار المتغيرات للتجميع
features = ['age', 'annual_income', 'spending_score', 'purchase_frequency',
'avg_order_value', 'days_since_last_purchase', 'total_purchases']
X = df[features].values
# تطبيع البيانات
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# إيجاد العدد الأمثل للمجموعات باستخدام Elbow Method
inertias = []
silhouette_scores = []
k_range = range(2, 11)
for k in k_range:
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
kmeans.fit(X_scaled)
inertias.append(kmeans.inertia_)
silhouette_scores.append(silhouette_score(X_scaled, kmeans.labels_))
# تصور Elbow Method
plt.figure(figsize=(15, 5))
plt.subplot(1, 3, 1)
plt.plot(k_range, inertias, 'bo-')
plt.xlabel('عدد المجموعات (K)')
plt.ylabel('Inertia')
plt.title('Elbow Method لإيجاد K الأمثل')
plt.grid(True, alpha=0.3)
plt.subplot(1, 3, 2)
plt.plot(k_range, silhouette_scores, 'ro-')
plt.xlabel('عدد المجموعات (K)')
plt.ylabel('Silhouette Score')
plt.title('Silhouette Score لكل K')
plt.grid(True, alpha=0.3)
# اختيار K=5 بناءً على النتائج
optimal_k = 5
kmeans_final = KMeans(n_clusters=optimal_k, random_state=42, n_init=10)
cluster_labels = kmeans_final.fit_predict(X_scaled)
# إضافة التصنيفات للبيانات الأصلية
df['cluster'] = cluster_labels
# تحليل المجموعات
print(f"
🎯 تحليل المجموعات (K={optimal_k}):")
for i in range(optimal_k):
cluster_data = df[df['cluster'] == i]
print(f"
📊 المجموعة {i+1} ({len(cluster_data)} عميل - {len(cluster_data)/len(df)*100:.1f}%):")
print(f" متوسط العمر: {cluster_data['age'].mean():.1f} سنة")
print(f" متوسط الدخل السنوي: {cluster_data['annual_income'].mean():.0f} ريال")
print(f" متوسط نقاط الإنفاق: {cluster_data['spending_score'].mean():.1f}")
print(f" متوسط تكرار الشراء: {cluster_data['purchase_frequency'].mean():.1f} مرة/شهر")
print(f" متوسط قيمة الطلب: {cluster_data['avg_order_value'].mean():.0f} ريال")
# تطبيق PCA للتصور
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)
plt.subplot(1, 3, 3)
colors = ['red', 'blue', 'green', 'orange', 'purple']
for i in range(optimal_k):
cluster_mask = cluster_labels == i
plt.scatter(X_pca[cluster_mask, 0], X_pca[cluster_mask, 1],
c=colors[i], label=f'مجموعة {i+1}', alpha=0.6)
plt.scatter(kmeans_final.cluster_centers_[:, 0], kmeans_final.cluster_centers_[:, 1],
c='black', marker='x', s=200, linewidths=3, label='المراكز')
plt.xlabel(f'المكون الأول ({pca.explained_variance_ratio_[0]:.1%})')
plt.ylabel(f'المكون الثاني ({pca.explained_variance_ratio_[1]:.1%})')
plt.title('تصور مجموعات العملاء')
plt.legend()
plt.tight_layout()
plt.show()
# إنشاء ملفات تعريف العملاء
cluster_profiles = {
0: "العملاء الشباب ذوو الدخل المتوسط",
1: "العملاء كبار السن ذوو الإنفاق العالي",
2: "العملاء متوسطو العمر والدخل",
3: "العملاء الشباب ذوو الإنفاق المنخفض",
4: "العملاء الأثرياء ذوو الإنفاق العالي"
}
print("
🏷️ ملفات تعريف العملاء:")
for i, profile in cluster_profiles.items():
count = (cluster_labels == i).sum()
percentage = count / len(df) * 100
print(f"المجموعة {i+1}: {profile} ({count} عميل - {percentage:.1f}%)")
💡 استراتيجيات التسويق المقترحة
- المجموعة 1: عروض للشباب، منتجات بأسعار معقولة
- المجموعة 2: منتجات فاخرة، خدمة VIP
- المجموعة 3: عروض متوازنة، برامج ولاء
- المجموعة 4: عروض ترويجية، خصومات جذابة
- المجموعة 5: منتجات حصرية، تجربة مميزة
💪 تمارين عملية
- تجميع متقدم: طبق DBSCAN على نفس بيانات العملاء وقارن النتائج مع K-Means. أي طريقة تعطي نتائج أفضل ولماذا؟
- تقليل الأبعاد: استخدم t-SNE لتصور بيانات العملاء وقارن النتائج مع PCA. ما الفروقات التي تلاحظها؟
- كشف الشذوذ: طبق Isolation Forest على بيانات العملاء لاكتشاف العملاء غير الطبيعيين. ما خصائص هؤلاء العملاء؟
📚 ملخص الدرس والخطوات التالية
✅ ما تعلمناه اليوم:
- التجميع: K-Means، DBSCAN، وHierarchical لتقسيم البيانات
- تقليل الأبعاد: PCA وt-SNE لتبسيط البيانات المعقدة
- كشف الشذوذ: Isolation Forest وOne-Class SVM للبيانات غير الطبيعية
- التطبيق العملي: مشروع شامل لتحليل سلوك العملاء
💡 أفضل الممارسات
- طبع البيانات دائماً قبل تطبيق خوارزميات التجميع
- استخدم Elbow Method وSilhouette Score لاختيار عدد المجموعات
- جرب عدة خوارزميات وقارن النتائج
- فسر النتائج في السياق التجاري وليس فقط تقنياً
➡️ الدرس القادم:
في الدرس الثامن سنتعلم "TensorFlow وKeras للتعلم العميق" حيث سنستكشف:
- مقدمة الشبكات العصبية والتعلم العميق
- بناء النماذج باستخدام TensorFlow وKeras
- الشبكات العصبية التطبيقية (CNNs) لمعالجة الصور
- مشروع عملي: تصنيف الصور باستخدام التعلم العميق