داده کاوی، هوش مصنوعی ۵۷۸۱ بازدید

همه کسانی که در حوزه «هوش مصنوعی» (Artificial Intelligence) و «یادگیری ماشین» (Machine Learning) فعالیت دارند، با مسأله انتخاب «ویژگی‌های مرتبط» (Relevant Features) در یک مجموعه داده و حذف یا نادیده گرفتن ویژگی‌های «نامرتبط» (Irrelevant) یا کم اهمیت (که سهم چندانی در پیش بینی درست برچسب کلاس نمونه‌های جدید و به تبع آن، عملکرد مدل‌های یادگیری ندارند) دست و پنجه نرم کرده‌اند. «انتخاب ویژگی» (Feature Selection)، یکی از مفاهیم کلیدی در یادگیری ماشین است. روش های انتخاب ویژگی نقش مهمی در عملکرد بهینه مدل‌های یادگیری دارند.

فهرست مطالب این نوشته

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

اهمیت مرحله انتخاب ویژگی در طراحی مدل‌های یادگیری

تحقیقات انجام شده در زمینه تاثیر انتخاب ویژگی‌های مناسب در عملکرد روش‌های یادگیری ماشین، نشان داده است که انتخاب مجموعه مناسب از ویژگی‌ها در هنگام طراحی مدل‌های یادگیری ماشین، عملکرد، دقت و کارایی روش‌های یادگیری «نظارت شده» (Supervised) و «نظارت نشده» (Unsupervised) را بهبود می‌بخشد. همچنین، وقتی که ابعاد فضای ویژگی داده‌ها بسیار زیاد است و با معضل «نفرین ابعاد بالا» (Curse of Dimensionality) مواجه هستیم، استفاده از مجموعه ویژگی‌های مناسب، «هزینه‌های محاسباتی» (نظیر زمان آموزش و یا منابع) لازم برای آموزش بهینه سیستم را به شدت کاهش می‌دهد. محاسبه درجه اهمیت ویژگی‌ها و استفاده از آن‌ها در مرحله انتخاب ویژگی، گام مهمی در جهت «تفسیرپذیری» (Interpretability) مدل‌های یادگیری ماشین خواهد بود.

روش های انتخاب ویژگی نظارت شده و نظارت نشده

برای انتخاب بهترین ویژگی‌ها برای یک مدل یادگیری نظارت شده، «روش های انتخاب ویژگی نظارت شده» (Supervised Feature Selection) ارائه شده‌اند. هدف این دسته از الگوریتم‌ها، انتخاب بهترین زیر مجموعه از ویژگی‌ها برای تضمین عملکرد بهینه یک مدل نظارت شده (به عنوان نمونه، مسائل دسته‌بندی (Classification) و «رگرسیون» (Regression)) است. این الگوریتم‌ها برای انتخاب بهترین ویژگی‌ها، از «داده‌های برچسب زده» (Labelled Data) استفاده می‌کنند. با این حال، در شرایطی که داده‌های برچسب زده در دسترس نیستند (یادگیری نظارت نشده)، روش‌هایی به نام «روش های انتخاب ویژگی نظارت نشده» (Unsupervised Feature Selection) پیاده‌سازی شده‌اند که ویژگی‌ها را براساس معیارهای مختلفی نظیر «واریانس» (Variance)، آنتروپی (Entropy)، قابلیت ویژگی‌ها در حفظ اطلاعات مرتبط با مشابهت‌های محلی (Local Similarity) و سایر موارد امتیازبندی می‌کنند.

ویژگی‌های مرتبطی که از طریق «فرایندهای مکاشفه‌ای نظارت نشده» (Unsupervised Heuristics) شناسایی شده‌اند، می‌توانند در مدل‌های یادگیری نظارت شده نیز مورد استفاده قرار بگیرند. چنین کاربردهایی از ویژگی‌های شناسایی شده، به سیستم یادگیری نظارت شده اجازه می‌دهد تا علاوه بر شناسایی میزان «همبستگی» (Correlation) ویژگی‌ها با برچسب کلاس داده‌ها، الگوهای دیگری نیز در داده‌های یادگیری شناسایی کنند. از دیدگاه طبقه‌بندی، روش های انتخاب ویژگی را می‌توان در چهار دسته زیر طبقه‌بندی کرد:

  • روش‌های «فیلتر» (Filter)
  • روش‌های «بسته‌بند» (Wrapper)
  • روش‌های «تعبیه شده» (Embedded)
  • روش‌های «ترکیبی» (Hybrid)

روش‌های انتخاب ویژگی بسته‌بند

این دسته از روش های انتخاب ویژگی، در هر مرحله، زیرمجموعه‌ای از ویژگی‌ها در فضای ویژگی را انتخاب می‌کند و عملکرد الگوریتم یادگیری ماشین روی این زیر مجموعه سنجیده می‌شود. از نتیجه عملکرد الگوریتم یادگیری ماشین، برای ارزیابی زیرمجموعه انتخاب شده از فضای ویژگی استفاده می‌شود. به عنوان نمونه، مشخص می‌شود که کدام یک از زیر مجموعه‌های انتخاب شده، بیشترین تاثیر را در افزایش دقت یک مسأله دسته‌بندی خواهند داشت. از این روش مدل‌سازی و جستجوی ویژگی برای انتخاب ویژگی جهت آموزش انواع روش‌های یادگیری ماشین استفاده می‌شود.

انتخاب ویژگی مستقیم

