Logistic Regression: Sigmoid, Log Loss ilə sıfırdan modelin qurulması
Bu yazıda sinifləndirmə və əsas modellərdən biri olan Loqistik Reqressiya modelindən danışacağıq.
Bu gün daha çox kompleks modellərdən danışırıq: Neural Networks, LLM-lər, Generative AI və s. Amma real problemlərin həllində uzun illərdir istifadə olunan və hələ də aktuallığını qoruyan modellərdən biri Logistic Regression-dır.
Bəs daha kompleks modellərin olduğu bir dövrdə niyə Logistic Regression hələ də bu qədər geniş istifadə olunur?
Çünki real biznes problemlərində məqsəd hər zaman sadəcə düzgün təxmin vermək deyil. Bəzən modelin bu qərarı niyə verdiyini izah edə bilmək də ən az nəticənin özü qədər vacibdir.
Məsələn, kredit riskinin qiymətləndirilməsində modelin sadəcə müştərinin riskli olduğunu deməsi kifayət etməyə bilər. Eyni zamanda bu nəticəyə hansı faktorların daha çox təsir etdiyini də anlamaq istəyirik: gəliri, mövcud borcları, əvvəlki kredit davranışı, yoxsa başqa göstəricilər?
Logistic Regression-un əsas üstünlüklərindən biri də məhz buradadır. Model nisbətən sadə quruluşa malikdir, sürətli öyrədilir və nəticələrinin izah edilməsi daha rahatdır. Sütunların ağırlıqlarına baxaraq onların modelin qərarına hansı istiqamətdə təsir etdiyini görə bilirik.
Buna görə sadə model hər zaman zəif model demək deyil. Praktikada problemin tələbindən asılı olaraq daha sadə və izah edilə bilən model, daha kompleks modeldən daha uyğun seçim ola bilər.
Daha kompleks model ≠ daha yaxşı model.
İndi isə Logistic Regression-un bu qərarları necə verdiyini sıfırdan başa düşməyə çalışaq.
Məsələn gələn mailin spam olub-olmadığını, şişin xoşxassəli və ya bədxassəli olmağı kimi məsələləri aydınlaşdırmaq lazım olanda biz problemə sinifləndirmə olaraq baxırıq. Bunu da aşağıdakı kimi 1 və 0 olaraq adlandıra bilərik. Yəni müəyyən şərtlər ödənəndə 1(bədxassəli) və ya 0(xoşxassəli) şəklində adlandıra bilərik.

Çoxlu sinifləndirmə də ola bilər:

Press enter or click to view image in full size

Biz bu yazıda 2-li sinifləndirmə məsələsinə baxacağıq. Aşağıdakı kimi bir problemə baxaq:
Press enter or click to view image in full size

Fərz edək ki, əlimizdə belə bir data var. Bu problemə Xətti reqressiya məntiqi ilə yanaşaq:
Press enter or click to view image in full size

Göründüyü kimi sadə bir xətti model ilə 2 sinfi ayıra bildik. Təsadüfi 0.5 dəyəri götürərik və reqressiyadan alınan nəticələri 0.5 ilə müqayisə edib dataları aydın bir şəkildə sinifləndirə bilərik.
İndi fərz edək ki, fərqli datalar var və şiş böyüdükcə bədxassəli olma ehtimalı da artır. Sadə bir nümunə üstündə baxaq:
Press enter or click to view image in full size

Bu zaman modelimizi yeniləməliyik. Məsələn, aşağıdakı kimi bir model əldə edə bilərik:
Press enter or click to view image in full size

Tutaq ki, təxmini belə bir xətt ilə ayıra bildik, uğurlu bir xətti reqressiya oldu. Amma 0.5 ilə müqayisə edib ayırmağa çalışdıqda, bəzi 1-lərin 0.5-dən qabaqda olduğu üçün 0 kimi sinifləndiriləcək. Amma onların 1 olduğunu görürük. Yəni xətti bir funksiya ilə yaxşı bir sinifləndirmə edə bilmirik. Deməli biz funksiyamızı dəyişməliyik.
Deməli hipotez funksiyamızı dəyişməliyik. İkili sinifləndirmədən danışdığımız üçün(0 və 1) bizə 0 və 1 arasında olan dəyərlərdən danışacağıq.

Bunun üçün biz sigmoid funksiyasından istifadə edəcəyik.

Sigmoid funksiyası z-dən asılı bir funksiyadır. Biz hipotez funksiyası isə X- inputlar və onların ağırlıqlarından asılıdır. O zaman z-nin yerinə yazırıq.

Funksiyanın qrafiki aşağıdakı kimi olur:
Press enter or click to view image in full size

Gördüyümüz kimi z dəyəri müsbət sonsuzluğuna doğru getdiyində nəticə 1-ə, mənfi sonsuzluğa doğru getdiyində isə nəticə 0-a yaxınlaşır.
Tutaq ki, bir hesablama elədik və hipotezi 0.8 olaraq hesabladıq. Bu da deməkdir ki, 80% ehtimalla y=1 olacaq. Buna ehtimal kimi baxsaq, biz əslində X və w bilinərkən y=1 olma ehtimalını tapırıq. O zaman bunu aşağıdakı kimi göstərə bilərik:

O zaman bir də y=0 olma ehtimalını hesablaya bilərik və ikisinin cəmi ümumi 1 edəcək:
Press enter or click to view image in full size

