أساسيات تعلم الآلة1996متوسط10 دقيقة قراءة

تقليص المعاملات وانتقاء المتغيرات بأسلوب Lasso

Regression Shrinkage and Selection via the Lasso

Tibshirani, R. — Journal of the Royal Statistical Society Series B

المشكلة

العادية تتقن ملاءمة بيانات ، لكنها لا تملك أي وسيلة لكبح تعقيد . المشكلة تظهر بوضوح حين يكون عدد المتغيرات كبيراً — وخاصة حين يتجاوز عدد العيّنات — فيحفظ النموذج الضجيج بدل أن يتعلّم النمط الحقيقي، وتصبح المعاملات ضخمة وغير مستقرّة. انحدار الحافة (عقوبة L2) يعالج جزءاً من المشكلة بتقليص المعاملات نحو الصفر، لكنه لا يُلغي أيّاً منها تماماً، فتبقى جميع المتغيرات في النموذج ويصعب تفسيره. قبل Lasso لم تكن هناك طريقة تجمع بين التقليص والانتقاء التلقائي في مسألة أمثَلة محدَّبة واحدة.

الإسهام

Lasso (عامل والانتقاء بالقيمة المطلقة الصغرى): أسلوب تنظيم يستبدل عقوبة المربعات (L2) في انحدار الحافة بعقوبة القيمة المطلقة (L1) — أي مجموع القيم المطلقة للمعاملات بدل مجموع مربعاتها. هذا التعديل يبدو بسيطاً، لكن أثره الهندسي جذري: منطقة القيد تأخذ شكل معيَّن (ماسة) بزوايا حادة تقع على المحاور مباشرةً. حين تتمدد منحنيات الخطأ المتساوي وتلامس هذا الشكل، تصطدم عادةً بإحدى الزوايا — ما يعني أن معاملاً واحداً أو أكثر ينتهي عند الصفر تماماً. النتيجة: نموذج مُتناثر يجمع التقليص والانتقاء التلقائي في مسألة أمثَلة محدَّبة واحدة.

الأثر

أصبحت ورقة Lasso من أكثر الأوراق البحثية استشهاداً في الإحصاء وتعلُّم الآلة، وأسّست لعائلة كاملة من الأساليب المبنية على التناثر: الشبكة المرنة (Elastic Net)، وLasso المجموعات، وLasso التكيُّفي، وLasso المُندمج، وLasso البياني. بفضل هذا العمل صار الانتقاء التلقائي للمتغيرات جزءاً أساسياً من أدوات التنظيم، وفتح الباب أمام النمذجة العملية في مجالات كعلم الجينوم والمالية ومعالجة الإشارات وأي مجال يفوق فيه عدد المتغيرات عدد العيّنات. عقوبة L1 اليوم أداة أساسية في كل مكتبة تعلُّم آلي تقريباً.

تخيّل أنك تدير مطبخاً فيه 50 برطمان بهارات، لكن أي طبق حقيقي لا يحتاج أكثر من 3 إلى 5 منها. طريقة المربعات الصغرى تشبه طاهياً يرمي رشّة من كل برطمان في القدر — حتى البهارات التي لا تضيف شيئاً — فيخرج الطبق مشوَّشاً بلا هوية. بأسلوب الحافة (Ridge) يُبقي الخمسين برطماناً لكنه يُقلّل الرشّات، فتخفّ النكهات دون أن يختفي الازدحام.

Lasso يتصرّف كطاهٍ صارم: ينظر لكل بهار ويسأل — هل هذا يُحسّن الطبق فعلاً؟ إن لم يكن كذلك، يُعيد البرطمان إلى الرفّ مغلقاً ومُستبعَداً تماماً. لا يبقى في الوصفة إلا ما يستحق مكانه. السرّ في شكل الميزانية: بدل سقفٍ دائري أملس على مجموع المربعات (كما في Ridge)، يفرض Lasso سقفاً على مجموع القيم المطلقة — وهذا السقف يأخذ شكل معيَّن (ماسة) بزوايا حادة. عند تلك الزوايا بالذات تختفي بهارات بأكملها من الوصفة.

المشكلة: متنبئات كثيرة وانضباط قليل

