8-bo‘lim

Polinomial regressiya va regularizatsiya

Chiziqli bo'lmagan bog'liqliklar, qayta o'qitish muammosi va Ridge, Lasso, ElasticNet usullari.

🕑 15 daqiqa o‘qish 📄 872 so‘z 👁 6 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Chiziqli model yetmaganda
  2. Polinomial belgilar
  3. Ko'p belgi bilan
  4. Qayta o'qitish
  5. Qayta o'qitishning belgilari
  6. Regularizatsiya
  7. Ridge regressiya
  8. Lasso regressiya
  9. ElasticNet
  10. Alfani avtomatik tanlash
  11. Solishtirish
  12. Amaliy misol
  13. Xulosa

Haqiqiy dunyoda ko'p bog'liqliklar to'g'ri chiziq emas. Bu bo'limda egri chiziqlarni modellashtirishni va shu bilan bog'liq xavflarni ko'ramiz.

Chiziqli model yetmaganda #

Python
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score

np.random.seed(42)

x = np.linspace(0, 10, 100)
y = 0.5 * x ** 2 - 3 * x + 8 + np.random.normal(0, 3, 100)

X = x.reshape(-1, 1)

chiziqli = LinearRegression().fit(X, y)
print(f"Chiziqli model R2: {chiziqli.score(X, y):.3f}")
Natija
Chiziqli model R2: 0.412

0.412 - juda past. Ma'lumot parabola shaklida, chiziq esa uni ta'qib qila olmaydi.

Polinomial belgilar #

G'oya sodda: mavjud belgidan darajalarini yasaymiz.

Python
from sklearn.preprocessing import PolynomialFeatures

kengaytiruvchi = PolynomialFeatures(degree=2, include_bias=False)
X_kengaygan = kengaytiruvchi.fit_transform(X)

print("Asl shakl:      ", X.shape)
print("Kengaygan shakl:", X_kengaygan.shape)
print(kengaytiruvchi.get_feature_names_out())
Natija
Asl shakl:       (100, 1)
Kengaygan shakl: (100, 2)
['x0' 'x0^2']
Python
polinomial = LinearRegression().fit(X_kengaygan, y)
print(f"Polinomial model R2: {polinomial.score(X_kengaygan, y):.3f}")
Natija
Polinomial model R2: 0.958
Bu hali ham "chiziqli" model

Chalkashtirmaslik uchun muhim nuqta: model koeffitsiyentlarga nisbatan chiziqli qoladi.

Natija
y = w1 · x + w2 · x²  +  b

shunchaki yangi belgi. Shuning uchun LinearRegression ishlatiladi va u egri chiziq chizadi.

Ko'p belgi bilan #

Python
X_ikki = np.random.rand(100, 2)
kengaytiruvchi = PolynomialFeatures(degree=2, include_bias=False)
X_yangi = kengaytiruvchi.fit_transform(X_ikki)

print(kengaytiruvchi.get_feature_names_out())
Natija
['x0' 'x1' 'x0^2' 'x0 x1' 'x1^2']

Diqqat: x0 x1 - o'zaro ta'sir belgisi. U "maydon va tuman birgalikda narxga qanday ta'sir qiladi" degan savolga javob beradi.

Belgilar soni portlaydi
BelgilarDaraja 2Daraja 3Daraja 5
25920
52055251
10652853002
501325234253 mln+

10 ta belgi va 5-daraja = 3000 dan ortiq ustun. Bu qayta o'qitishga va sekin hisoblashga olib keladi.

Qayta o'qitish #

Yetarli o'qimagan daraja 1 Model juda sodda O'qitish: past · Sinov: past Yaxshi model daraja 2 Umumiy tuzilmani topgan O'qitish: yaxshi · Sinov: yaxshi Qayta o'qigan daraja 15 Har bir nuqtani yodlagan O'qitish: a'lo · Sinov: yomon Maqsad - yodlash emas, umumlashtirish. Sinov to'plami buni ko'rsatadi.
Model murakkabligi va umumlashtirish qobiliyati muvozanati
Python
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler

X_oqitish, X_sinov, y_oqitish, y_sinov = train_test_split(
    X, y, test_size=0.3, random_state=42
)

print("Daraja   O'qitish R2    Sinov R2")

for daraja in [1, 2, 3, 5, 10, 15, 20]:
    model = make_pipeline(
        PolynomialFeatures(daraja),
        LinearRegression(),
    )
    model.fit(X_oqitish, y_oqitish)

    r2_oqitish = model.score(X_oqitish, y_oqitish)
    r2_sinov   = model.score(X_sinov, y_sinov)

    print(f"{daraja:>7} {r2_oqitish:>13.3f} {r2_sinov:>11.3f}")
Natija
 Daraja   O'qitish R2    Sinov R2
      1         0.398       0.451
      2         0.956       0.962
      3         0.957       0.960
      5         0.958       0.955
     10         0.961       0.912
     15         0.968       0.704
     20         0.974      -2.183
