فصل ۱۱: برازش قانون

عنوان اصلی: RuleFit
منبع: https://christophm.github.io/interpretable-ml-book/rulefit.html
نویسنده: Christoph Molnar
مترجم: مریم محمودی


الگوریتم برازش قانون (Friedman و Popescu، ۲۰۰۸) مدل‌های خطی تنکی می‌آموزد که اثرات تعاملی میان ویژگی‌ها را به‌صورت خودکار و در قالب قوانین تصمیم شناسایی و در خود جای می‌دهند.

مدل رگرسیون خطی تعامل میان ویژگی‌ها را در نظر نمی‌گیرد. آیا خوب نبود مدلی داشتیم که به‌سادگی و تفسیرپذیریِ مدل‌های خطی باشد، اما تعاملات میان ویژگی‌ها را نیز در خود جای دهد؟ برازش قانون دقیقاً همین شکاف را پر می‌کند. برازش قانون یک مدل خطی تنک می‌آموزد که هم ویژگی‌های اصلی و هم تعدادی ویژگی جدید را در بر می‌گیرد؛ این ویژگی‌های جدید همان قوانین تصمیم هستند. این ویژگی‌های تازه، تعاملات میان ویژگی‌های اصلی را ضبط می‌کنند. برازش قانون این ویژگی‌ها را به‌صورت خودکار از روی درخت‌های تصمیم تولید می‌کند. هر مسیر در یک درخت را می‌توان با ترکیب تصمیم‌های تقسیم (split) در قالب یک قانون بازنویسی کرد؛ به شکل ۱۱.۱ نگاه کنید. پیش‌بینیِ گره‌ها کنار گذاشته می‌شود و فقط شرط‌های تقسیم در قوانین تصمیم استفاده می‌شوند:

از یک درخت با ۳ گره پایانی، ۴ قانون قابل تولید است.

شکل ۱۱.۱: از یک درخت با ۳ گره پایانی، ۴ قانون قابل تولید است.

توضیح مترجم: نکتهٔ کلیدی این‌جا این است که قانون فقط از گره‌های پایانی (برگ) ساخته نمی‌شود، بلکه از هر گرهی که در مسیر درخت قرار دارد — از جمله گره‌های میانی — نیز یک قانون ساخته می‌شود. برای همین یک درخت با ۳ برگ (که یعنی ۲ گرهٔ تصمیم دارد) به‌جای ۳ قانون، ۴ قانون تولید می‌کند.

مثال مترجم برای درک بهتر خوانندگان: فرض کنید درختی داریم با این ساختار: ابتدا شرط temp > 12؛ اگر برقرار بود، سپس شرط hum <= 80. از این درخت چهار قانون قابل استخراج است:

۱. temp > 12 → ۱ وگرنه ۰ (از گرهٔ ریشه) ۲. temp <= 12 → ۱ وگرنه ۰ (شاخهٔ مخالف همان گره) ۳. temp > 12 AND hum <= 80 → ۱ وگرنه ۰ (مسیر تا برگ اول) ۴. temp > 12 AND hum > 80 → ۱ وگرنه ۰ (مسیر تا برگ دوم)

همان‌طور که می‌بینید، حتی شرط تنهای temp > 12 (بدون ادامهٔ مسیر تا یک برگ) هم یک قانون جداگانه محسوب می‌شود. برای نمایش بصری ساختار «ریشه ← شاخه‌ها ← برگ‌ها» در یک درخت تصمیم، می‌توانید این آموزش تصویری دربارهٔ درخت‌های تصمیم را ببینید.

این درخت‌های تصمیم از کجا می‌آیند؟ درخت‌ها برای پیش‌بینی متغیر هدف مورد نظر آموزش داده می‌شوند. این کار تضمین می‌کند که تقسیم‌بندی‌ها برای وظیفهٔ پیش‌بینی معنادار باشند. هر الگوریتمی که تعداد زیادی درخت تولید کند، مثلاً یک جنگل تصادفی، می‌تواند برای برازش قانون به کار رود. هر درخت به قوانین تصمیم تجزیه می‌شود که به‌عنوان ویژگی‌های اضافی در یک مدل رگرسیون خطی تنک (Lasso) استفاده می‌شوند.

مقالهٔ برازش قانون از داده‌های مسکن بوستون برای نمایش این ایده استفاده کرده است: هدف پیش‌بینی میانهٔ ارزش خانه در یک محلهٔ بوستون است. یکی از قوانین تولیدشده توسط برازش قانون این است: اگر تعداد اتاق‌ها > ۶.۶۴ و غلظت اکسید نیتریک < ۰.۶۷ آن‌گاه ۱ وگرنه ۰.