الفكرة الأساسية في الخطي بسيطة: نُعبّر عن المتغير المستهدَف yy بمجموع موزون لمجموعة x1,x2,,xpx_1, x_2, \dots, x_p مع ضجيج عشوائي. المربعات الصغرى العادية (OLS) تبحث عن β^\hat{\beta} التي تجعل مجموع مربعات الأخطاء أصغر ما يمكن. وحين يكون عدد المتغيرات pp صغيراً مقارنةً بعدد العيّنات nn، تعمل هذه الطريقة بشكل ممتاز.

المشكلة تظهر في التطبيقات الواقعية: في علم الجينوم قد يكون لديك آلاف الجينات، وفي المالية مئات المؤشرات، وفي النصوص ملايين الكلمات — أي أن pp قد يُنافس nn أو يتجاوزه. في هذه الحالة تملك المربعات الصغرى عدداً لا نهائياً من الحلول التي تُلائم البيانات تماماً، لكنها جميعاً عديمة الفائدة لأن النموذج حفظ الضجيج بدل أن يتعلّم النمط الحقيقي. بل حتى حين يكون p<np < n، فإن وجود متغيرات غير مفيدة يُضخّم ويجعل النموذج هشّاً.

افتح في المختبر
حرّك المنزلق لزيادة عدد المتغيرات (p). لاحظ كيف يهبط خطأ التدريب إلى الصفر بينما يتضخّم خطأ الاختبار.
تستيقظ التجربة عند وصولك…

انحدار الحافة: تقليص بلا انتقاء

قبل Lasso، كانت الطريقة المعتادة لمواجهة هي انحدار الحافة (Hoerl وKennard، 1970). الفكرة فيه أن نُضيف إلى دالة الخطأ حدّاً عقابياً يتناسب مع مجموع مربعات المعاملات:

β^ridge=argminβ{i=1n(yijxijβj)2+λj=1pβj2}\hat{\beta}^{\text{ridge}} = \arg\min_{\beta} \left\{ \sum_{i=1}^{n} \left( y_i - \sum_{j} x_{ij} \beta_j \right)^2 + \lambda \sum_{j=1}^{p} \beta_j^2 \right\}
دالة هدف انحدار الحافة — عقوبة L2الحد λΣβ²_j يضغط على كل المعاملات لتقترب من الصفر، وكلما كبُر λ زاد هذا الضغط. لكن لا يصل أي معامل إلى الصفر تماماً — انحدار الحافة يُقلّص الجميع لكنه لا يحذف أحداً.

انحدار الحافة يُحسّن استقرار التنبؤات ويُقلّل التباين، لكنه لا يُنتج أبداً. لو بدأت بألف متغير للتعبير الجيني مثلاً، ستحصل على ألف معامل مُقلَّص — لا شيء منها صفر، ولا شيء مُستبعَد. النتيجة جدار من الأرقام الصغيرة، ولا إجابة واضحة على السؤال الأهم: أيّ الجينات مهمة فعلاً؟

Lasso: تغيير واحد يغيّر كل شيء

فكرة Tibshirani تبدو للوهلة الأولى تعديلاً بسيطاً: بدل أن نعاقب مربعات المعاملات (L2)، نعاقب قيمها المطلقة (L1):

β^lasso=argminβ{12ni=1n(yijxijβj)2+λj=1pβj}\hat{\beta}^{\text{lasso}} = \arg\min_{\beta} \left\{ \frac{1}{2n} \sum_{i=1}^{n} \left( y_i - \sum_{j} x_{ij} \beta_j \right)^2 + \lambda \sum_{j=1}^{p} |\beta_j| \right\}
دالة هدف Lasso — عقوبة L1التغيير الوحيد: |β_j| بدل β²_j. القيمة المطلقة فيها نقطة انكسار حادة عند الصفر — مشتقتها ±1 في كل مكان ما عدا الصفر نفسه حيث لا تكون معرَّفة. هذا الانكسار هو بالضبط ما يدفع المعاملات نحو الصفر ويُثبّتها عنده.

يمكن التعبير عن Lasso بصورة مكافئة كمسألة مقيَّدة: صغّر مجموع مربعات الأخطاء بشرط jβjt\sum_j |\beta_j| \leq t. هذا القيد يرسم المنطقة المسموح للحل أن يقع فيها — وشكل هذه المنطقة هو مفتاح فهم كل شيء.

الهندسة: لماذا يصنع المعيَّن أصفاراً