در «روش های انتخاب ویژگی مستقیم» (Forward Feature Selection)، ابتدا یک زیر مجموعه تهی از ویژگی‌ها ساخته می‌شود. سپس در هر مرحله، ویژگی‌هایی که بهترین عملکرد را برای مدل یادگیری به ارمغان می‌آورند، به این زیر مجموعه اضافه می‌شوند. در زبان برنامه نویسی پایتون، از بسته نرم‌افزاری mlxtend برای پیاده‌سازی روش های انتخاب ویژگی مستقیم استفاده می‌شود. در کد زیر، از این روش انتخاب ویژگی جهت آموزش یک «دسته‌بند جنگل تصادفی» (Random Forest) استفاده شده است.

from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier
from sklearn.metrics import roc_auc_score

from mlxtend.feature_selection import SequentialFeatureSelector

feature_selector = SequentialFeatureSelector(RandomForestClassifier(n_jobs=-1),
           k_features=15,
           forward=True,
           verbose=2,
           scoring='roc_auc',
           cv=4)

features = feature_selector.fit(np.array(train_features.fillna(0)), train_labels)

filtered_features= train_features.columns[list(features.k_feature_idx_)]
filtered_features

filtered_features= train_features.columns[list(features.k_feature_idx_)]

clf = RandomForestClassifier(n_estimators=100, random_state=41, max_depth=3)
clf.fit(train_features[filtered_features].fillna(0), train_labels)

train_pred = clf.predict_proba(train_features[filtered_features].fillna(0))
print('Accuracy on training set: {}'.format(roc_auc_score(train_labels, train_pred[:,1])))

test_pred = clf.predict_proba(test_features[filtered_features].fillna(0))
print('Accuracy on test set: {}'.format(roc_auc_score(test_labels, test_pred [:,1])))

در این قطعه کد، متغیر (k_features) تعداد ویژگی‌های انتخابی را نشان می‌دهد. پارامتر (forward) در صورتی که True باشد، برای سیستم مشخص می‌کند که باید از روش مستقیم برای انتخاب ویژگی استفاده شود.

انتخاب ویژگی معکوس

در «روش های انتخاب ویژگی معکوس» (Backward Feature Selection)، ابتدا تمامی ویژگی‌ها در زیر مجموعه حضور دارند. سپس در هر مرحله، بدترین ویژگی‌ها از زیر مجموعه حذف می‌شوند (ویژگی‌هایی که حذف آن‌ها، باعث ایجاد کمترین کاهش در عملکرد، دقت و کارایی روش یادگیری ماشین می‌شوند). در زبان برنامه نویسی پایتون، از بسته نرم‌افزاری mlxtend برای پیاده‌سازی روش های انتخاب ویژگی معکوس استفاده می‌شود. در کد زیر، از این روش انتخاب ویژگی جهت آموزش یک «دسته‌بند جنگل تصادفی» (Random Forest) استفاده شده است.

from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier
from sklearn.metrics import roc_auc_score
from mlxtend.feature_selection import SequentialFeatureSelector

feature_selector = SequentialFeatureSelector(RandomForestClassifier(n_jobs=-1),
           k_features=15,
           forward=False,
           verbose=2,
           scoring='roc_auc',
           cv=4)

features = feature_selector.fit(np.array(train_features.fillna(0)), train_labels)

filtered_features= train_features.columns[list(features.k_feature_idx_)]
filtered_features

clf = RandomForestClassifier(n_estimators=100, random_state=41, max_depth=3)
clf.fit(train_features[filtered_features].fillna(0), train_labels)

train_pred = clf.predict_proba(train_features[filtered_features].fillna(0))
print('Accuracy on training set: {}'.format(roc_auc_score(train_labels, train_pred[:,1])))

test_pred = clf.predict_proba(test_features[filtered_features].fillna(0))
print('Accuracy on test set: {}'.format(roc_auc_score(test_labels, test_pred [:,1])))

در این قطعه کد، متغیر (k_features) تعداد ویژگی‌های انتخابی را نشان می‌دهد. پارامتر (forward) در صورتی که False باشد، برای سیستم مشخص می‌کند که باید از روش معکوس برای انتخاب ویژگی استفاده شود.

روش حذف بازگشتی ویژگی

روش «حذف بازگشتی ویژگی» (Recursive Feature Elimination)، یک روش «حریصانه» (Greedy) برای انتخاب ویژگی است. در این روش، ویژگی‌ها به طور بازگشتی و با در نظر گرفتن مجموعه‌های کوچک و کوچک‌تر از ویژگی‌ها (در هر مرحله) انتخاب می‌شوند. در این روش، ویژگی‌ها بر اساس مرتبه حذف شدن آن‌ها از فضای ویژگی رتبه‌بندی می‌شوند. در زبان برنامه برنامه‌نویسی پایتون، از بسته نرم‌افزاری SciKit-Learn برای حذف بازگشتی ویژگی‌های نامرتبط و انتخاب بهترین ویژگی‌ها استفاده می‌شود. در قطعه کد زیر، از این دسته از روش های انتخاب ویژگی برای انتخاب بهترین ویژگی‌های ممکن جهت «دسته‌بندی ارقام» (Digit Classification) استفاده می‌شود.

from sklearn.svm import SVC
from sklearn.datasets import load_digits
from sklearn.feature_selection import RFE
import matplotlib.pyplot as plt

# Load the digits dataset
digits = load_digits()
X = digits.images.reshape((len(digits.images), -1))
y = digits.target

# Create the RFE object and rank each pixel
svc = SVC(kernel="linear", C=1)
rfe = RFE(estimator=svc, n_features_to_select=1, step=1)
rfe.fit(X, y)
ranking = rfe.ranking_.reshape(digits.images[0].shape)

# Plot pixel ranking
plt.matshow(ranking, cmap=plt.cm.Blues)
plt.colorbar()
plt.title("Ranking of pixels with RFE")
plt.show()