برازش قانون همچنین یک معیار اهمیت ویژگی ارائه می‌دهد که به شناسایی جملات خطی و قوانینی که برای پیش‌بینی‌ها اهمیت دارند کمک می‌کند. اهمیت ویژگی از روی وزن‌های مدل رگرسیون محاسبه می‌شود. این معیار اهمیت را می‌توان برای ویژگی‌های اصلی (که هم به‌صورت «خام» و هم احتمالاً در بسیاری از قوانین تصمیم استفاده شده‌اند) تجمیع کرد.

برازش قانون همچنین نمودارهای وابستگی جزئی (partial dependence plots) را معرفی می‌کند تا میانگین تغییر پیش‌بینی در اثر تغییر یک ویژگی را نشان دهد. نمودار وابستگی جزئی یک روش مستقل از مدل است که با هر مدلی قابل استفاده است و در فصل نمودارهای وابستگی جزئی توضیح داده شده است.

تفسیر و مثال

از آنجا که برازش قانون در نهایت یک مدل خطی برآورد می‌کند، تفسیر آن همانند مدل‌های خطی «معمولی» است. تنها تفاوت این است که این مدل ویژگی‌های جدیدی دارد که از قوانین تصمیم مشتق شده‌اند. قوانین تصمیم ویژگی‌های دودویی هستند: مقدار ۱ به این معناست که همهٔ شرط‌های قانون برقرارند؛ در غیر این صورت مقدار ۰ است. برای جملات خطی در برازش قانون، تفسیر همانند مدل‌های رگرسیون خطی است: اگر ویژگی به اندازهٔ یک واحد افزایش یابد، پیش‌بینی به اندازهٔ وزن متناظر آن ویژگی تغییر می‌کند.

در این مثال از برازش قانون برای پیش‌بینی تعداد دوچرخه‌های کرایه‌شده در یک روز مشخص استفاده می‌کنیم. جدول ۱۱.۱ پنج مورد از قوانینی را که برازش قانون تولید کرده، به همراه وزن Lasso و اهمیت آن‌ها نشان می‌دهد. نحوهٔ محاسبه بعداً در این فصل توضیح داده می‌شود. مهم‌ترین قانون این بود: «temp بیشتر از ۱۲ و hum کمتر یا مساوی ۸۶»، با وزن ۶۲۶. تفسیر آن این است: اگر دما بیشتر از ۱۲ درجه و رطوبت کمتر یا مساوی ۸۶٪ باشد، پیش‌بینی تعداد دوچرخه‌ها به اندازهٔ ۶۲۶ افزایش می‌یابد، به شرطی که مقادیر سایر ویژگی‌ها ثابت بمانند. در مجموع، از ۸ ویژگی اصلی، ۳۶۸ قانون از این دست ایجاد شد؛ عدد نسبتاً بزرگی! اما به لطف Lasso، تنها ۳۳ مورد از این ۳۶۸ قانون وزنی متفاوت از صفر دارند.

جدول ۱۱.۱: قوانین تولیدشده توسط برازش قانون به همراه وزن‌هایشان در مدل خطی.

توصیفوزناهمیت
temp بیشتر از ۱۲ و hum کمتر یا مساوی ۸۶626311
cnt_2d_bfr بیشتر از ۵۳۸۲ و hum کمتر یا مساوی ۸۰661299
cnt_2d_bfr بیشتر از ۲۷۰۳ و weather در {"GOOD"}426213
cnt_2d_bfr بیشتر از ۵۰۴۷ و temp بیشتر از ۹376178
۴ ≤ windspeed ≤ ۲۴-32161

محاسبهٔ اهمیت‌های سراسری ویژگی‌ها نشان می‌دهد که دما و روند زمانی مهم‌ترین ویژگی‌ها هستند، همان‌طور که در شکل ۱۱.۲ نمایش داده شده است. سنجهٔ اهمیت ویژگی، هم اهمیت جملهٔ خام ویژگی و هم اهمیت همهٔ قوانین تصمیمی که آن ویژگی در آن‌ها ظاهر می‌شود را در بر می‌گیرد.

اهمیت ویژگی‌ها در برازش قانون

شکل ۱۱.۲: سنجه‌های اهمیت ویژگی برای مدل برازش قانون در پیش‌بینی تعداد دوچرخه‌ها. مهم‌ترین ویژگی‌ها برای پیش‌بینی‌ها، تعداد قبلی، رطوبت و دما بودند.

الگوی تفسیر