لنبسّط الصورة ونتخيّل مسألة بمعاملَين فقط على مستوى ثنائي الأبعاد. دالة في المربعات الصغرى ترسم خطوط تساوٍ بيضاوية (قطوع ناقصة) مركزها حل OLS — كل خط يمثّل مجموعة قيم (β1,β2)(\beta_1, \beta_2) التي تُعطي الخطأ ذاته.

في انحدار الحافة، القيد β12+β22t\beta_1^2 + \beta_2^2 \leq t يرسم دائرة. حين يتمدد أصغر قطع ناقص حتى يلمس هذه الدائرة، نقطة التلامس تقع عادةً على المنحنى الأملس — أي أن كلا المعاملَين يبقيان مختلفَين عن الصفر.

أما في Lasso فالقيد β1+β2t|\beta_1| + |\beta_2| \leq t يرسم معيَّناً — مربعاً مائلاً بـ45 درجة وزواياه الحادة تقع على المحاور مباشرةً. حين يتمدد القطع الناقص ويلامس هذا المعيَّن، يصطدم في الغالب بإحدى الزوايا، وعند الزاوية يكون أحد المعاملَين صفراً تماماً — أي أنه حُذف من النموذج. في الأبعاد العالية يتحوّل المعيَّن إلى متعدد وجوه بزوايا أكثر بكثير من أوجهه، فترتفع فرصة الوصول إلى حلّ متناثر.

افتح في المختبر
حرّك λ لترى كيف تتقاطع منطقة القيد (المعيَّن مقابل الدائرة) مع منحنيات الخطأ المتساوي. لاحظ كيف ينجذب حل Lasso نحو الزاوية.
تستيقظ التجربة عند وصولك…

العتبة اللينة: الرؤية التحليلية

في الحالة الخاصة التي تكون فيها أعمدة مصفوفة التصميم متعامدة ومعيارية — أي أن كل متغير مستقل عن الآخرين وتباينه واحد — يكون لحل Lasso صيغة مغلقة أنيقة تُسمى :

β^jlasso=sign(β^jOLS)max(β^jOLSλ, 0)\hat{\beta}_j^{\text{lasso}} = \text{sign}(\hat{\beta}_j^{\text{OLS}}) \cdot \max\left(|\hat{\beta}_j^{\text{OLS}}| - \lambda, \ 0\right)
العتبة اللينة — كل معامل على حدةالآلية واضحة: إذا كان تقدير المربعات الصغرى أصغر من λ بالقيمة المطلقة، يصبح صفراً تماماً — يُحذف المتغير. وإن كان أكبر، يُقلَّص نحو الصفر بمقدار ثابت λ. في المقابل، انحدار الحافة يضرب كل معامل في 1/(1+λ) — يُصغّره لكنه لا يُلغيه أبداً.
افتح في المختبر
حرّك λ وشاهد كيف تحذف العتبة اللينة المعاملات الصغيرة وتُقلّص الكبيرة.
تستيقظ التجربة عند وصولك…

مسار التنظيم: مشاهدة المتغيرات تدخل وتخرج

تخيّل أنك تبدأ من قيمة λ\lambda كبيرة جداً حيث كل المعاملات صفر، ثم تُنزلها تدريجياً نحو الصفر (أي نحو حل المربعات الصغرى). مع كل انخفاض، تبدأ المعاملات بالظهور في النموذج واحداً تلو الآخر. المنحنى الذي يرسمه كل معامل كدالة في λ\lambda — أي مسار التنظيم — يكون خطياً بالقِطع في Lasso، وهي خاصية مميزة اكتشفها Efron وزملاؤه (2004) عبر خوارزمية LARS.

هذا المسار يحكي قصة أهمية المتغيرات: أول معامل يبتعد عن الصفر هو أقوى متغير، والثاني هو الأهم بعده في وجود الأول، وهكذا. يختار بعدها قيمة λ\lambda التي تُعطي أفضل أداء تنبؤي على بيانات لم تُستخدَم في التدريب، فنحصل على نموذج متناثر مبنيّ على أسس منهجية.

افتح في المختبر
حرّك منزلق λ وشاهد المعاملات وهي تظهر في النموذج وتختفي منه على طول مسار التنظيم.
تستيقظ التجربة عند وصولك…