روش های انتخاب ویژگی تعبیه شده

از «روش‌های تعبیه شده» (Embedded Methods)، برای انتخاب ویژگی در الگوریتم‌های یادگیری ماشینی استفاده می‌شود که عملیات انتخاب ویژگی و «برازش مدل» (Model Fitting) در آن‌ها، به صورت همزمان انجام می‌شوند. چنین کاری معمولا از طریق یک روش «تنظیم‌گر پراکندگی» (Sparsity Regularizer) و یا تعریف «قید» (Constraint) قابل انجام است که سبب صفر شدن وزن برخی از ویژگی‌ها می‌شود.

روش رگرسیون لجستیکی چند جمله‌ای اسپارس

در روش «رگرسیون لجستیکی چند جمله‌ای اسپارس» (Sparse Multinomial Logistic Regression)، مکانیزم تنظیم‌گر پراکندگی از طریق تعریف «توزیع احتمال پیشین جهت تعیین خودکار مرتبط بودن» (Automatic Relevance Determination Prior)، برای یک روش رگرسیون لجستیکی چند جمله‌ای کلاسیک پیاده‌سازی می‌شود. مکانیزم تنظیم‌گر پراکندگی، اهمیت هر کدام از ویژگی‌ها را تخمین می‌زند و ویژگی‌هایی که برای پیش‌بینی مفید نیستند را هرس می‌کند. پیاده‌سازی کامل این دسته از روش های انتخاب ویژگی در زبان برنامه‌نویسی پایتون، از طریق [+] قابل دسترس است.

روش رگرسیون تعیین خودکار مرتبط بودن

روش «رگرسیون تعیین خودکار مرتبط بودن» (Automatic Relevance Determination Regression)، یک روش مبتنی بر «رگرسیون ستیغی بیزی» (Bayesian Ridge Regression) است. این مدل انتخاب ویژگی، وزن‌های ویژگی‌ها را بیش از دیگر مدل‌های رگرسیونی دیگر نظیر «رگرسیون کمترین توان‌های دوم عادی» (Ordinary Least Square Regression)، به سمت صفر سوق می‌دهد (به شکل‌های زیر دقت کنید).

روش های انتخاب ویژگی (Feature Selection Methods)

روش های انتخاب ویژگی (Feature Selection Methods)

همانطور که در شکل بالا مشاهده می‌شود، «قید پراکندگی» (Sparsity Constraint) روش رگرسیون تعیین خودکار مرتبط بودن، وزن برخی از ویژگی‌ها را صفر می‌کند و از این طریق، ویژگی‌های مرتبط در فضای ویژگی را تعیین می‌کند. در قطعه کد زیر، روش های انتخاب ویژگی «رگرسیون تعیین خودکار مرتبط بودن»، با روش های انتخاب ویژگی «رگرسیون کمترین توان‌های دوم عادی» مقایسه شده‌اند. در این قطعه کد، ابتدا یک فضای ویژگی (100×100) به‌طور تصادفی و از طریق توزیع گوسی تولید می‌شود. هدف پیدا کردن زیر مجموعه‌ای از 10 ویژگی مهم و مرتبط از فضای ویژگی مسأله است. برای پیاده‌سازی این قطعه کد، از  بسته نرم‌افزاری SciKit-Learn پایتون استفاده شده است.

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

from sklearn.linear_model import ARDRegression, LinearRegression

# #############################################################################
# Generating simulated data with Gaussian weights

# Parameters of the example
np.random.seed(0)
n_samples, n_features = 100, 100
# Create Gaussian data
X = np.random.randn(n_samples, n_features)
# Create weights with a precision lambda_ of 4.
lambda_ = 4.
w = np.zeros(n_features)
# Only keep 10 weights of interest
relevant_features = np.random.randint(0, n_features, 10)
for i in relevant_features:
    w[i] = stats.norm.rvs(loc=0, scale=1. / np.sqrt(lambda_))
# Create noise with a precision alpha of 50.
alpha_ = 50.
noise = stats.norm.rvs(loc=0, scale=1. / np.sqrt(alpha_), size=n_samples)
# Create the target
y = np.dot(X, w) + noise

# #############################################################################
# Fit the ARD Regression
clf = ARDRegression(compute_score=True)
clf.fit(X, y)

ols = LinearRegression()
ols.fit(X, y)

# #############################################################################
# Plot the true weights, the estimated weights, the histogram of the
# weights, and predictions with standard deviations
plt.figure(figsize=(6, 5))
plt.title("Weights of the model")
plt.plot(clf.coef_, color='darkblue', linestyle='-', linewidth=2,
         label="ARD estimate")
plt.plot(ols.coef_, color='yellowgreen', linestyle=':', linewidth=2,
         label="OLS estimate")
plt.plot(w, color='orange', linestyle='-', linewidth=2, label="Ground truth")
plt.xlabel("Features")
plt.ylabel("Values of the weights")
plt.legend(loc=1)

plt.figure(figsize=(6, 5))
plt.title("Histogram of the weights")
plt.hist(clf.coef_, bins=n_features, color='navy', log=True)
plt.scatter(clf.coef_[relevant_features], np.full(len(relevant_features), 5.),
            color='gold', marker='o', label="Relevant features")
plt.ylabel("Features")
plt.xlabel("Values of the weights")
plt.legend(loc=1)

plt.figure(figsize=(6, 5))
plt.title("Marginal log-likelihood")
plt.plot(clf.scores_, color='navy', linewidth=2)
plt.ylabel("Score")
plt.xlabel("Iterations")


# Plotting some predictions for polynomial regression
def f(x, noise_amount):
    y = np.sqrt(x) * np.sin(x)
    noise = np.random.normal(0, 1, len(x))
    return y + noise_amount * noise