تفسیر مشابه مدل‌های خطی است: پیش‌بینی به اندازهٔ $\beta_j$ تغییر می‌کند اگر ویژگی $X_j$ به اندازهٔ یک واحد تغییر کند، به شرطی که همهٔ ویژگی‌های دیگر ثابت بمانند. تفسیر وزن یک قانون تصمیم حالت خاصی از همین قاعده است: اگر همهٔ شرط‌های قانون تصمیم $r_k$ برقرار باشند، پیش‌بینی به اندازهٔ $\alpha_k$ (وزن آموخته‌شدهٔ قانون $r_k$ در مدل خطی) تغییر می‌کند.

برای دسته‌بندی (با استفاده از رگرسیون لجستیک به‌جای رگرسیون خطی): اگر همهٔ شرط‌های قانون تصمیم $r_k$ برقرار باشند، نسبت شانس (odds) برای رویداد در مقابل عدم رویداد در ضریب $\alpha_k$ ضرب می‌شود.

توضیح مترجم: این‌جا با حالت رگرسیون خطی فرق دارد. در رگرسیون خطی، وزن به‌صورت جمعی به پیش‌بینی اضافه می‌شود (مثلاً پیش‌بینی ۶۲۶ واحد بیشتر می‌شود). اما در رگرسیون لجستیک، اثر روی نسبت شانس (odds) ضربی است، نه جمعی.

مثال مترجم برای درک بهتر خوانندگان: فرض کنید $\alpha_k = 1.5$ برای قانونی است که شرایطش برقرار است. تفسیر درست این است: «odds جدید = ۱.۵ × odds قبلی» — یعنی نسبت شانس ۵۰٪ افزایش می‌یابد، نه این‌که عدد ۱.۵ به odds قبلی اضافه شود.

⚠️ مراقب برون‌یابی (extrapolation) باشید

عبارت «به شرطی که همهٔ ویژگی‌های دیگر ثابت بمانند» در اینجا کمی نامعقول است، چرا که یک ویژگی می‌تواند هم یک مؤلفهٔ خطی داشته باشد و هم در چند قانون ظاهر شود. تغییر ویژگی اصلی در این صورت چند مؤلفهٔ مدل را همزمان تغییر می‌دهد؛ بنابراین در واقع همهٔ ویژگی‌های مدل ثابت نمی‌مانند.

توضیح مترجم: برای مثال، اگر ویژگی «دما» هم به‌صورت خطی در مدل حضور داشته باشد و هم در قوانینی مثل «دما > ۱۲» یا «دما > ۹ و cnt_2d_bfr > ۵۰۴۷» به کار رفته باشد، افزایش یک واحدی دما می‌تواند هم‌زمان جملهٔ خطی و چند قانون را فعال یا غیرفعال کند. در این حالت نمی‌توان گفت «فقط دما تغییر کرده و بقیهٔ ویژگی‌ها ثابت مانده‌اند»، چون خودِ قوانین از جنس همان دما ساخته شده‌اند.

نظریه

بیایید عمیق‌تر به جزئیات فنی الگوریتم برازش قانون بپردازیم. برازش قانون از دو مؤلفه تشکیل شده است: مؤلفهٔ اول «قوانین» را از روی درخت‌های تصمیم می‌سازد، و مؤلفهٔ دوم یک مدل خطی را با ویژگی‌های اصلی و قوانین جدید به‌عنوان ورودی برازش می‌کند (از همین‌رو نام اصلی «RuleFit» یا «برازش قانون»).

گام ۱: تولید قوانین

یک قانون چه شکلی دارد؟ قوانین تولیدشده توسط الگوریتم شکل ساده‌ای دارند. برای مثال: اگر $x_2 < 3$ و $x_5 < 7$ آن‌گاه ۱ وگرنه ۰.

قوانین با تجزیهٔ درخت‌های تصمیم ساخته می‌شوند: هر مسیر به یک گره در درخت را می‌توان به یک قانون تصمیم تبدیل کرد. درخت‌های مورد استفاده برای قوانین، برای پیش‌بینی متغیر هدف برازش می‌شوند. بنابراین تقسیم‌بندی‌ها و قوانین حاصل، برای پیش‌بینی همان متغیری که به آن علاقه‌مندید بهینه شده‌اند. کافی است تصمیم‌های دودویی‌ای را که به یک گرهٔ خاص می‌رسند با «AND» به هم زنجیر کنید — و یک قانون به دست می‌آید. مطلوب است که تعداد زیادی قانون متنوع و معنادار تولید شود. برای برازش یک مجموعهٔ درخت‌های تصمیم از طریق رگرسیون یا دسته‌بندی متغیر هدف $\mathbf{y}$ با ویژگی‌های اصلی $\mathbf{X}$، از تقویت گرادیانی (gradient boosting) استفاده می‌شود. هر درخت حاصل به چند قانون تبدیل می‌شود.

