📖 الدرس السابع: التعلم غير الخاضع للإشراف
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) لمعالجة الصور
- مشروع عملي: تصنيف الصور باستخدام التعلم العميق