degree = 10
X = np.linspace(0, 10, 100)
y = f(X, noise_amount=1)
clf_poly = ARDRegression(threshold_lambda=1e5)
clf_poly.fit(np.vander(X, degree), y)

X_plot = np.linspace(0, 11, 25)
y_plot = f(X_plot, noise_amount=0)
y_mean, y_std = clf_poly.predict(np.vander(X_plot, degree), return_std=True)
plt.figure(figsize=(6, 5))
plt.errorbar(X_plot, y_mean, y_std, color='navy',
             label="Polynomial ARD", linewidth=2)
plt.plot(X_plot, y_plot, color='gold', linewidth=2,
         label="Ground Truth")
plt.ylabel("Output y")
plt.xlabel("Feature X")
plt.legend(loc="lower left")
plt.show()

روش‌های انتخاب ویژگی فیلتر

در این دسته از روش های انتخاب ویژگی، اهمیت ویژگی‌ها بر اساس مشخصات ذاتی آن‌ها و بدون استفاده از الگوریتم‌های یادگیری (جهت سنجش کیفیت ویژگی‌های انتخابی) ارزیابی می‌شوند. چنین الگوریتم‌هایی نسبت به روش‌های بسته‌بند سریعتر هستند و بار محاسباتی کمتری را به سیستم تحمیل می‌کنند. اگر داده کافی برای مدل‌سازی «همبستگی آماری» (Statistical Correlation) میان ویژگی‌ها وجود نداشته باشد، روش‌های فیلتر نتایج به مراتب بدتری نسبت به روش‌های بسته‌بند ارائه می‌کنند. برخلاف روش‌های بسته‌بند، روش های انتخاب ویژگی فیلتر در معرض «بیش برازش» (Overfitting) قرار نمی‌گیرند. این دسته روش‌ها بیشتر زمانی به کار گرفته می‌شوند که استفاده از روش‌های بسته‌بند برای انتخاب ویژگی، بار محاسباتی فوق‌العاده زیادی به سیستم تحمیل می‌کنند. به ویژه زمانی که ابعاد فضای ویژگی بسیار زیاد باشد (داده‌ها با ابعاد بالا) و استفاده از روش‌های بسته‌بند از لحاظ محاسباتی مقرون به صرفه نباشد، از روش‌های فیلتر به‌وفور استفاده می‌شود.

روش‌های انتخاب ویژگی نظارت شده

در این بخش، مهم‌ترین روش‌های فیلتر نظارت شده برای انتخاب ویژگی مورد بحث و بررسی قرار می‌گیرند.

روش انتخاب ویژگی Relief

در این روش، در هر مرحله و به طور تصادفی، یک نمونه از میان نمونه‌های موجود در مجموعه داده انتخاب می‌شود. سپس، میزان مرتبط بودن هر کدام از ویژگی‌ها، بر اساس اختلاف میان نمونه انتخاب شده و دو نمونه همسایه نزدیک (کلاس نمونه‌ اول، مشابه کلاس نمونه انتخابی و کلاس نمونه دوم، مخالف کلاس نمونه انتخابی است) به روز رسانی می‌شود. اگر یکی از ویژگی‌های نمونه انتخاب شده با ویژگی‌ مشابه در نمونه همسایه از کلاس مشابه (نمونه Hit) اختلاف داشته باشد، امتیاز این ویژگی کاهش می‌یابد. از سوی دیگر، اگر همان ویژگی در نمونه انتخاب شده با ویژگی‌ مشابه در نمونه همسایه از کلاس مخالف (نمونه Miss) اختلاف داشته باشد، امتیاز این ویژگی افزایش می‌یابد.

$$W _ { i } = W _ { i } – ( x _ { i } – nearHit _ { i }) ^ { 2 } + ( x _ { i } – nearMiss _ { i }) ^ { 2 }$$

همان طور که در رابطه بالا مشخص است، در صورتی اختلاف میان یک ویژگی در نمونه انتخاب شده و ویژگی مشابه در نمونه کلاس مشابه، بیشتر از اختلاف میان همان ویژگی در نمونه انتخاب شده با ویژگی مشابه در نمونه کلاس مخالف باشد، وزن (درجه اهمیت) این ویژگی کاهش می‌یابد و برعکس. در الگوریتم ReleifF، که گسترشی از الگوریتم Relief محسوب می‌شود، نمونه‌های همسایه بیشتری برای به روز رسانی وزن‌ها جستجو می‌شوند. پیاده‌سازی کامل این دسته از روش های انتخاب ویژگی در زبان برنامه‌نویسی پایتون، از طریق [+] قابل دسترس است.

روش انتخاب ویژگی امتیاز فیشر (Fisher)

از این روش انتخاب ویژگی، بیشتر برای مقاصد «دسته‌بندی باینری» (Binary Classification) استفاده می‌شود. در این دسته از روش های انتخاب ویژگی، «نسبت فیشر» (FiR) در قالب «فاصله میان میانگین نمونه کلاس‌ها (مثبت و منفی) به ازای یک ویژگی خاص» تقسیم بر «واریانس کلاس‌ها (مثبت و منفی) به ازای همان ویژگی» تعریف می‌شود. از طریق این روش، میزان اهمیت (وزن) هر ویژگی مشخص می‌شود.

$$FiR _ { i } = \frac { \mid \overline { X _ i ^ { (0) } } – \overline { X _ i ^ { (1) } } \mid } { \sqrt { Var ( X_{i} ) ^ { (0) } + Var ( X _ { i } )^{ (1) } } }$$

روش انتخاب ویژگی امتیاز کای 2 (Chi-squared)

