40 گام به سوی آینده‌ای هوشمند - مجموعه وبینارهای رایگان در حوزه هوش مصنوعی
Filter by دسته‌ها
chatGTP
آموزش هوش مصنوعی و انواع آن
آموزش‌های پایه‌ای هوش مصنوعی
اصول هوش مصنوعی
پایتون و ابزارهای یادگیری عمیق
کتابخانه‌ های یادگیری عمیق
یادگیری با نظارت
یادگیری بدون نظارت
یادگیری تقویتی
یادگیری عمیق
یادگیری نیمه نظارتی
آموزش‌های پیشرفته هوش مصنوعی
بینایی ماشین
پردازش زبان طبیعی
پردازش گفتار
چالش‌های عملیاتی
داده کاوی و بیگ دیتا
رایانش ابری و HPC
سیستم‌‌های امبدد
علوم شناختی
دیتاست
اخبار
تیتر یک
رسانه‌ها
آموزش پردازش زبان طبیعی
آموزش علوم داده
اینفوگرافیک
پادکست
ویدیو
رویدادها
کاربردهای هوش مصنوعی
کسب‌و‌کار
تحلیل بازارهای هوش مصنوعی
کارآفرینی
هوش مصنوعی در ایران
هوش مصنوعی در جهان
 مدیریت دیتاست‌های نامتوازن در مسائل رده‌بندی دودویی (بخش سوم)

مدیریت دیتاست‌های نامتوازن در مسائل رده‌بندی دودویی (بخش سوم)

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

در این نوشتار که قسمت سوم است، یکی دیگر از روش‌هایی را بررسی می‌کنیم که مستقیماً بر روی خود الگوریتم مداخله می‌کند؛ این تکنیک با تابع زیان الگوریتم سروکار دارد.

ایده‌ کلی این تکنیک، مشابه با روش نقطه‌برش است که در قسمت قبلی توضیح دادیم. اگر چنین دیتاست نامتوازنی داشته باشیم:

تارگت کانت

هدف این است که الگوریتم قادر باشد منفی‌ها (نمونه‌های کلاس 0) را نیز به‌درستی و با احتمال بالا تشخیص دهد و رده‌بندی کند، حتی اگر این کار به قیمت رده‌بندی اشتباه چند نمونه از کلاس مثبت (کلاس 1) تمام شود. این کار را می‌توان با نامتقارن کردن تابع زیان انجام داد.

در این مثال، از تابع زیان آنتروپی متقاطع دودویی استفاده می‌کنیم، چون مسئله‌ای که در دست داریم، یک مسئله‌ رده‌بندی دودویی است:

رده بندی دودویی

توجه داشته باشید که p(x) مقدار پیش‌بینی‌شده‌ y است. اینجا p(x) را احتمال قرارگیری نمونه در کلاس 1 در نظر می‌گیریم و احتمال قرارگیری در کلاس 0 مکمل این مقدار یعنی 1-p(x) است.

هدف این است که مثبت‌های کاذب را بیشتر از منفی‌های کاذب جریمه کنیم؛ چون می‌خواهیم الگوریتم را وادار کنیم، منفی‌های حقیقی را به‌درستی رده‌بندی کند. بدین منظور، می‌توانیم دو جزء تابع آنتروپی متقاطع را به نحوی وزن‌دهی کنیم که جزء دوم سنگین‌تر باشد:

تابع آنتروپی متقاطع

در این معادله، w_2>w_1

برای درک بهتر تغییرات جریمه‌ مربوط به یک نمونه‌ مثبت کاذب، به تصاویر زیر دقت کنید:

دودویی

یک نمونه‌ پیش‌بینی‌شده از y داریم: 8/0=p(red)؛ پس با اینکه این نمونه در واقع متعلق به کلاس 0 است، ولی در کلاس 1 زده بندی شده است (مثبت کاذب). در شکل سمت راست، جریمه‌ تابع زیان متقارن را می‌بینید که کمتر از تابع زیان نامتقارن است (61/1 < 22/3). دلیل این مسئله این است که می‌خواهیم خطای چنین رده‌بندی اشتباهی را خیلی بیشتر از خطای یک منفی کاذب جریمه کنیم.

پیاده‌سازی در پایتون

برای پیاده‌سازی در پایتون از Keras به‌عنوان یک رده بند دودویی برای داده‌های مصنوعی خود استفاده می‌کنیم. بدین ترتیب، به‌سادگی می‌توانیم هنگام کامپایل کردن مدل، یک تابع سفارشی را به‌عنوان تابع زیان وارد کنیم.

ابتدا دیتاست نامتوازن خود را تعریف می‌کنیم و آن را به دو مجموعه‌ آموزشی و آزمایشی تقسیم می‌کنیم:

from sklearn.datasets import make_classification
import pandas as pdX, y_tmp = make_classification(
    n_classes=2, class_sep=1, weights=[0.98, 0.02],
    n_informative=10, n_redundant=0,n_repeated=0, 
    n_features=10,  
    n_samples=10000, random_state=123
)#little trick for terminlogy purpose (positive class = 1, negative class = 0)y = y_tmp.copy()
for i in range(len(y_tmp)):
  if y_tmp[i]==0:
    y[i] = 1
  else:
    y[i] = 0#splittingfrom sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
       X, y, test_size=0.33, random_state=42)from 