توضیح مترجم: تقویت گرادیانی یک روش ساخت مجموعهٔ درخت است که در آن درخت‌ها یکی‌یکی و پی‌درپی ساخته می‌شوند؛ هر درخت جدید سعی می‌کند خطاهای باقی‌ماندهٔ درخت(های) قبلی را جبران کند، نه این‌که از صفر دوباره کل مسئله را حل کند. نتیجهٔ نهایی، مجموع وزن‌دارِ پیش‌بینی همهٔ این درخت‌هاست. برای نمایش بصری این ایده — که چطور هر درخت جدید روی خطای درخت‌های قبلی می‌سازد — می‌توانید به این توضیح تصویری الگوریتم تقویت گرادیانی مراجعه کنید.

نه‌فقط درخت‌های تقویت‌شده، بلکه هر الگوریتم مجموعهٔ درختی می‌تواند برای تولید درخت‌های برازش قانون استفاده شود. یک مجموعهٔ درخت را می‌توان با این فرمول کلی توصیف کرد:

$$\hat{f}(\mathbf{x}) = a_0 + \sum_{m=1}^M a_m \hat{f}_m(\mathbf{x})$$

$M$ تعداد درخت‌ها و $\hat{f}_m(\mathbf{x})$ تابع پیش‌بینی $m$امین درخت است. مقادیر $a$ وزن‌ها هستند. مجموعه‌های بگ‌شده (bagged)، جنگل تصادفی، AdaBoost و MART مجموعه‌های درختی تولید می‌کنند و می‌توانند برای برازش قانون استفاده شوند.

قوانین را از تمام درخت‌های مجموعه می‌سازیم. هر قانون $r_m$ به این شکل است:

$$r_m(\mathbf{x}) = \prod_{j \in \mathrm{T}_m} I(x_j \in s_{jm})$$

توضیح مترجم: این فرمول چیز پیچیده‌ای نیست — فقط راه ریاضی نوشتنِ «AND» است. چون هر $I(\cdot)$ فقط مقدار ۰ یا ۱ می‌گیرد، حاصل‌ضرب چند تا از این‌ها فقط زمانی ۱ می‌شود که همهٔ آن‌ها هم‌زمان ۱ باشند (دقیقاً مثل AND منطقی). اگر حتی یکی از شرط‌ها صفر باشد، کل حاصل‌ضرب صفر می‌شود.

مثال مترجم برای درک بهتر خوانندگان: برای نمونه‌ای با temp=20، hum=70، windspeed=15 و قانون $I(\mathrm{temp}>15) \cdot I(\mathrm{hum}<80)$: چون $I(20>15)=1$ و $I(70<80)=1$، حاصل‌ضرب برابر $1 \times 1 = 1$ است (قانون فعال است). اما اگر hum=90 بود: $I(90<80)=0$، پس حاصل‌ضرب برابر $1 \times 0 = 0$ می‌شد (قانون غیرفعال).

که در آن $\mathrm{T}_m$ مجموعهٔ ویژگی‌های استفاده‌شده در $m$امین درخت است، $I$ تابع اندیکاتور است که وقتی ویژگی $x_j$ در زیرمجموعهٔ مشخص‌شدهٔ مقادیر $s_{jm}$ برای ویژگی $j$ام (بر اساس تقسیم‌بندی‌های درخت) باشد برابر ۱ و در غیر این صورت برابر ۰ است. برای ویژگی‌های عددی، $s_{jm}$ یک بازه در محدودهٔ مقادیر ویژگی است. این بازه یکی از دو حالت زیر را دارد:

$$x_{s_{jm},\mathrm{lower}} < x_j$$

$$x_j < x_{s_{jm},\mathrm{upper}}$$

تقسیم‌بندی‌های بیشتر روی همان ویژگی می‌تواند به بازه‌های پیچیده‌تری منجر شود. برای ویژگی‌های دسته‌ای، زیرمجموعهٔ $s$ شامل برخی دسته‌های خاص همان ویژگی است.

مثالی ساخته‌شده برای دادهٔ کرایهٔ دوچرخه:

$$r_{17}(\mathbf{x}) = I(x_{\mathrm{temp}} < 15) \cdot I(x_{\mathrm{weather}} \in {\mathrm{good}, \mathrm{misty}}) \cdot I(10 \leq x_{\mathrm{windspeed}} < 20)$$