این روش انتخاب ویژگی، اختلاف معنادار میان «تناوب مشاهده شده» (Observed Frequency) و «تناوب مورد انتظار» (Expected Frequency) دو ویژگی «دسته‌ای» (Categorical) را می‌سنجد. «فرض صفر» (Null Hypothesis) در این روش بیان می‌کند که هیچ‌گونه همبستگی (تناظری) میان این دو متغیر وجود ندارد. این روش، به «آزمون مستقل بودن کای 2» (Chi-square Test of Independence) نیز مشهور است.

$$X ^ { 2 } = \frac { (Observed \; Frequency – Expected \; Frequency ) ^ { 2 } } { Expected \; Frequency }$$

برای اینکه بتوان به درستی از این رابطه، برای سنجش رابطه میان ویژگی‌های مختلف موجود در یک مجموعه داده و ویژگی هدف (که به آن، متغیر کلاس یا Target نیز گفته می‌شود) استفاده کرد، باید دو شرط زیر برقرار باشد:

  • ویژگی‌ها باید دسته‌ای باشند.
  • ویژگی‌ها باید مستقل از یکدیگر نمونه‌گیری شده باشند.
  • تناوب مورد انتظار متغیرها بزرگتر از پنج باشد.

شرط آخر تضمین می‌کند که «تابع توزیع تجمعی» (Cumulative Distribution Function) آماره‌های آزمون کای 2، از طریق توزیع کای 2 (Chi-square Distribution) «قابل تقریب زدن» (Approximation) خواهد بود. در زبان برنامه برنامه‌نویسی پایتون، از بسته نرم‌افزاری SciKit-Learn برای انتخاب بهترین ویژگی‌ها به روش امتیاز کای 2 استفاده می‌شود. در قطعه کد زیر، از این روش انتخاب ویژگی‌های برای انتخاب 2 ویژگی برتر در مجموعه داده iris استفاده شده است.

from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
iris = load_iris()
X, y = iris.data, iris.target
X.shape

X_new = SelectKBest(chi2, k=2).fit_transform(X, y)
X_new.shape

روش انتخاب ویژگی مبتنی بر همبستگی (Correlation-based)

در این روش انتخاب ویژگی، به زیرمجموعه‌ای از ویژگی‌ها، یک زیرمجموعه خوب گفته می‌شود که ویژگی‌های موجود در آن، از یک سو، همبستگی بالایی با «دسته‌بندی» (Classification) یا ویژگی هدف داشته باشند و از سوی دیگر، با یکدیگر «ناهمبسته» (Uncorrelated) باشند. میزان «شایستگی» (Merit) یا خوب بودن یک زیرمجموعه از ویژگی‌ها، از طریق رابطه زیر محاسبه می‌شود:

$$Merit _ { S _ { k }}= \frac { k \overline {r} _ {cf} } { \sqrt {k+k(k-1) \overline{r} _ {ff} } }$$

در این رابطه، $$\overline {r} _ {cf}$$ مقدار میانگین همبستگی محاسبه شده میان ویژگی هدف و تمامی ویژگی‌های موجود در مجموعه داده و $$\overline{r} _ {ff}$$ مقدار میانگین همبستگی یک به یک محاسبه شده میان ویژگی‌ها است. در نهایت، روش مبتنی بر همبستگی به شکل زیر فرموله می‌شود:

$$CFS = max _ {S _ { k } } \left [ \frac { r_ { cf_ {1} }+ r_{ cf_ {2} }+ …… + r_ { cf_{k} } }{ \sqrt {k + 2 (r_ {f_ {2} f_ {1} }+ …. +r_ {f_ {i} f_ {j} }+ ….. +r_ {f_ {k} f_ {1} } ) } } \right]$$

در این رابطه، به متغیرهای $$r_ { cf_ {i}}$$ و $$r_ {f_ {i} f_ {j} }$$، مقدار همبستگی گفته می‌شود. در زبان برنامه برنامه‌نویسی پایتون، از بسته نرم‌افزاری scikit-learn برای انتخاب بهترین ویژگی‌ها به روش مبتنی بر همبستگی استفاده می‌شود. در قطعه کد زیر، از روش مبتنی بر همبستگی برای انتخاب 5 ویژگی برتر از یک مجموعه داده استفاده شده است. در مرحله بعد، از ویژگی‌های انتخاب شده برای آموزش و تست یک مدل «ماشین بردار پشتیبان» (Support Vector Machine) استفاده می‌شود.

from sklearn import svm
from sklearn.metrics import accuracy_score
import numpy as np
from skfeature.function.similarity_based import fisher_score
score = fisher_score.fisher_score(X_train, y_train)
idx = fisher_score.feature_ranking(score)
num_fea = 5
selected_features_train = X_train[:, idx[0:num_fea]]
selected_features_test = X_test[:, idx[0:num_fea]]
clf.fit(selected_features_train, y_train)
y_predict = clf.predict(selected_features_test)
acc = accuracy_score(y_test, y_predict)

روش انتخاب ویژگی فیلتر مبتنی بر همبستگی سریع

روش فیلتر مبتنی بر همبستگی سریع (Fast Correlation-based Filter)، سرعت و کارایی بهتری نسبت به روش‌های انتخاب ویژگی ReliefF و «مبتنی بر همبستگی» از خود نشان می‌دهد. در نتیجه، به شکل بهتری می‌تواند خود را با داده‌های با ابعاد بالا منطبق و ویژگی‌های به مراتب بهتری را از داده‌های ورودی انتخاب کند. در این روش، ابتدا مقدار «عدم حتمیت نامتقارن» (Symmetrical Uncertainty) برای تمامی ویژگی‌ها محاسبه می‌شود. این مقدار، از طریق محاسبه «بهره اطلاعاتی x به شرط y» تقسیم بر «مجموع کل آنتروپی تمامی ویژگی‌ها» به دست می‌آید. سپس، مقادیر عدم حتمیت نامتقارن، مرتب‌سازی و ویژگی‌های «زائد» (Redundant) حذف می‌شوند. در زبان برنامه برنامه‌نویسی پایتون، می‌توان از بسته نرم‌افزاری skfeature برای پیاده‌سازی فیلتر مبتنی بر همبستگی سریع استفاده کرد.