حلّ Lasso: النزول الإحداثي

عقوبة L1 تجعل غير ملساء، ما يعني أنه لا توجد صيغة مغلقة بسيطة حين تكون المتغيرات مترابطة. الحل العملي الأكثر استخداماً هو : الفكرة أن نُحسّن معاملاً واحداً في كل خطوة مع تثبيت البقية.

حين ننظر لمعامل واحد بمفرده، تتحوّل المسألة إلى بُعد واحد، وحلّها هو ببساطة تطبيق صيغة العتبة اللينة على البواقي الجزئية. نكرّر المرور على المعاملات الـ pp جميعها، وبما أن دالة الهدف محدَّبة فإن هذه العملية تتقارب نحو الحل الأمثل الشامل. النزول الإحداثي سريع جداً — يتعامل مع ملايين المتغيرات في ثوانٍ — وهو المحرك الذي تعتمد عليه مكتبة glmnet الشهيرة (Friedman وHastie وTibshirani، 2010).

النزول الإحداثي لحل Lassopython

مبسَّط لإظهار الفكرة — ليس التنفيذ الحقيقي.

import numpy as np

def soft_threshold(z, lam):
    """العتبة اللينة: S(z, λ) = sign(z) * max(|z| - λ, 0)"""
    return np.sign(z) * np.maximum(np.abs(z) - lam, 0.0)

def lasso_cd(X, y, lam, max_iter=1000, tol=1e-6):
    """النزول الإحداثي لحل Lasso.
    X: مصفوفة التصميم (n, p) (معيارية)
    y: المتغير المستهدَف (n,) (مركّز)
    """
    n, p = X.shape
    beta = np.zeros(p)
    r = y.copy()               # البواقي = y - X @ beta

    for iteration in range(max_iter):
        beta_old = beta.copy()
        for j in range(p):
            # أعد إضافة مساهمة المتنبئ j
            r += X[:, j] * beta[j]
            # احسب تقدير المربعات الصغرى للمتنبئ j
            z_j = X[:, j] @ r / n
            # طبّق العتبة اللينة
            beta[j] = soft_threshold(z_j, lam)
            # حدّث البواقي
            r -= X[:, j] * beta[j]

        # تحقق من التقارب
        if np.max(np.abs(beta - beta_old)) < tol:
            break
    return beta

المنظور البايزي: توزيعات لابلاس المسبَقة

لعقوبة L1 تفسير احتمالي أنيق يربطها بالتفكير البايزي. لو افترضنا أن كل معامل يخضع لـ مستقل من نوع لابلاس p(βj)exp(λβj)p(\beta_j) \propto \exp(-\lambda|\beta_j|)، ثم حسبنا تقدير (MAP)، نحصل رياضياً على حل Lasso نفسه تماماً. الفكرة الجوهرية هنا: توزيع لابلاس له قمة حادة عند الصفر وأذيال ثقيلة — كأنه يقول إن معظم المعاملات ينبغي أن تكون صفراً، لكن القليل منها قد يكون كبيراً. قارن ذلك بالتوزيع الغاوسي المسبَق في انحدار الحافة: قمته ملساء عند الصفر وتضاؤله سريع — يفترض أن المعاملات صغيرة لكنها لا تساوي صفراً أبداً.

افتح في المختبر
قارن بين توزيع لابلاس المسبَق (L1 / Lasso) والتوزيع الغاوسي (L2 / الحافة). لاحظ كم قمة لابلاس عند الصفر أكثر حدّة.
تستيقظ التجربة عند وصولك…

مقارنة جنباً إلى جنب: OLS مقابل الحافة مقابل Lasso

يمكن فهم الطرق الثلاث كطيف متدرّج من الانضباط. المربعات الصغرى لا تضع أي قيود — كل حرّ تماماً. انحدار الحافة يفرض ميزانية ملساء تُقلّص الجميع بالتناسب. أما Lasso فيفرض ميزانية حادة تحذف المساهمات الأضعف بالكامل. المقارنة التفاعلية أدناه توضّح هذا الفرق عملياً.

افتح في المختبر
بدّل بين OLS وانحدار الحافة وLasso لترى كيف تتغيّر المعاملات. لاحظ كيف يحذف Lasso المتغيرات غير المهمة تماماً.
تستيقظ التجربة عند وصولك…

