هناك قول مأثور في التعلم الآلي: القمامة تدخل، القمامة تخرج. من الممكن أن يكون لديك أكثر الخوارزميات تعقيدًا في العالم، ولكن إذا قمت بتغذيتها ببيانات سيئة الإعداد، فستكون النتائج سيئة. على العكس من ذلك، يمكن لخوارزمية بسيطة توفر بيانات ممتازة ومعدة بعناية أن تتفوق على خوارزمية معقدة بالنظر إلى بيانات أولية وفوضوية.
هندسة الميزات هي حرفة تحويل البيانات الأولية إلى تمثيلات يمكن لخوارزميات التعلم الآلي التعلم منها بشكل فعال. يمكن القول إنها المهارة الوحيدة الأكثر تأثيرًا في التعلم الآلي التطبيقي - وهي المكان الذي تلتقي فيه المعرفة العميقة بالمجال مع علم البيانات.
في التعلم الآلي، الميزة هي أي خاصية أو سمة قابلة للقياس للشيء الذي تحاول التنبؤ به. الميزات هي المدخلات إلى النموذج الخاص بك؛ التسمية (أو الهدف) هو الإخراج.
نموذج التنبؤ بأسعار المنازل:
بالنسبة لمصنف البريد الإلكتروني العشوائي:
غالبًا ما تكون جودة الميزات وكميتها وأهميتها أكثر أهمية من الخوارزمية التي تختارها.
بيانات العالم الحقيقي فوضوية. تمتلك خوارزميات التعلم الآلي متطلبات محددة لا تلبيها البيانات الأولية أبدًا:
هندسة الميزات هي عملية سد الفجوة بين البيانات الأولية والمدخلات الجاهزة للنموذج.
عندما يكون للميزات مقاييس مختلفة جدًا، يمكن تضليل النماذج. يمكن للمعلم ذو القيم بالآلاف أن يهيمن على المعالم ذات القيم بين 0 و1.
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
X_scaled = scaler.fit_transform(X_train)
# Before: age=[22, 65, 34], income=[18000, 95000, 42000]
# After: age=[0.0, 1.0, 0.27], income=[0.0, 1.0, 0.31]
تسجيل الدخول للانضمام إلى النقاش
أكثر قوة بالنسبة للقيم المتطرفة من القياس الأدنى والأقصى:
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X_train)
# Transforms each feature to have mean=0, standard deviation=1
# Feature value → (value - mean) / std_dev
القاعدة الأساسية: استخدم التقييس بشكل افتراضي. استخدم min-max عندما تحتاج إلى قيم في نطاق محدد محدد (على سبيل المثال، مدخلات الشبكة العصبية).
فئات مثل "أحمر/أخضر/أزرق" أو "لندن/مانشستر/برمنغهام" ليس لها ترتيب رقمي طبيعي. تحتاج إلى تشفيرها قبل إطعامها لمعظم الخوارزميات.
إنشاء عمود ثنائي لكل فئة. الأفضل عندما لا يكون للفئات ترتيب متأصل:
import pandas as pd
# Original: colour = ['red', 'green', 'blue', 'red']
df = pd.DataFrame({'colour': ['red', 'green', 'blue', 'red']})
encoded = pd.get_dummies(df['colour'], prefix='colour')
print(encoded)
# colour_blue colour_green colour_red
# 0 0 0 1
# 1 0 1 0
# 2 1 0 0
# 3 0 0 1
تعيين كل فئة إلى عدد صحيح. استخدم فقط عندما يكون للفئات ترتيب طبيعي:
from sklearn.preprocessing import LabelEncoder
# Works for: ['low', 'medium', 'high'] → [0, 1, 2]
# DANGER: Don't use for unordered categories like cities —
# the model will incorrectly assume London(0) < Paris(1) < Tokyo(2)
le = LabelEncoder()
df['education_level'] = le.fit_transform(df['education_level'])
# 'school' → 0, 'undergraduate' → 1, 'postgraduate' → 2
البيانات المفقودة تكاد تكون عالمية في مجموعات البيانات في العالم الحقيقي. لديك عدة خيارات:
املأ القيم المفقودة ببديل محسوب:
from sklearn.impute import SimpleImputer
import numpy as np
# Strategy options: 'mean', 'median', 'most_frequent', 'constant'
imputer = SimpleImputer(strategy='median')
X_imputed = imputer.fit_transform(X)
# For numerical data: median is robust to outliers
# For categorical data: use 'most_frequent'
في بعض الأحيان تكون حقيقة أن البيانات مفقودة مفيدة في حد ذاتها:
# Create a binary flag: 1 if income was missing, 0 if present
df['income_missing'] = df['income'].isna().astype(int)
# Then impute the original column
df['income'].fillna(df['income'].median(), inplace=True)
قم بإسقاط عمود إذا كان يحتوي على أكثر من 70-80% من القيم المفقودة (نادرًا ما تكون مفيدة). قم بإسقاط صف فقط إذا كان لديك الكثير من البيانات وكان الصف مفقودًا بشكل عشوائي (وليس بشكل منهجي).
هذا هو المكان الذي تصبح فيه الهندسة المميزة فنًا. يمكنك استخدام معرفة المجال لإنشاء ميزات تلتقط أنماطًا غير مرئية في البيانات الأولية.
df['purchase_datetime'] = pd.to_datetime(df['purchase_datetime'])
# Extract meaningful components
df['hour_of_day'] = df['purchase_datetime'].dt.hour
df['day_of_week'] = df['purchase_datetime'].dt.dayofweek
df['is_weekend'] = (df['day_of_week'] >= 5).astype(int)
df['month'] = df['purchase_datetime'].dt.month
df['is_holiday'] = df['purchase_datetime'].isin(uk_holidays).astype(int)
لا يخبر الطابع الزمني الأولي النموذج بأي شيء بشكل مباشر؛ تكشف هذه الميزات المشتقة عن أنماط مثل "ذروة الاحتيال في الساعة 3 صباحًا" أو "ارتفاع المبيعات في عطلات نهاية الأسبوع".
# Square footage × number of bathrooms might be more predictive
# than either feature alone for house prices
df['size_per_bathroom'] = df['sqft'] / df['bathrooms']
# Ratio of income to loan amount — a classic credit risk feature
df['debt_to_income'] = df['loan_amount'] / df['annual_income']
from sklearn.feature_extraction.text import TfidfVectorizer
# Convert raw text to numerical feature matrix
vectorizer = TfidfVectorizer(max_features=1000, stop_words='english')
text_features = vectorizer.fit_transform(df['review_text'])
# Each word becomes a feature; its value reflects how important
# the word is in that document relative to the whole corpus
بمجرد إنشاء نموذج، يمكنك قياس الميزات التي وجدتها أكثر فائدة. يعد هذا مفيدًا لفهم النموذج الخاص بك ولتحديد الميزات التي سيتم الاحتفاظ بها أو إسقاطها:
from sklearn.ensemble import RandomForestClassifier
import matplotlib.pyplot as plt
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)
# Get feature importances
importances = pd.Series(
model.feature_importances_,
index=feature_names
).sort_values(ascending=False)
print(importances.head(10))
# income_to_debt_ratio 0.187
# days_since_last_payment 0.143
# credit_utilisation 0.121
# ...
يمكن عادةً إسقاط الميزات ذات الأهمية القريبة من الصفر دون التأثير على الأداء - ويؤدي إسقاطها إلى تبسيط النموذج وتقليل وقت التدريب ويمكن أن يؤدي إلى تحسين التعميم.
عندما يكون لديك مئات أو آلاف الميزات، يمكن للنماذج أن تعاني - وهذا ما يسمى لعنة الأبعاد. تعمل تقنيات تقليل الأبعاد على ضغط الميزات مع الحفاظ على الأنماط الأكثر أهمية:
from sklearn.decomposition import PCA
# Reduce 100 features to 10 components that capture 95% of variance
pca = PCA(n_components=10)
X_reduced = pca.fit_transform(X_scaled)
print(f"Variance explained: {pca.explained_variance_ratio_.sum():.2%}")
# Variance explained: 94.7%
يعد PCA (تحليل المكونات الرئيسية) هو النهج الأكثر شيوعًا، ولكن هناك طرق أخرى تشمل t-SNE (للتصور) وUMAP (للحفاظ على البنية المحلية).
لديك مجموعة بيانات تحتوي على عمود ”المدينة” يحتوي على 50 اسمًا مختلفًا للمدينة. ما هو أسلوب الترميز الذي يجب عليك استخدامه؟