import numpy as np
from skfeature.utility.mutual_information import su_calculation


def fcbf(X, y, **kwargs):
    """
    This function implements Fast Correlation Based Filter algorithm
    Input
    -----
    X: {numpy array}, shape (n_samples, n_features)
        input data, guaranteed to be discrete
    y: {numpy array}, shape (n_samples,)
        input class labels
    kwargs: {dictionary}
        delta: {float}
            delta is a threshold parameter, the default value of delta is 0
    Output
    ------
    F: {numpy array}, shape (n_features,)
        index of selected features, F[0] is the most important feature
    SU: {numpy array}, shape (n_features,)
        symmetrical uncertainty of selected features
    Reference
    ---------
        Yu, Lei and Liu, Huan. "Feature Selection for High-Dimensional Data: A Fast Correlation-Based Filter Solution." ICML 2003.
    """

    n_samples, n_features = X.shape
    if 'delta' in kwargs.keys():
        delta = kwargs['delta']
    else:
        # the default value of delta is 0
        delta = 0

    # t1[:,0] stores index of features, t1[:,1] stores symmetrical uncertainty of features
    t1 = np.zeros((n_features, 2), dtypes='object')
    for i in range(n_features):
        f = X[:, i]
        t1[i, 0] = i
        t1[i, 1] = su_calculation(f, y)
    s_list = t1[t1[:, 1] > delta, :]
    # index of selected features, initialized to be empty
    F = []
    # Symmetrical uncertainty of selected features
    SU = []
    while len(s_list) != 0:
        # select the largest su inside s_list
        idx = np.argmax(s_list[:, 1])
        # record the index of the feature with the largest su
        fp = X[:, s_list[idx, 0]]
        np.delete(s_list, idx, 0)
        F.append(s_list[idx, 0])
        SU.append(s_list[idx, 1])
        for i in s_list[:, 0]:
            fi = X[:, i]
            if su_calculation(fp, fi) >= t1[i, 1]:
                # construct the mask for feature whose su is larger than su(fp,y)
                idx = s_list[:, 0] != i
                idx = np.array([idx, idx])
                idx = np.transpose(idx)
                # delete the feature by using the mask
                s_list = s_list[idx]
                length = len(s_list)//2
                s_list = s_list.reshape((length, 2))
    return np.array(F, dtype=int), np.array(SU)

روش‌های انتخاب ویژگی نظارت نشده

در این بخش، مهم‌ترین روش‌های فیلتر نظارت نشده برای انتخاب ویژگی مورد بحث و بررسی قرار می‌گیرند.

روش انتخاب ویژگی واریانس

روش «واریانس» (Variance)، یکی از روش‌های فیلتر نظارت نشده برای انتخاب ویژگی است. این روش، یکی از بهترین و موثرترین روش‌ها برای انتخاب ویژگی‌های مرتبطی است که معمولا امتیاز واریانس بالاتری دارند. در زبان برنامه برنامه‌نویسی پایتون، می‌توان از بسته نرم‌افزاری scikit-feature برای پیاده‌سازی فیلتر واریانس استفاده کرد. به عنوان نمونه، در کد زیر، یک مجموعه داده حاوی مقادیر ویژگی صحیح تعریف شده است. در هر نمونه از این مجموعه داده، دو ویژگی یکسان وجود دارد. روش واریانس به راحتی قادر خواهد بود تا ویژگی‌های یکسان در نمونه‌ها را حذف کند.

X = [[0, 2, 0, 3], [0, 1, 4, 3], [0, 1, 1, 3]]
selector = VarianceThreshold()
selector.fit_transform(X)

روش انتخاب ویژگی میانگین قدر مطلق تفاضل‌ها

در این روش، «میانگین قدر مطلق تفاضل‌ها» (Mean Absolute Difference) برای ویژگی‌های موجود در مجموعه داده، با استفاده «مقدار میانگین» (Mean Value) ویژگی‌ها محاسبه می‌‌شوند. ویژگی‌هایی که میانگین قدر مطلق تفاضل بالاتری داشته باشند، «قدرت متمایز کنندگی» (Discriminative Power) بالاتری خواهند داشت؛ در نتیجه، ویژگی‌های مرتبط‌تری هستند.

$$MAD _ { i } = \frac { 1 } { n } \sum _ { j = 1 } ^ n \mid X _ { ij } – \overline { X_ { i } } \mid$$

از طریق کد زیر در برنامه‌نویسی پایتون، می‌توان درجه اهمیت یا مرتبط بودن ویژگی‌ها را با استفاده از میانگین قدر مطلق تفاضل‌ها محاسبه کرد.

mad = np.sum(np.abs(data -np.mean(data, axis =0 )), axis = 0)/data.shape[0]

روش انتخاب ویژگی نسبت پراکندگی

روش «نسبت پراکندگی» (Dispersion Ratio)، از طریق محاسبه میانگین ریاضی (Arithmetic Mean)، تقسیم بر، «میانگین هندسی» (Geometric Mean) هر ویژگی، درجه اهمیت یا مرتبط بودن یک ویژگی را مشخص می‌کند. نسبت پراکندگی بالاتر برای یک ویژگی، به معنای مرتبط‌تر بودن آن ویژگی نسبت به دیگر ویژگی‌های موجود در مجموعه داده است.