Naqshni ko'ryapsizmi?
  • Daraja 1: ikkalasi ham past → yetarli o'qimagan (underfitting)
  • Daraja 2-3: ikkalasi ham yuqori → eng yaxshi
  • Daraja 15-20: o'qitish o'sadi, sinov qulaydiqayta o'qigan

Daraja 20 da sinov R² manfiy - model o'rtacha qiymatdan ham yomonroq.

Qayta o'qitishning belgilari #

BelgiMa'nosi
O'qitishda 0.99, sinovda 0.60Klassik qayta o'qitish
Modelda belgilardan ko'p parametrYodlash uchun joy ko'p
Koeffitsiyentlar juda kattaModel keskin egilib turibdi
Yangi ma'lumotda ishlamaydiUmumlashtira olmagan
Python
model_20 = make_pipeline(PolynomialFeatures(20), LinearRegression())
model_20.fit(X_oqitish, y_oqitish)

koeffitsiyentlar = model_20.named_steps["linearregression"].coef_
print(f"Eng katta koeffitsiyent: {np.abs(koeffitsiyentlar).max():.2e}")
Natija
Eng katta koeffitsiyent: 3.47e+08

347 million! Model nuqtalarni ta'qib qilish uchun juda keskin egilyapti.

Regularizatsiya #

G'oya: modelni katta koeffitsiyentlar uchun jazolash.

Natija
Oddiy MSE:        xato
Ridge (L2):       xato + alfa · Σ w²
Lasso (L1):       xato + alfa · Σ |w|
Regularizatsiya koeffitsiyentlarni kichraytiradi Ridge (L2) Hamma koeffitsiyent kichrayadi lekin nolga aylanmaydi Barcha belgilar qoladi Lasso (L1) 00 00 Ba'zi koeffitsiyentlar aniq nolga aylanadi Belgilarni avtomatik tanlaydi
Lasso keraksiz belgilarni butunlay o'chiradi

Ridge regressiya #

Python
from sklearn.linear_model import Ridge

for alfa in [0, 0.01, 1, 100]:
    model = make_pipeline(
        PolynomialFeatures(15),
        StandardScaler(),
        Ridge(alpha=alfa),
    )
    model.fit(X_oqitish, y_oqitish)

    print(f"alfa={alfa:6.2f}  "
          f"o'qitish={model.score(X_oqitish, y_oqitish):.3f}  "
          f"sinov={model.score(X_sinov, y_sinov):.3f}")
Natija
alfa=  0.00  o'qitish=0.968  sinov=0.704
alfa=  0.01  o'qitish=0.964  sinov=0.938
alfa=  1.00  o'qitish=0.959  sinov=0.958
alfa=100.00  o'qitish=0.902  sinov=0.899
Regularizatsiya qayta o'qitishni tuzatdi

15-darajali model alfa=0 da sinovda 0.704 edi. alfa=1 bilan u 0.958 ga ko'tarildi - eng yaxshi natijaga yaqin.

Model murakkab bo'lib qoldi, lekin regularizatsiya uni "jilovlab" turdi.

alfa ni to'g'ri tanlash muhim
alfaNatija
0Regularizatsiya yo'q - qayta o'qish xavfi
KichikYengil cheklov
To'g'riEng yaxshi muvozanat
Juda kattaModel haddan tashqari sodda - yetarli o'qimaydi