القيود والتوسيعات

رغم قوته، في Lasso نقطتا ضعف معروفتان:

  • المتغيرات المترابطة. حين يكون متغيران يحملان معلومات متشابهة، يختار Lasso أحدهما بشكل شبه عشوائي ويحذف الآخر. لا يتقاسم الفضل بينهما — بل ينتقي ممثلاً واحداً عن كل مجموعة مترابطة ويُسقط البقية.

  • حالة p > n. حين يتجاوز عدد المتغيرات عدد العيّنات، لا يستطيع Lasso اختيار أكثر من nn متغيراً، حتى لو كان العدد الحقيقي للمتغيرات المهمة أكبر من ذلك.

هذه القيود دفعت إلى تطوير توسيعات مهمة. الشبكة المرنة (Zou وHastie، 2005) تمزج عقوبتي L1 وL2 معاً، فتحتفظ بقدرة Lasso على الانتقاء وتُضيف إليها تعاملاً أفضل مع بين المتغيرات. Lasso التكيُّفي (Zou، 2006) يمنح كل معامل وزن عقوبة مختلفاً فيحقق خصائص إحصائية أقوى. Lasso المجموعات (Yuan وLin، 2006) ينتقي أو يحذف مجموعات كاملة من المتغيرات المرتبطة بنيوياً.

شجرة عائلة Lasso

  1. 1970

    انحدار الحافة

    قدّم Hoerl وKennard أسلوب التنظيم بعقوبة L2 لمعالجة مسائل الانحدار سيئة الشرط. يُقلّص كل المعاملات لكنه لا يحذف أيّاً منها.

  2. 1996

    Lasso

    استبدل Tibshirani عقوبة L2 بعقوبة L1، فجمع التقليص والانتقاء التلقائي معاً في مسألة أمثَلة محدَّبة واحدة.

  3. 2004

    خوارزمية LARS

    طوّر Efron وHastie وJohnstone وTibshirani خوارزمية الانحدار بأصغر زاوية، التي تحسب مسار Lasso الكامل بكفاءة وتكشف أن المسار خطي بالقِطع.

  4. 2005

    الشبكة المرنة

    جمع Zou وHastie بين عقوبتي L1 وL2، فعالجا مشكلة عدم استقرار Lasso مع المتغيرات المترابطة دون التضحية بالتناثر.

  5. 2006

    Lasso التكيُّفي وLasso المجموعات

    قدّم Zou أوزان عقوبة تكيُّفية تُحسّن الخصائص الإحصائية. وقدّم Yuan وLin آلية لانتقاء مجموعات كاملة من المتغيرات المرتبطة بنيوياً.

  6. 2010

    مكتبة glmnet

    أصدر Friedman وHastie وTibshirani تطبيقاً فعّالاً للنزول الإحداثي جعل Lasso قابلاً للاستخدام على نطاق واسع — ملايين المتغيرات في ثوانٍ.

الفكرة ذاتها في شيفرة برمجية

Lasso مع scikit-learn — من البيانات إلى نموذج متناثرpython

مبسَّط لإظهار الفكرة — ليس التنفيذ الحقيقي.

from sklearn.linear_model import LassoCV
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import make_regression
import numpy as np

# ولّد بيانات: 200 عينة، 50 متغيراً، 5 فقط مهمة فعلاً
X, y, true_coef = make_regression(
    n_samples=200, n_features=50, n_informative=5,
    noise=10, coef=True, random_state=42
)

# دائماً اجعل المتغيرات معيارية قبل التنظيم
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# LassoCV يختار أفضل λ تلقائياً عبر التحقق المتقاطع
model = LassoCV(cv=5, random_state=42)
model.fit(X_scaled, y)

nonzero = np.sum(model.coef_ != 0)
print(f"المتغيرات المُختارة: {nonzero} / 50")      # ≈5، مطابق للحقيقة
print(f"أفضل λ: {model.alpha_:.4f}")
print(f"R² درجة: {model.score(X_scaled, y):.3f}")

# قارن: أكبر 5 معاملات تتطابق مع المتغيرات الخمسة المهمة فعلاً

اختبر فهمك

المرجعTibshirani, R.. Regression Shrinkage and Selection via the Lasso. Journal of the Royal Statistical Society Series B, 1996.

مصطلحات هذه الورقة