این قانون اگر هر سه شرط برقرار باشند ۱ برمی‌گرداند، در غیر این صورت ۰. برازش قانون همهٔ قوانین ممکن را از یک درخت استخراج می‌کند، نه فقط از گره‌های برگ. بنابراین قانون دیگری که ساخته می‌شود این است:

$$r_{18}(\mathbf{x}) = I(x_{\mathrm{temp}} < 15) \cdot I(x_{\mathrm{weather}} \in {\mathrm{good}, \mathrm{misty}})$$

در مجموع، تعداد قوانین تولیدشده از یک مجموعهٔ $M$ درخت که هرکدام $t_m$ گرهٔ پایانی دارند، برابر است با:

$$K = \sum_{m=1}^M 2(t_m - 1)$$

یک ترفند که نویسندگان برازش قانون معرفی کرده‌اند این است که درخت‌ها را با عمق تصادفی می‌آموزند تا قوانین متنوعی با طول‌های مختلف تولید شوند. توجه کنید که مقدار پیش‌بینی‌شده در هر گره را کنار می‌گذاریم و فقط شرط‌هایی را که ما را به یک گره می‌رسانند نگه می‌داریم، و سپس از روی آن‌ها یک قانون می‌سازیم. وزن‌دهی قوانین تصمیم در گام ۲ برازش قانون انجام می‌شود.

راه دیگری برای نگاه به گام ۱: برازش قانون مجموعهٔ جدیدی از ویژگی‌ها را از روی ویژگی‌های اصلی شما تولید می‌کند. این ویژگی‌ها دودویی هستند و می‌توانند تعاملات نسبتاً پیچیده‌ای از ویژگی‌های اصلی شما را نمایش دهند. قوانین به‌گونه‌ای انتخاب می‌شوند که برای وظیفهٔ پیش‌بینی مفید باشند. قوانین به‌صورت خودکار از روی ماتریس متغیرهای همراه $\mathbf{X}$ تولید می‌شوند. به بیان ساده می‌توانید قوانین را ویژگی‌های جدیدی بر پایهٔ ویژگی‌های اصلی خود در نظر بگیرید.

💡 شرط‌های کمتر، تفسیرپذیری بهتر

برای تفسیرپذیری بهتر، تعداد شرط‌ها در هر قانون را بین ۱ تا ۳ نگه دارید.

گام ۲: مدل خطی تنک

در گام ۱ تعداد بسیار زیادی قانون به دست می‌آورید. از آنجا که گام اول را می‌توان صرفاً یک تبدیل ویژگی در نظر گرفت، هنوز کار برازش مدل تمام نشده است. همچنین می‌خواهید تعداد قوانین را کاهش دهید. علاوه بر قوانین، همهٔ ویژگی‌های «خام» مجموعه‌دادهٔ اصلی شما نیز در مدل خطی تنک استفاده خواهند شد. هر قانون و هر ویژگی اصلی به یک ویژگی در مدل خطی تبدیل می‌شود و یک برآورد وزن دریافت می‌کند. ویژگی‌های خام اصلی اضافه می‌شوند چون درخت‌ها در بازنمایی روابط خطی سادهٔ میان $Y$ و $X_j$ ضعیف عمل می‌کنند. پیش از آموزش مدل خطی تنک، ویژگی‌های اصلی را وینزوریزه (winsorize) می‌کنیم تا در برابر داده‌های پرت مقاوم‌تر باشند:

$$l_j^*(x_j) = \min(\delta_j^+, \max(\delta_j^-, x_j))$$

که در آن $\delta_j^-$ و $\delta_j^+$ کوانتیل‌های $\delta$ توزیع دادهٔ $\mathbf{x}_j$ هستند. انتخاب مقدار ۰.۰۵ برای $\delta$ به این معناست که هر مقداری از ویژگی $X_j$ که در ۵٪ پایین‌ترین یا ۵٪ بالاترین مقادیر قرار دارد، به‌ترتیب در کوانتیل ۵٪ یا ۹۵٪ محدود می‌شود. به‌عنوان یک قاعدهٔ سرانگشتی، می‌توانید $\delta = 0.025$ را انتخاب کنید.

توضیح مترجم: وینزوریزه کردن یعنی به‌جای حذف مقادیر پرت، آن‌ها را «هَرَس» می‌کنیم — یعنی مقادیر خیلی بزرگ را با بزرگ‌ترین مقدار قابل‌قبول (مثلاً کوانتیل ۹۷.۵٪) و مقادیر خیلی کوچک را با کوچک‌ترین مقدار قابل‌قبول (کوانتیل ۲.۵٪) جایگزین می‌کنیم. داده حذف نمی‌شود، فقط «سقف» و «کف» می‌گیرد. برای مقایسهٔ بصری توزیع داده پیش و پس از وینزوریزه کردن، می‌توانید این مقاله دربارهٔ وینزوریزه کردن را ببینید.

