8-bo‘lim
Polinomial regressiya va regularizatsiya
Chiziqli bo'lmagan bog'liqliklar, qayta o'qitish muammosi va Ridge, Lasso, ElasticNet usullari.
Ushbu bo‘lim mundarijasi
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 #
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}")
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.
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())
Asl shakl: (100, 1)
Kengaygan shakl: (100, 2)
['x0' 'x0^2']
polinomial = LinearRegression().fit(X_kengaygan, y)
print(f"Polinomial model R2: {polinomial.score(X_kengaygan, y):.3f}")
Polinomial model R2: 0.958
Chalkashtirmaslik uchun muhim nuqta: model koeffitsiyentlarga nisbatan chiziqli qoladi.
y = w1 · x + w2 · x² + b
x² shunchaki yangi belgi. Shuning uchun LinearRegression ishlatiladi
va u egri chiziq chizadi.
Ko'p belgi bilan #
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())
['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 | Daraja 2 | Daraja 3 | Daraja 5 |
|---|---|---|---|
| 2 | 5 | 9 | 20 |
| 5 | 20 | 55 | 251 |
| 10 | 65 | 285 | 3002 |
| 50 | 1325 | 23425 | 3 mln+ |
10 ta belgi va 5-daraja = 3000 dan ortiq ustun. Bu qayta o'qitishga va sekin hisoblashga olib keladi.
Qayta o'qitish #
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}")
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
- 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 qulaydi → qayta o'qigan
Daraja 20 da sinov R² manfiy - model o'rtacha qiymatdan ham yomonroq.
Qayta o'qitishning belgilari #
| Belgi | Ma'nosi |
|---|---|
| O'qitishda 0.99, sinovda 0.60 | Klassik qayta o'qitish |
| Modelda belgilardan ko'p parametr | Yodlash uchun joy ko'p |
| Koeffitsiyentlar juda katta | Model keskin egilib turibdi |
| Yangi ma'lumotda ishlamaydi | Umumlashtira olmagan |
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}")
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.
Oddiy MSE: xato
Ridge (L2): xato + alfa · Σ w²
Lasso (L1): xato + alfa · Σ |w|
Ridge regressiya #
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}")
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
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 muhimalfa | Natija |
|---|---|
| 0 | Regularizatsiya yo'q - qayta o'qish xavfi |
| Kichik | Yengil cheklov |
| To'g'ri | Eng yaxshi muvozanat |
| Juda katta | Model haddan tashqari sodda - yetarli o'qimaydi |
Uni kross-validatsiya bilan tanlang (16-bo'lim).
Lasso regressiya #
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)}")
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.
- 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:
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 Ridge1→ sof Lasso0.5→ teng aralashma
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 #
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}")
Eng yaxshi alfa: 0.6579
Sinov R2: 0.959
Solishtirish #
| Model | Koeffitsiyentlar | Belgi tanlash | Qachon |
|---|---|---|---|
| LinearRegression | Cheklanmagan | Yo'q | Belgilar kam, shovqin kam |
| Ridge | Kichrayadi | Yo'q | Belgilar korrelyatsiyalangan |
| Lasso | Nolga aylanadi | Ha | Belgilar ko'p, ko'pi keraksiz |
| ElasticNet | Aralash | Ha | Ko'p va korrelyatsiyalangan |
- Avval oddiy
LinearRegressionni sinang - asos natija - Qayta o'qitish bo'lsa -
RidgeCV - Belgilar juda ko'p bo'lsa -
LassoCV - Ikkalasi ham kerak bo'lsa -
ElasticNetCV
Regularizatsiyali modellarda masshtablash majburiy - aks holda katta qiymatli belgilar ko'proq jazolanadi.
Amaliy misol #
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}")
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.
y = 0.3x³ - 2x² + 5x + shovqinma'lumotini yarating.- Chiziqli model bilan R² ni o'lchang.
PolynomialFeatures(3)bilan qayta o'qiting - farqni ko'ring.- Daraja 1 dan 20 gacha aylanib, o'qitish va sinov R² ni jadvalga chiqaring.
- Ikkala qiymatni bitta grafikda chizing - qayerda ajralishini toping.
- Daraja 20 uchun koeffitsiyentlarning eng kattasini toping.
Ridge(alpha=1)qo'shing va natija qanchalik yaxshilanganini ko'ring.- 30 ta belgidan faqat 5 tasi muhim bo'lgan ma'lumot yarating.
Lassonechta belgini nolga aylantirganini sanang.RidgeCVbilan eng yaxshialfani avtomatik toping.
Xulosa #
PolynomialFeaturesmavjud 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,LassoCVeng yaxshialfani avtomatik topadi.
Keyingi bo'limda klassifikatsiya vazifasiga o'tamiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
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.