from sklearn.metrics import classification_report, confusion_matrix
import numpy as np
import tensorflow as tf
from tensorflow import keras
import pandas as pdmodel = keras.Sequential([
  keras.layers.Dense(
    units=36,
    activation='relu',
    input_shape=(X_train.shape[-1],)
  ),
  keras.layers.BatchNormalization(),
  keras.layers.Dense(units=1, activation='sigmoid'),
])

حال یک مدل متوالی خیلی ساده را از طریق Keras تعریف می‌کنیم.

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

model.compile(
  optimizer=keras.optimizers.Adam(lr=0.001),
  loss=keras.losses.BinaryCrossentropy(),
  metrics="Accuracy"
)history = model.fit(
    X_train,
    y_train,
    epochs=20,
    validation_split=0.05,
    shuffle=True,
    verbose=0
)model.evaluate(X_test, y_test)

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

import matplotlib.pyplot as pltpreds = model.predict(X_test)
y_pred = np.where(preds>0.5,1,0)cm = confusion_matrix(y_test, y_pred)fig, ax = plt.subplots(figsize=(8, 8))
ax.imshow(cm)
ax.grid(False)
ax.xaxis.set(ticks=(0, 1), ticklabels=('Predicted 0s', 'Predicted 1s'))
ax.yaxis.set(ticks=(0, 1), ticklabels=('Actual 0s', 'Actual 1s'))
ax.set_ylim(1.5, -0.5)
for i in range(2):
    for j in range(2):
        ax.text(j, i, cm[i, j], ha='center', va='center', color='red')
plt.show()

رده‌بندی اشتباه کلاس اقلیت

با اینکه این الگوریتم از رگرسیون لوجیستیک بهتر است، اما همچنان 54 نمونه‌ منفی حقیقی را به اشتباه رده‌بندی کرده است! پس باید راهی برای تشخیص این نمونه‌ها پیدا کنیم. بنابراین، از رویکرد تابع زیان سفارشی استفاده می‌کنیم:

import keras.backend as Kdef weighted_binary_crossentropy(y_true, y_pred):
  weights = (tf.math.abs(y_true-1) * 59.) + 1.
  bce = K.binary_crossentropy(y_true, y_pred)
  weighted_bce = K.mean(bce * weights)
  return weighted_bce

اینجا با استفاده از آنتروپی متقاطع تعبیه‌شده (همراه کمی تغییر)، یک ترفند هوشمندانه را به کار بردیم: یک تنسور از وزن‌ها را به نحوی تعریف کردیم که ورودی‌های منفی، وزن بیشتری (=60) را به نسبت وردی های مثبت دریافت کند. دریافت کنند و بدین ترتیب، جریمه‌ رده‌بندی اشتباه آن‌ها نیز سنگین‌تر شود.

model.compile(
  optimizer=keras.optimizers.Adam(lr=0.001),
  loss=weighted_binary_crossentropy,
  metrics="Accuracy"
)model.fit(
    X_train,
    y_train,
    epochs=20,
    validation_split=0.05,
    shuffle=True,
    verbose=0
)

حال مدل را با این تابع جدید کامپایل می‌کنیم:

به ماتریس درهم‌ریختگی به‌دست‌آمده توجه کنید:

ماتریس درهم ریختگی

همان‌طور که ماتریس بالا نشان می‌دهد، مدل اکنون می‌تواند 57 نمونه‌ منفی (27 تا بیشتر از قبل) را به‌درستی رده‌بندی کند. می‌توانید مقادیر گوناگون و فرایندهای وزن‌دهی متفاوتی را امتحان کنید، تا به نتیجه‌ دلخواه خود برسید (که البته بستگی دارد به مسئله‌ای که در دست دارید). در ازای رسیدن به این نتیجه، چندین نمونه مثبت کاذب (317) به دست آورده‌ایم؛ اینکه این نوع رده‌بندی اشتباه (افزایش مثبت‌های کاذب) برای شما قابل‌قبول است یا خیر به مسئله‌ شما و کاربرد آن بستگی دارد.

جمع‌بندی

سفارشی کردن تابع زیان، روش خوبی برای مدیریت داده‌های نامتوازن است. البته این فرایند (همچون تغییر نقطه‌برش‌ها) هزینه‌ای دارد و آن هم کاهش دقت کلی مدل است؛ اما باید به یک نکته توجه کرد؛ آن شرکت بیمه‌ای که قرار است از این الگوریتم استفاده کند، در صورتی احساس امنیت بیشتری خواهد داشت که الگوریتم بتواند معاملات کلاهبرداری را تشخیص دهد (هر چند به قیمت رده‌بندی اشتباه چند معامله‌ واقعی باشد) یا اگر الگوریتم از نظر اسمی دقت بالایی داشته باشد، اما بیشتر معاملات کلاهبرداری را نادیده بگیرد؟

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

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

مدیریت دیتاست‌های نامتوازن در مسائل رده‌بندی دودویی (بخش اول)

مدیریت دیتاست‌های نامتوزان در مسائل رده‌بندی دودویی (بخش دوم)

میانگین امتیاز / 5. تعداد ارا :

مطالب پیشنهادی مرتبط

اشتراک در
اطلاع از
0 نظرات
بازخورد (Feedback) های اینلاین
مشاهده همه دیدگاه ها
[wpforms id="48325"]