$$AM_{i}= \overline{X}_{i}=\frac{1}{n}\sum_{j=1}^n X_{ij}, \;\;\;\; GM_{i}=\left( \prod_{j=1}^n X_{ij}\right)^{\frac{1}{\pi}}$$

$$R _ { i }= \frac { AM _ { i }} { GM { i } } \in \left [ 1, \infty \right]$$

از طریق کد زیر در برنامه‌نویسی پایتون، می‌توان درجه اهمیت یا مرتبط بودن ویژگی‌ها را با استفاده از روش نسبت پراکندگی محاسبه کرد.

def dispersion(data):
    data = data +1 #avoid 0 division
    aritmeticMean = np.mean(data, axis =0 )
    geometricMean = np.power(np.prod(data, axis =0 ),1/data.shape[0])
    R = aritmeticMean/geometricMean
    return R

R = dispersion(data)

روش انتخاب ویژگی امتیاز لاپلاسین

روش «امتیاز لاپلاسین» (Laplacian Score)، بر پایه این مشاهده بنا نهاده شده است که داده‌های یک کلاس یکسان، معمولا در همسایگی یکدیگر در فضای ویژگی قرار دارند؛ در نتیجه اهمیت (مرتبط بودن) یک ویژگی را می‌توان از طریق محاسبه قدرت این ویژگی در حفظ اطلاعات «محلیت» (Locality) نمونه‌ها سنجید. در این روش، ابتدا نمونه‌ها با استفاده از یک معیار فاصله دلخواه به یک «گراف نزدیک‌ترین همسایه» (Nearest Neighbor Graph) نگاشت می‌شوند. سپس، ماتریس وزن محاسبه می‌شود. در مرحله بعد، امتیاز لاپلاسین برای هر کدام از ویژگی‌ها محاسبه می‌شود. ویژگی‌هایی که اهمیت بیشتری (مرتبط‌تر) نسبت به دیگر ویژگی‌ها داشته باشند، امتیاز لاپلاسین کمتری نسبت به دیگر ویژگی‌ها خواهند داشت و برعکس. با این حال در پایان، برای مشخص کردن بهترین زیر مجموعه از ویژگی‌ها، از یک روش «خوشه‌بندی» (Clustering) نظیر K-Means استفاده می‌شود. در زبان برنامه برنامه‌نویسی پایتون، می‌توان از بسته نرم‌افزاری skfeature، برای پیاده‌سازی فیلتر امتیاز لاپلاسین استفاده کرد.

import numpy as np
from scipy.sparse import *
from skfeature.utility.construct_W import construct_W


def lap_score(X, **kwargs):
    """
    This function implements the laplacian score feature selection, steps are as follows:
    1. Construct the affinity matrix W if it is not specified
    2. For the r-th feature, we define fr = X(:,r), D = diag(W*ones), ones = [1,...,1]', L = D - W
    3. Let fr_hat = fr - (fr'*D*ones)*ones/(ones'*D*ones)
    4. Laplacian score for the r-th feature is score = (fr_hat'*L*fr_hat)/(fr_hat'*D*fr_hat)
    Input
    -----
    X: {numpy array}, shape (n_samples, n_features)
        input data
    kwargs: {dictionary}
        W: {sparse matrix}, shape (n_samples, n_samples)
            input affinity matrix
    Output
    ------
    score: {numpy array}, shape (n_features,)
        laplacian score for each feature
    Reference
    ---------
    He, Xiaofei et al. "Laplacian Score for Feature Selection." NIPS 2005.
    """

    # if 'W' is not specified, use the default W
    if 'W' not in kwargs.keys():
        W = construct_W(X)
    # construct the affinity matrix W
    W = kwargs['W']
    # build the diagonal D matrix from affinity matrix W
    D = np.array(W.sum(axis=1))
    L = W
    tmp = np.dot(np.transpose(D), X)
    D = diags(np.transpose(D), [0])
    Xt = np.transpose(X)
    t1 = np.transpose(np.dot(Xt, D.todense()))
    t2 = np.transpose(np.dot(Xt, L.todense()))
    # compute the numerator of Lr
    D_prime = np.sum(np.multiply(t1, X), 0) - np.multiply(tmp, tmp)/D.sum()
    # compute the denominator of Lr
    L_prime = np.sum(np.multiply(t2, X), 0) - np.multiply(tmp, tmp)/D.sum()
    # avoid the denominator of Lr to be 0
    D_prime[D_prime < 1e-12] = 10000

    # compute laplacian score for all features
    score = 1 - np.array(np.multiply(L_prime, 1/D_prime))[0, :]
    return np.transpose(score)


def feature_ranking(score):
    """
    Rank features in ascending order according to their laplacian scores, the smaller the laplacian score is, the more
    important the feature is
    """
    idx = np.argsort(score, 0)
    return idx

ترکیب روش امتیاز لاپلاسین با روش آنتروپی مبتنی بر فاصله برای انتخاب ویژگی

این روش انتخاب ویژگی، بر پایه روش امتیاز لاپلاسین بنا نهاده شده است. با این تفاوت که در پایان، برای مشخص کردن بهترین زیر مجموعه از ویژگی‌ها، از روش «آنتروپی مبتنی بر فاصله» (Distance-based Entropy) به جای روش خوشه‌بندی K-Means استفاده می‌شود. این روش، عملکرد و پایداری بهتری در انتخاب بهترین ویژگی‌ها در مجموعه داده‌های با ابعاد بالا (High-Dimensional Datasets) از خود نشان داده است. در زبان برنامه برنامه‌نویسی پایتون، می‌توان از بسته نرم‌افزاری skfeature برای پیاده‌سازی فیلتر امتیاز لاپلاسین استفاده کرد. شایان توجه است که در این قطعه کد، از توابع پیاده‌سازی برای روش امتیاز لاپلاسین (کدهای روش امتیاز لاپلاسین) جهت محاسبه درجه اهمیت (مرتبط بودن) ویژگی‌ها استفاده می‌شود.