مثال مترجم برای درک بهتر خوانندگان: فرض کنید ستون windspeed این مقادیر را دارد: [2, 5, 8, 10, 12, 60]. اگر کوانتیل ۹۵٪ برابر ۱۵ باشد، مقدار پرت ۶۰ به ۱۵ تبدیل می‌شود: [2, 5, 8, 10, 12, 15]. میانگین و انحراف معیار دیگر تحت‌تأثیر آن مقدار عجیب ۶۰ نیستند.

علاوه بر این، جملات خطی باید نرمال‌سازی شوند تا اهمیت پیشینی یکسانی با یک قانون تصمیم معمولی داشته باشند:

$$l_j(x_j) = 0.4 \cdot \frac{l^*_j(x_j)}{\mathrm{std}(l^*_j(x_j))}$$

عدد $0.4$ میانگین انحراف معیار قوانین با توزیع پوششیِ یکنواخت $s_k \sim U(0, 1)$ است.

توضیح مترجم (استخراج ریاضی اضافه): یک قانون تصمیم، متغیری دودویی با احتمال موفقیت $s$ (پوشش) است، پس انحراف معیارش $\sqrt{s(1-s)}$ است. اگر فرض کنیم پوشش $s$ به‌طور یکنواخت بین ۰ و ۱ پخش شده، میانگین این انحراف معیار روی همهٔ مقادیر ممکن $s$ برابر است با:

$$\int_0^1 \sqrt{s(1-s)},ds = \frac{\pi}{8} \approx 0.393 \approx 0.4$$

یعنی عدد $0.4$ صرفاً «انحراف معیار متوسط یک قانون تصادفی معمولی» است، و هدف از ضرب کردن جمله‌های خطی در این عدد این است که مقیاس ویژگی‌های خام (که می‌توانند هر بازه‌ای داشته باشند، مثلاً دما بین ۰ تا ۴۰) با مقیاس قوانین صفر/یک قابل‌مقایسه شود.

هر دو نوع ویژگی را ترکیب می‌کنیم تا ماتریس ویژگی جدیدی بسازیم و یک مدل خطی تنک با Lasso و ساختار زیر آموزش دهیم:

$$\hat{f}(\mathbf{x}) = \hat{\beta}_0 + \sum_{k=1}^K \hat{\alpha}_k r_k(\mathbf{x}) + \sum_{j=1}^p \hat{\beta}_j l_j(x_j)$$

که در آن $\hat{\alpha}_k$ وزن برآوردشده برای قانون $k$ و $\hat{\beta}_j$ وزن ویژگی اصلی $j$ است. از آنجا که برازش قانون از Lasso استفاده می‌کند، تابع زیان محدودیت اضافه‌ای می‌گیرد که برخی وزن‌ها را وادار به گرفتن برآورد صفر می‌کند:

$$({\hat{\alpha}}_1^K, {\hat{\beta}}_0^p) = \arg\min_{{\hat{\alpha}}_1^K, {\hat{\beta}}_0^p} \sum_{i=1}^n L(y^{(i)}, \hat{f}(\mathbf{x}^{(i)}))$$

$$+ \lambda \cdot \left(\sum_{k=1}^K |\hat{\alpha}_k| + \sum_{j=1}^p |\hat{\beta}_j|\right)$$

نتیجه یک مدل خطی است که برای همهٔ ویژگی‌های اصلی و همهٔ قوانین، اثرات خطی دارد. تفسیر آن مانند مدل‌های خطی است؛ تنها تفاوت این است که برخی از ویژگی‌ها اکنون قوانین دودویی هستند.

گام ۳ (اختیاری): اهمیت ویژگی

برای جملات خطی ویژگی‌های اصلی، اهمیت ویژگی با استفاده از پیش‌بین استانداردشده اندازه‌گیری می‌شود:

$$I_j = |\hat{\beta}_j| \cdot \mathrm{std}(l_j(x_j))$$

که در آن $\hat{\beta}_j$ وزن حاصل از مدل Lasso و $\mathrm{std}(l_j(x_j))$ انحراف معیار جملهٔ خطی روی داده است.

برای جملات قانون تصمیم، اهمیت با فرمول زیر محاسبه می‌شود:

$$I_k = |\hat{\alpha}_k| \cdot \sqrt{s_k(1-s_k)}$$

که در آن $\hat{\alpha}_k$ وزن Lasso مرتبط با قانون تصمیم و $s_k$ پوشش (support) ویژگی در داده است، یعنی درصد نقاط داده‌ای که قانون تصمیم برای آن‌ها اعمال می‌شود (که در آن $r_k(\mathbf{x})=1$):

$$s_k = \frac{1}{n} \sum_{i=1}^n r_k(\mathbf{x}^{(i)})$$

یک ویژگی هم می‌تواند به‌صورت جملهٔ خطی ظاهر شود و هم احتمالاً در بسیاری از قوانین تصمیم. چگونه اهمیت کلی یک ویژگی را اندازه‌گیری کنیم؟ اهمیت $J_j(\mathbf{x}_j)$ یک ویژگی را می‌توان برای هر پیش‌بینی منفرد اندازه گرفت:

$$J_j(x_j) = I_j(x_j) + \sum_{k \mid x_j \in r_k} \frac{I_k(r_k)}{m_k}$$

که در آن $I_j$ اهمیت جملهٔ خطی و $I_k$ اهمیت قوانین تصمیمی است که $X_j$ در آن‌ها ظاهر می‌شود، و $m_k$ تعداد ویژگی‌های تشکیل‌دهندهٔ قانون $r_k$ است. جمع اهمیت ویژگی روی همهٔ نمونه‌ها، اهمیت سراسری ویژگی را به دست می‌دهد:

$$J_j(\mathbf{x}_j) = \sum_{i=1}^n J_j(x^{(i)}_j)$$

توضیح مترجم: وقتی یک قانون از چند شرط تشکیل شده (مثلاً «temp > 12 AND hum <= 86» که $m_k=2$ ویژگی دارد)، منطقی نیست کل اهمیت آن قانون را به‌طور کامل به هر دو ویژگی نسبت بدهیم — چون این کار اهمیت را دوبار می‌شمارد. به همین دلیل اهمیت قانون به‌طور مساوی بین ویژگی‌های تشکیل‌دهنده‌اش تقسیم می‌شود.

مثال مترجم برای درک بهتر خوانندگان: طبق جدول ۱۱.۱، قانون «temp > 12 & hum <= 86» اهمیت $I_k=311$ دارد و از ۲ ویژگی تشکیل شده ($m_k=2$). پس این قانون به اهمیت کلی temp مقدار $311/2=155.5$ اضافه می‌کند، و همان مقدار ۱۵۵.۵ به اهمیت کلی hum نیز اضافه می‌شود. این عدد بعداً با سهم این دو ویژگی از جمله‌های خطی و سایر قوانینی که در آن‌ها ظاهر شده‌اند، جمع می‌شود تا اهمیت نهایی و سراسری هر ویژگی به دست بیاید.

می‌توان زیرمجموعه‌ای از نمونه‌ها را انتخاب کرد و اهمیت ویژگی را برای آن گروه محاسبه کرد.

مزایا

برازش قانون به‌طور خودکار تعاملات ویژگی را به مدل‌های خطی اضافه می‌کند. بنابراین، مشکل مدل‌های خطی را که نیازمند افزودن دستی جملات تعاملی هستند حل می‌کند، و تا حدی نیز به مسئلهٔ مدل‌سازی روابط غیرخطی کمک می‌کند.

برازش قانون هم وظایف دسته‌بندی و هم رگرسیون را پشتیبانی می‌کند.

قوانین تولیدشده به‌راحتی تفسیرپذیرند، چون قوانین تصمیم دودویی هستند. یا قانون برای یک نمونه صدق می‌کند یا نه. تفسیرپذیری خوب فقط زمانی تضمین می‌شود که تعداد شرط‌های درون یک قانون زیاد نباشد. یک قانون با ۱ تا ۳ شرط منطقی به نظر می‌رسد. این یعنی حداکثر عمق ۳ برای درخت‌های مجموعهٔ درختی.

حتی اگر مدل قوانین زیادی داشته باشد، همهٔ آن‌ها برای هر نمونه اعمال نمی‌شوند. برای یک نمونهٔ منفرد، تنها تعداد کمی قانون (با وزن غیرصفر) اعمال می‌شود. این ویژگی، تفسیرپذیری محلی را بهبود می‌بخشد.

برازش قانون مجموعه‌ای از ابزارهای تشخیصی مفید پیشنهاد می‌کند. این ابزارها مستقل از مدل هستند، بنابراین می‌توانید آن‌ها را در بخش روش‌های مستقل از مدل این کتاب بیابید: اهمیت ویژگی، نمودارهای وابستگی جزئی و تعاملات ویژگی.