Yuxarıdakı nümunəyə qayıtsaq, y=1 olma ehtimalı 0.8 idisə, y=0 olma ehtimalı da 0.2 olacaq.
O zaman bunu daha əvvəl danışdığımız bernulli düsturu kimi ümumi formada yaza bilərik:

Yuxarıda biz threshold olaraq 0.5 seçdik, amma bunu problemə görə dəyişə bilərik. Threshold dəyərini 0.5-dən 0.6-ya artırdıqda modelin bir nümunəni y=1 kimi sinifləndirməsi üçün daha yüksək ehtimal tələb olunur. Buna görə model daha az nümunəyə y=1 deyəcək.
z-nin qrafikinə baxdığımızda hipotez funksiyasını 0.5 ilə müqayisə etmək, z-ni 0 ilə müqayisə etmək deməkdir. Qrafikə baxaq:

Düstur kimi yazaq:

Decision boundary
Tutaq ki, hesablama aparmışıq və ağırlıqları aşağıdakı kimi tapmışıq:
w₀=-3, w₁=1, w₂=1 Bu əslində -3+x₁+x₂≥0 olarsa, y=1 deməkdir. Yəni, x₁+x₂≥3 olarsa, y=1 olacaq. Qrafik üstündə baxaq:
Press enter or click to view image in full size

Yuxarıdakı hipotez funksiyasında biz sadəcə bir sətir üçün hesabladıq. Yəni sadəcə ilk nümunənin 1 və ya 0 olmasını tapdıq. Bəs nümunə sayı çox olarsa? Yəni bir neçə nümunənin eyni vaxtda 1 və ya 0 olmasından söhbət gedir. Düstur aşağıdakı kimi olacaq:
Likelihood function
Press enter or click to view image in full size

İndi funksiyanın qrafiki çəkək:

Bu dəfə göründüyü kimi biz maksimallaşdırma etməliyik. Ona görə də “Gradient Ascent” istifadə edəcəyik. Düsturu yazaq:

Hesablamalar asanlaşsın deyə L funksiyasının loqarifmasını alıram. O zaman düstur aşağıdakı kimi olur:
Press enter or click to view image in full size

O zaman cost funksiyasını aşağıdakı kimi yaza bilərik:
Press enter or click to view image in full size

Sigmoid funksiyasının törəməsi

O zaman bunu da belə yaza bilərik:

Deməli,

Bir də loqarifmanın da törəməsinə baxaq:

İndi artıq l funksiyasının törəməsinə baxa bilərik:
Press enter or click to view image in full size

Törəməni açsaq aşağıdakı kimi olacaq:

Press enter or click to view image in full size

Mötərizəni vurub açsaq aşağıdakı kimi olacaq:
Press enter or click to view image in full size




İndi bunlara əsasən Python kodunu yazaq:
df=pd.read_csv("datasets/diabetes.csv")
X=df.drop("Outcome", axis=1)
X = np.c_[np.ones(X.shape[0]), X]
n, m=X.shape
y=np.array(df['Outcome']).reshape(-1, 1)
w=np.zeros((m, 1))
alpha=0.01
epochs=1000
def sigmoid_function(X, w):
y_pred= 1/(1 + np.exp(-np.dot(X, w)))
return y_pred
for epoch in range(epochs):
y_pred=sigmoid_function(X, w)
J=(-1/n) * ( np.dot(y.T, np.log(y_pred)) + np.dot((1-y).T, np.log(1-y_pred)) )
dw=((-1/n)* np.dot(X.T, (y-y_pred)))
w=w-alpha*dwİndi isə öyrəndiyimiz w ağırlıqlarından istifadə edərək modelin təxminlərini hesablayaq:
def accuracy(y, y_pred):
return (y==y_pred).mean()
y_pred=sigmoid_function(X, w)
y_pred=(y_pred >= 0.5).astype(int)
print(accuracy(y, y_pred))
İndi isə sklearn kitabxanasından LogisticRegression sinfini istifadə edək:
from sklearn.linear_model import LogisticRegression
X=df.drop("Outcome", axis=1)
y=df["Outcome"]
log_reg=LogisticRegression()
log_reg.fit(X, y)
y_pred=log_reg.predict(X)
print(accuracy_score(y, y_pred))
print(accuracy_score(y, y_pred))
Yekun olaraq, Logistic Regression sinifləndirmə problemlərində istifadə olunan və nəticəni ehtimal şəklində təqdim edən əsas maşın öyrənməsi alqoritmlərindən biridir. Model xətti kombinasiyadan alınan nəticəni sigmoid funksiyası vasitəsilə 0 və 1 arasındakı ehtimal dəyərinə çevirir və müəyyən edilmiş threshold əsasında yekun sinfi müəyyən edir. Modelin uyğun ağırlıqları öyrənməsi üçün Log Loss(Binary Cross-Entropy) cost funksiyası minimallaşdırılır və Gradient Descent vasitəsilə ağırlıqlar iterativ şəkildə yenilənir. Logistic Regression sadə və izah edilə bilən quruluşuna baxmayaraq, ehtimal əsaslı yanaşması və decision boundary yaratmaq qabiliyyətinə görə sinifləndirmə problemlərində geniş istifadə olunur.
4 people have read this article
Comments
Sign in to comment. Sign in