def distanceEntropy(d, mu = 0.5, beta=10):
    """
    As per: An Unsupervised Feature Selection Algorithm: Laplacian Score Combined with
    Distance-based Entropy Measure, Rongye Liu 
    """
    if d<=mu:
        result = (np.exp(beta * d) - np.exp(0))/(np.exp(beta * mu) - np.exp(0))
    else:
        result = (np.exp(beta * (1-d) )- np.exp(0))/(np.exp(beta *(1- mu)) - np.exp(0))              
    return result

def lse(data, ls):
    """
    This method takes as input a dataset, its laplacian scores for all features
    and applies distance based entropy feature selection in order to identify
    the best subset of features in the laplacian sense.
    """
    orderedFeatures = np.argsort(ls)
    scores = {}
    for i in range (2,len(ls)):
        selectedFeatures = orderedFeatures[:i]
        selectedFeaturesDataset = data[:, selectedFeatures]
        d =sklearn.metrics.pairwise_distances(selectedFeaturesDataset, metric = 'euclidean' )
        beta =10
        mu = 0.5

        d = preprocessing.MinMaxScaler().fit_transform(d)
        e = np.vectorize(distanceEntropy)(d) 
        e = preprocessing.MinMaxScaler().fit_transform(e)
        totalEntropy= np.sum(e)
        scores[i] = totalEntropy
    bestFeatures = orderedFeatures[:list(scores.keys())[np.argmin(scores.values())]]
    return bestFeatures

selectedFeatures = lse(data, ls)

روش انتخاب ویژگی چند خوشه‌ای

در روش «انتخاب ویژگی چند خوشه‌ای» (Multi-Cluster Feature selection)، یک «تحلیل طیفی» (Spectral Analysis) با هدف اندازه‌گیری همبستگی میان ویژگی‌های مختلف انجام می‌شود. بهترین «بردارهای ویژه» تولید شده از ماتریس لاپلاسین، برای خوشه‌بندی داده‌ها و محاسبه امتیاز برای هر کدام از ویژگی‌ها مورد استفاده قرار می‌گیرند. ویژگی مهم این روش، انتخاب بهترین ویژگی‌ها برای حفظ ساختار چند کلاستری داده‌ها در یادگیری نظارت نشده است. پیاده‌سازی کامل این روش انتخاب ویژگی در زبان برنامه‌نویسی پایتون، از طریق [+] قابل دسترس است.

import numpy as np
from fsfc.generic import NormalizedCut
from sklearn.pipeline import Pipeline
from sklearn.cluster import KMeans

data = np.array([...])

pipeline = Pipeline([
    ('select', NormalizedCut(3)),
    ('cluster', KMeans())
])
pipeline.fit_predict(data)

روش‌های انتخاب ویژگی ترکیبی

گزینه دیگر برای انتخاب بهترین ویژگی‌ها، ترکیب روش‌های فیلتر و بسته‌بند است. در چنین روش‌هایی از یک فرآیند دو مرحله‌ای برای ترکیب دو روش فیلتر و بسته‌بند استفاده می‌شود. در مرحله اول، ویژگی‌ها بر اساس مشخصه‌های آماری فیلتر می‌شوند. در مرحله بعد، با استفاده از یک روش انتخاب ویژگی بسته‌بند، بهترین ویژگی‌ها برای آموزش یک مدل یادگیری انتخاب می‌شوند.

اگر نوشته بالا برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

^^

بر اساس رای ۱۱ نفر
آیا این مطلب برای شما مفید بود؟
شما قبلا رای داده‌اید!
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.

«مرتضی جادریان»، دانشجوی مقطع دکتری مهندسی کامپیوتر گرایش هوش مصنوعی است. او در زمینه سیستم‌های هوشمند، به ویژه سیستم‌های هوشمند اطلاعاتی، روش‌های یادگیری ماشین، سیستم‌های دانش محور و محاسبات تکاملی فعالیت دارد.

3 نظر در “روش های انتخاب ویژگی در پایتون — راهنمای جامع

  • سلام، روز بخیر
    به فرض اگر ما تعداد ۲۰۰ عدد شاخص داشته باشیم، مرتبط با زنجیره تامین، به طور مثال قدرت مالی، نیروی کار چند مهارته، سرعت پاسخ، تعداد گواهی های کیفی و… که هر کدام از اینها به یکی از پارادایم های تاب اوری، چابکی، ناب و سبز متعلق هستند.
    حال اگر بخوایم از بین این ۲۰۰ شاخص ارزیابی، حداکثر تعداد ۱۵ عدد را اتتخاب کنیم، به عنوان ورودی چه چیزی باید برای مدل تعریف کنیم که خروجی ما ۱۵ شاخص مهم باشد؟
    منظور بنده این هست که در مدل های نظارت شده، مثلا در مثال معروف گل زنبق به عنوان داده امورش تعدادی داده به مدل میدهیم تا مدل متوجه شود که کدام مشخصات برای چه نوع گلی است، تا در انتها با توانایی تشخیص انواع مختلف گل زنبق را داشته باشد. حال در اینجا، چه چیزی باید تعریف کرد که مدل متوجه شود ما به دنبال چه چیزی هستیم؟

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد.

برچسب‌ها

مشاهده بیشتر