محدودیت‌ها

گاهی برازش قانون تعداد زیادی قانون تولید می‌کند که در مدل Lasso وزن غیرصفر می‌گیرند. تفسیرپذیری با افزایش تعداد ویژگی‌های موجود در مدل کاهش می‌یابد. یک راه‌حل امیدوارکننده، اجبار به یکنواختی (monotonic) اثرات ویژگی است، به این معنا که افزایش یک ویژگی باید به افزایش پیش‌بینی منجر شود.

یک نکتهٔ روایی: مقالات ادعا می‌کنند که عملکرد برازش قانون خوب است — اغلب نزدیک به عملکرد پیش‌بینی جنگل تصادفی! — اما در معدود مواردی که شخصاً آن را امتحان کرده‌ام، عملکرد ناامیدکننده بود. پس فقط کافی است برای مسئلهٔ خودتان امتحانش کنید و ببینید چطور عمل می‌کند.

محصول نهایی فرایند برازش قانون یک مدل خطی با ویژگی‌های اضافهٔ فانتزی (قوانین تصمیم) است. اما از آنجا که این یک مدل خطی است، تفسیر وزن‌ها همچنان غیرشهودی است. این مدل همان «پانویس» مدل رگرسیون خطی معمولی را با خود دارد: «... به شرطی که همهٔ ویژگی‌ها ثابت بمانند.» وقتی قوانین همپوشان دارید، این موضوع کمی پیچیده‌تر می‌شود. برای مثال، یکی از قوانین تصمیم (ویژگی‌ها) برای پیش‌بینی دوچرخه می‌تواند این باشد: «temp > 10» و قانون دیگری می‌تواند «temp > 15 & weather='GOOD'» باشد. اگر هوا خوب و دما بالای ۱۵ درجه باشد، دما به‌طور خودکار بالای ۱۰ درجه نیز هست. در مواردی که قانون دوم صدق کند، قانون اول نیز صدق می‌کند. تفسیر وزن برآوردشده برای قانون دوم این است: «با فرض ثابت ماندن همهٔ ویژگی‌های دیگر، پیش‌بینی تعداد دوچرخه‌ها با خوب بودن هوا و دمای بالای ۱۵ درجه به اندازهٔ $\beta_2$ افزایش می‌یابد.» اما اکنون کاملاً روشن می‌شود که عبارت «همهٔ ویژگی‌های دیگر ثابت» مشکل‌ساز است، چون اگر قانون ۲ صدق کند، قانون ۱ نیز صدق می‌کند و این تفسیر بی‌معنا می‌شود.

نرم‌افزار و جایگزین‌ها

الگوریتم برازش قانون در R پیاده‌سازی شده است (Fokkema، ۲۰۲۰ — به پیوست د مراجعه کنید)، و می‌توانید نسخهٔ Python آن را در گیت‌هاب بیابید.

چارچوب بسیار مشابهی به نام skope-rules وجود دارد؛ این ماژول پایتون نیز قوانین را از مجموعه‌های درختی استخراج می‌کند. تفاوت آن در نحوهٔ یادگیری قوانین نهایی است: نخست، skope-rules قوانین با عملکرد پایین را بر اساس آستانه‌های بازخوانی (recall) و دقت (precision) حذف می‌کند. سپس، قوانین تکراری و مشابه با انتخابی بر پایهٔ تنوع جملات منطقی (متغیر + عملگر بزرگ‌تر/کوچک‌تر) و عملکرد (نمرهٔ F1) قوانین حذف می‌شوند. این گام نهایی به Lasso متکی نیست، بلکه فقط بر نمرهٔ F1 خارج از کیسه (out-of-bag) و جملات منطقی تشکیل‌دهندهٔ قوانین تکیه دارد.

بستهٔ imodels نیز پیاده‌سازی‌هایی از دیگر مجموعه‌قوانین، مانند مجموعه‌قوانین بیزی، مجموعه‌قوانین تقویت‌شده (Boosted) و مجموعه‌قوانین SLIPPER را به‌عنوان یک بستهٔ پایتون با رابط یکپارچهٔ scikit-learn در بر دارد. علاوه بر این، تقویت مبتنی بر مدل (model-based boosting) (Bühlmann و Hothorn، ۲۰۰۷ — به پیوست د مراجعه کنید) نیز وجود دارد که امکان ترکیب مؤلفه‌های خطی و مؤلفه‌های قانون را فراهم می‌کند و در بستهٔ R به نام mboost پیاده‌سازی شده است.