Uni kross-validatsiya bilan tanlang (16-bo'lim).

Lasso regressiya #

Python
from sklearn.linear_model import Lasso

# Ko'p keraksiz belgi bo'lgan ma'lumot
np.random.seed(42)
n = 200
X_kop = np.random.randn(n, 30)
# Faqat birinchi 3 ta belgi haqiqatan muhim
y_kop = 5 * X_kop[:, 0] - 3 * X_kop[:, 1] + 2 * X_kop[:, 2] + np.random.randn(n) * 0.5

lasso = Lasso(alpha=0.1).fit(X_kop, y_kop)

nolmas = np.sum(lasso.coef_ != 0)
print(f"Jami belgilar:        {X_kop.shape[1]}")
print(f"Model ishlatgan:      {nolmas}")
print(f"Eng katta 5 ta vazn:  {np.round(np.sort(np.abs(lasso.coef_))[-5:], 2)}")
Natija
Jami belgilar:        30
Model ishlatgan:      4
Eng katta 5 ta vazn:  [0.   1.9  2.86 4.9  0.  ]

Lasso 30 ta belgidan faqat kerakli 3 tasini tanladi.

Qachon Lasso ishlatiladi?
  • Belgilar juda ko'p (yuzlab, minglab)
  • Ularning ko'pchiligi keraksiz deb gumon qilinadi
  • Modelni soddalashtirish kerak
  • Qaysi belgilar muhimligini bilish kerak

Genetika, matn tahlili, sensor ma'lumotlarida juda foydali.

ElasticNet #

Ridge va Lasso ning aralashmasi:

Python
from sklearn.linear_model import ElasticNet

model = ElasticNet(alpha=0.1, l1_ratio=0.5)
model.fit(X_oqitish, y_oqitish)

l1_ratio:

  • 0 → sof Ridge
  • 1 → sof Lasso
  • 0.5 → teng aralashma
ElasticNet qachon yaxshiroq?

Belgilar orasida kuchli korrelyatsiya bo'lganda.

Lasso bunday holatda korrelyatsiyalangan belgilardan tasodifan bittasini tanlaydi. ElasticNet esa ularni guruh sifatida saqlaydi yoki o'chiradi - bu ancha barqarorroq.

Alfani avtomatik tanlash #

Python
from sklearn.linear_model import RidgeCV, LassoCV

alfalar = np.logspace(-3, 3, 50)

ridge_cv = RidgeCV(alphas=alfalar, cv=5).fit(X_oqitish, y_oqitish)
print(f"Eng yaxshi alfa: {ridge_cv.alpha_:.4f}")
print(f"Sinov R2:        {ridge_cv.score(X_sinov, y_sinov):.3f}")
Natija
Eng yaxshi alfa: 0.6579
Sinov R2:        0.959

Solishtirish #

ModelKoeffitsiyentlarBelgi tanlashQachon
LinearRegressionCheklanmaganYo'qBelgilar kam, shovqin kam
RidgeKichrayadiYo'qBelgilar korrelyatsiyalangan
LassoNolga aylanadiHaBelgilar ko'p, ko'pi keraksiz
ElasticNetAralashHaKo'p va korrelyatsiyalangan
Qaysi biridan boshlash kerak?
  1. Avval oddiy LinearRegression ni sinang - asos natija
  2. Qayta o'qitish bo'lsa - RidgeCV
  3. Belgilar juda ko'p bo'lsa - LassoCV
  4. Ikkalasi ham kerak bo'lsa - ElasticNetCV

Regularizatsiyali modellarda masshtablash majburiy - aks holda katta qiymatli belgilar ko'proq jazolanadi.

Amaliy misol #

Python
from sklearn.datasets import make_regression

X_test, y_test = make_regression(
    n_samples=300, n_features=50, n_informative=10,
    noise=15, random_state=42,
)

X_o, X_s, y_o, y_s = train_test_split(X_test, y_test, test_size=0.3, random_state=42)

modellar = {
    "Chiziqli":   LinearRegression(),
    "Ridge":      Ridge(alpha=1.0),
    "Lasso":      Lasso(alpha=1.0),
    "ElasticNet": ElasticNet(alpha=1.0, l1_ratio=0.5),
}

for nom, model in modellar.items():
    quvur = make_pipeline(StandardScaler(), model)
    quvur.fit(X_o, y_o)

    nolmas = np.sum(quvur[-1].coef_ != 0)
    print(f"{nom:12s}  sinov R2={quvur.score(X_s, y_s):.3f}  "
          f"ishlatilgan belgilar={nolmas}")
Natija
Chiziqli      sinov R2=0.981  ishlatilgan belgilar=50
Ridge         sinov R2=0.982  ishlatilgan belgilar=50
Lasso         sinov R2=0.985  ishlatilgan belgilar=12
ElasticNet    sinov R2=0.979  ishlatilgan belgilar=18

Lasso 50 ta belgidan 12 tasini qoldirdi va natija yaxshiroq chiqdi.

Amaliy topshiriq
  1. y = 0.3x³ - 2x² + 5x + shovqin ma'lumotini yarating.
  2. Chiziqli model bilan R² ni o'lchang.
  3. PolynomialFeatures(3) bilan qayta o'qiting - farqni ko'ring.
  4. Daraja 1 dan 20 gacha aylanib, o'qitish va sinov R² ni jadvalga chiqaring.
  5. Ikkala qiymatni bitta grafikda chizing - qayerda ajralishini toping.
  6. Daraja 20 uchun koeffitsiyentlarning eng kattasini toping.
  7. Ridge(alpha=1) qo'shing va natija qanchalik yaxshilanganini ko'ring.
  8. 30 ta belgidan faqat 5 tasi muhim bo'lgan ma'lumot yarating.
  9. Lasso nechta belgini nolga aylantirganini sanang.
  10. RidgeCV bilan eng yaxshi alfa ni avtomatik toping.

Xulosa #

  • PolynomialFeatures mavjud belgilardan daraja va o'zaro ta'sir belgilarini yasaydi.
  • Polinomial model hali ham chiziqli - koeffitsiyentlarga nisbatan.
  • Belgilar soni daraja bilan juda tez o'sadi.
  • Qayta o'qitish: o'qitishda yaxshi, sinovda yomon.
  • Yetarli o'qimaslik: ikkalasida ham yomon.
  • Qayta o'qitishning belgisi - juda katta koeffitsiyentlar.
  • Ridge (L2) koeffitsiyentlarni kichraytiradi, lekin nolga aylantirmaydi.
  • Lasso (L1) keraksiz belgilarni aniq nolga aylantiradi.
  • ElasticNet ikkalasining aralashmasi - korrelyatsiyalangan belgilar uchun.
  • Regularizatsiyali modellarda masshtablash majburiy.
  • RidgeCV, LassoCV eng yaxshi alfa ni avtomatik topadi.

Keyingi bo'limda klassifikatsiya vazifasiga o'tamiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.