Ievads
MÅ«sdienÄs visi runÄ par mÄkslÄ«go intelektu kÄ par universÄlu rÄ«ku, kas spÄj atrisinÄt jebkuru problÄmu. TomÄr realitÄtÄ Å”ie AI modeļi bieži vien darbojas kÄ āmelnÄ kasteā š¦ ā rezultÄti var bÅ«t neprognozÄjami, un atbilde var atŔķirties pat tad, ja jautÄjums tiek uzdots identiski. Tas biznesÄ rada riskus.
TieÅ”i tÄpÄc klasiskÄ maŔīnmÄcīŔanÄs (Machine Learning) joprojÄm ir neaizvietojama un kritiski svarÄ«ga. TÄ balstÄs uz matemÄtisku precizitÄti un tiek izmantota daudzÄs nozarÄs, lai pieÅemtu izŔķiroÅ”us lÄmumus:
- š¦ Banku sektorÄ: KredÄ«tu atmaksas risku izvÄrtÄÅ”anai.
- š”ļø ApdroÅ”inÄÅ”anÄ: KrÄpniecÄ«bas gadÄ«jumu atklÄÅ”anai un risku precÄ«zai novÄrtÄÅ”anai.
- š„ MedicÄ«nÄ: SlimÄ«bu diagnostikai un ÄrstÄÅ”anas plÄnoÅ”anai.
- š MazumtirdzniecÄ«bÄ: PieprasÄ«juma un krÄjumu prognozÄÅ”anai.
- š Fitnesa nozarÄ: LietotÄju aktivitÄtes analÄ«zei un ieÅÄmumu prognozi, Åemot vÄrÄ sezonalitÄti.
- Google: IekÅ”ÄjÄs lietojumprogrammas ā Google izmanto maŔīnmÄcīŔanos daudzos savos pakalpojumos, piemÄram, Google Photos fotoattÄlu kategorizÄÅ”anai šø, kÄ arÄ« tÄdÄs funkcijÄs kÄ Google Maps ceļojuma laika prognozÄÅ”anai šŗļø un teikumu automÄtiskai pabeigÅ”anai āļø.
- Meta: ReklÄmu mÄrÄ·auditorijas atlasei un satura ieteikumiem.
- LinkedIn: Lai ieteiktu jums piemÄrotÄkÄs darba vakances un kontaktus.
Å ajÄ rakstÄ es parÄdīŔu savu praktisku piemÄru no finanÅ”u pasaules: kÄ var izmantot Python, LightGBM un Optuna, lai izveidotu stabilu modeli, kas ar 92% precizitÄti (AUC) prognozÄ kredÄ«tu atmaksu, pÄrvÄrÅ”ot datus reÄlÄ biznesa vÄrtÄ«bÄ. š
š 1. Solis: Datu izpÄte (EDA) ā Datu stÄsts
Pirms mÄs varam kaut ko prognozÄt, mums ir ājÄsadzirdā, ko dati mums stÄsta. Å ajÄ projektÄ es veicu dziļu izpÄti 5 posmos, lai atrastu slÄptÄs likumsakarÄ«bas.
1.1. Datu struktÅ«ra un kvalitÄte
ManÄ rÄ«cÄ«bÄ bija ~600 000 ierakstu. Pirmais pÄrsteigums? Datu kvalitÄte. Izmantojot df.info() un df.isnull().sum(), tika atklÄjts, ka datu kopÄ nav nevienas trÅ«kstoÅ”as vÄrtÄ«bas. Tas ir rets gadÄ«jums, kas ļÄva mums izlaist sarežģīto datu aizpildīŔanas (imputation) posmu un fokusÄties uz analÄ«zi.
āļø Train - Data Info
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 593994 entries, 0 to 593993
Data columns (total 13 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 id 593994 non-null int64
1 annual_income 593994 non-null float64
2 debt_to_income_ratio 593994 non-null float64
3 credit_score 593994 non-null int64
4 loan_amount 593994 non-null float64
5 interest_rate 593994 non-null float64
6 gender 593994 non-null object
7 marital_status 593994 non-null object
8 education_level 593994 non-null object
9 employment_status 593994 non-null object
10 loan_purpose 593994 non-null object
11 grade_subgrade 593994 non-null object
12 loan_paid_back 593994 non-null float64
dtypes: float64(5), int64(2), object(6)
memory usage: 58.9+ MB
1.2. MÄrÄ·a mainÄ«gais (Target Variable)
Es sÄku ar galveno jautÄjumu: cik daudzi cilvÄki tieÅ”Äm atmaksÄ kredÄ«tus? Tika atklÄts mÄrens disbalanss:
- ā 80% atmaksÄ kredÄ«tu.
- ā 20% neatmaksÄ (default).
Tas nozÄ«mÄ, ka mums jÄbÅ«t uzmanÄ«giem ā ja modelis vienkÄrÅ”i minÄtu āVisi atmaksÄsā, tÄ precizitÄte bÅ«tu 80%, bet tas bÅ«tu bezjÄdzÄ«gs. TÄpÄc tika izvÄlÄta AUC-ROC metrika un stratificÄtÄ validÄcija.
count_paid = train_df['loan_paid_back'].value_counts().get(1.0, 0)
count_not_paid = train_df['loan_paid_back'].value_counts().get(0.0, 0)1.3. Skaitlisko pazīmju analīze
TÄlÄk es pÄtÄ«ju tÄdus rÄdÄ«tÄjus kÄ Gada ienÄkumi, ParÄda-ienÄkumu attiecÄ«ba (DTI) un KredÄ«treitings. VizuÄlÄ analÄ«ze (histogrammas un ābox plotsā) atklÄja divas bÅ«tiskas lietas:
- Izteikta nobÄ«de (Skewness): IenÄkumi un DTI rÄdÄ«tÄji bija spÄcÄ«gi nobÄ«dÄ«ti pa labi (right-skewed). VÄlÄk es to laboju ar
log1ptransformÄciju. - SpÄcÄ«gi signÄli: Bija skaidri redzama atŔķirÄ«ba ā cilvÄkiem, kas neatmaksÄ kredÄ«tus (sarkanie grafikos), parasti ir zemÄks kredÄ«treitings un augstÄka parÄda slodze.
1.4. Kategorisko pazīmju analīze
Å is bija viens no interesantÄkajiem posmiem. Es analizÄju, kÄ atmaksas varbÅ«tÄ«ba mainÄs atkarÄ«bÄ no profesijas vai kredÄ«ta mÄrÄ·a. AtklÄjums bija dramatisks, bet paÅ”saprotams:
- š Studenti un Bezdarbnieki: Ä»oti augsts risks (tikai ~7-26% atmaksas rÄdÄ«tÄjs).
- š PensionÄri un NodarbinÄtie: Ä»oti zems risks (~90-99% atmaksas rÄdÄ«tÄjs).
- š¤ Grade (KredÄ«ta reitings): Perfekta lineÄra sakarÄ«ba ā jo zemÄka bankas pieŔķirtÄ klase (no A uz F), jo mazÄka iespÄja, ka kredÄ«ts tiks atmaksÄts.
Å ie ieskati man vÄlÄk ļÄva izveidot spÄcÄ«gas funkcijas (features).
1.5. KorelÄciju un MijiedarbÄ«bu analÄ«ze
Visbeidzot, es pÄrbaudÄ«ju, kÄ mainÄ«gie ir saistÄ«ti savÄ starpÄ. Tika izveidots āPair Plotā un korelÄcijas matrica, kas parÄdÄ«ja loÄ£isku, bet svarÄ«gu sakarÄ«bu: Zems kredÄ«treitings = AugstÄka procentu likme.
Bija skaidri redzams, ka riskantÄkie klienti grupÄjas konkrÄtos datu apgabalos (zems reitings + augsts DTI), kas man deva ideju izveidot jaunas ākombinÄtÄsā funkcijas nÄkamajÄ solÄ«.
š§© 2. Solis: Funkciju inženierija (Feature Engineering) ā Modeļa ādegvielaā
NeapstrÄdÄti dati reti ir pietiekami, lai sasniegtu izcilus rezultÄtus. Funkciju inženierija ir process, kurÄ mÄs izmantojam savas zinÄÅ”anas par nozari (Å”ajÄ gadÄ«jumÄ ā finansÄm), lai izveidotu jaunus, spÄcÄ«gus mainÄ«gos. Å eit ir mana stratÄÄ£ija:
2.1. TrokÅ”Åa novÄrÅ”ana
Pirmais solis bija vienkÄrÅ”s, bet efektÄ«vs: tika izdzÄsti gender (dzimums) un marital_status (Ä£imenes stÄvoklis). Mans EDA pierÄdÄ«ja, ka Å”iem datiem nav nekÄdas saistÄ«bas ar kredÄ«ta atmaksu. MazÄk ātrokÅ”Åaā nozÄ«mÄ stabilÄku modeli.
2.2. āGudrÄā kodÄÅ”ana (Smart Encoding)
Datos bija kolonna grade_subgrade (piem., āC3ā), kas bija ļoti svarÄ«ga, bet teksta formÄtÄ modelis to nesaprot. TÄ vietÄ, lai izmantotu standarta āOne-Hotā kodÄÅ”anu (kas radÄ«tu 35 jaunas kolonnas), mÄs izmantojÄm kÄrtas kodÄÅ”anu (Ordinal Encoding):
- Burtu (A-F) pÄrvÄrtu ciparÄ (A=1, B=2ā¦).
- Apvienoju to ar apakÅ”klasi (3), iegÅ«stot jaunu skaitlisku vÄrtÄ«bu grade_combined (piem., C3 -> 33).
RezultÄts: Modelis uzreiz āsaprotā, ka C3 ir riskantÄks par A1, bet droÅ”Äks par F5.
2.3. FinanÅ”u rÄdÄ«tÄju izveide (Domain Knowledge)
Šis bija interesants instruments. Es izveidoju jaunas pazīmes, balstoties uz banku loģiku:
- š° loan_to_income: KredÄ«ta summa dalÄ«ta ar gada ienÄkumiem. Vai aizÅÄmums ir samÄrÄ«gs ar algu?
- š total_debt: Gada ienÄkumi reizinÄti ar DTI (ParÄda-ienÄkumu attiecÄ«bu). Tas parÄda kopÄjo parÄdu apjomu dolÄros.
- š available_income: Cik naudas klientam paliek pÄri pÄc parÄdu nomaksas?
- āļø affordability: Vai brÄ«vie lÄ«dzekļi sedz ikmÄneÅ”a maksÄjumu?
2.4. MatemÄtiskÄs transformÄcijas
TÄ kÄ ienÄkumu dati bija ļoti nevienmÄrÄ«gi (ar dažiem miljonÄriem, kas kropļo vidÄjos rÄdÄ«tÄjus), es izmantoju Logaritmisko transformÄciju (np.log1p). Tas padarÄ«ja datu sadalÄ«jumu ānormÄlÄkuā un vieglÄk uztveramu modelim.
š» Koda ieskats: PazÄ«mju izveides funkcija
def create_features(df):
# PÄrvÄrÅ”am reitingus skaitļos (A->1, B->2...)
grade_map = {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, 'F': 6, 'G': 7}
df['grade_rank'] = df['grade_subgrade'].str[0].map(grade_map)
# Izveidojam finanŔu attiecības
df['loan_to_income'] = df['loan_amount'] / (df['annual_income'] + 1)
df['total_debt'] = df['debt_to_income_ratio'] * df['annual_income']
df['available_income'] = df['annual_income'] - df['total_debt']
# LogaritmiskÄ transformÄcija nobÄ«dÄ«tiem datiem
df['log_annual_income'] = np.log1p(df['annual_income'])
return dfš» TransformÄto datu informÄcija
š New Train Data Info
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 593994 entries, 0 to 593993
Data columns (total 26 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 id 593994 non-null int64
1 annual_income 593994 non-null float64
2 debt_to_income_ratio 593994 non-null float64
3 credit_score 593994 non-null int64
4 loan_amount 593994 non-null float64
5 interest_rate 593994 non-null float64
6 education_level 593994 non-null object
7 employment_status 593994 non-null object
8 loan_purpose 593994 non-null object
9 loan_paid_back 593994 non-null float64
10 grade_rank 593994 non-null int64
11 grade_number 593994 non-null int64
12 grade_combined 593994 non-null int64
13 loan_to_income 593994 non-null float64
14 total_debt 593994 non-null float64
15 available_income 593994 non-null float64
16 monthly_payment 593994 non-null float64
17 payment_to_income 593994 non-null float64
18 affordability 593994 non-null float64
19 credit_interest 593994 non-null float64
20 income_credit 593994 non-null float64
21 log_annual_income 593994 non-null float64
22 log_loan_to_income 593994 non-null float64
23 log_total_debt 593994 non-null float64
24 log_available_income 593994 non-null float64
25 log_monthly_payment 593994 non-null float64
dtypes: float64(18), int64(5), object(3)
memory usage: 117.8+ MB
š¤ 3. Solis: ModelÄÅ”ana un OptimizÄcija ā No minÄjumiem lÄ«dz precizitÄtei
Datu zinÄtnÄ modeļa palaiÅ”ana (model.fit) ir vienkÄrÅ”ÄkÄ daļa. MÄksla slÄpjas validÄcijas stratÄÄ£ijÄ un optimizÄcijÄ. MÄs nepaļÄvÄmies uz veiksmi ā mÄs izmantojÄm sistemÄtisku pieeju.
3.1. AizsardzÄ«ba pret pÄrmÄcīŔanos (Overfitting)
TÄ vietÄ, lai sadalÄ«tu datus vienkÄrÅ”Ä 80/20 proporcijÄ (kas ir riskanti, jo rezultÄts ir atkarÄ«gs no tÄ, kuri dati trÄpÄs testÄ), es izmantoju 10-kÄrÅ”u StratificÄto ValidÄciju (10-Fold Stratified Cross-Validation).
- KÄ tas strÄdÄ: Dati tiek sadalÄ«ti 10 daļÄs, saglabÄjot 80:20 mÄrÄ·a attiecÄ«bu katrÄ daļÄ.
- RezultÄts: MÄs iegÅ«stam 10 dažÄdus modeļus un vienu, statistiski ticamu OOF (Out-of-Fold) rezultÄtu. Mans gala iesniegums (submission) bija visu 10 modeļu prognožu vidÄjais rÄdÄ«tÄjs, kas ir daudz stabilÄks nekÄ viena modeļa minÄjums.
3.2. āLielais Trijnieksā
Es izvÄlÄjos Gradient Boosting algoritmus, kas Å”obrÄ«d dominÄ tabulÄro datu sacensÄ«bÄs. Es trenÄju trÄ«s dažÄdus modeļus, izmantojot GPU paÄtrinÄjumu Kaggle vidÄ:
- š LightGBM: Ätrs, efektÄ«vs un manÄ eksperimentÄ izrÄdÄ«jÄs visprecÄ«zÄkais.
- š² XGBoost: Klasisks, spÄcÄ«gs algoritms, kas pievÄrsa lielÄku uzmanÄ«bu nodarbinÄtÄ«bas statusam.
- š± CatBoost: Lieliski tiek galÄ ar kategorijÄm un sniedza āhibrÄ«daā skatÄ«jumu.
3.3. Hiperparametru optimizÄcija ar āOptunaā
Es izmantoju Optuna bibliotÄku, lai automatizÄti atrastu labÄkÄs kombinÄcijas (piem., learning_rate, num_leaves, depth).
- Optuna veica 50 eksperimentus (trials) katram modelim.
- Tas uzlaboja manu LightGBM rezultÄtu no 0.92225 uz 0.92274. IespÄjams, izklausÄs maz, bet sacensÄ«bÄs un lielos biznesa apjomos Ŕī atŔķirÄ«ba ir bÅ«tiska.
3.4. Modeļu apvienoŔana (Blending)
Beidzot es izmÄÄ£inÄju Modeļu apvienoÅ”anu (Blending) ā paÅÄmot vidÄjo rezultÄtu no visiem trim modeļiem. TomÄr dati parÄdÄ«ja, ka mans OptimizÄtais LightGBM viens pats darbojas labÄk nekÄ maisÄ«jums. Datu zinÄtnÄ ir svarÄ«gi uzticÄties validÄcijas rezultÄtiem, nevis intuÄ«cijai, tÄpÄc es izvÄlÄjÄmies vienkÄrÅ”Äko un spÄcÄ«gÄko risinÄjumu.
š» Koda ieskats: Optuna optimizÄcija
import optuna
def objective(trial):
params = {
'learning_rate': trial.suggest_float('learning_rate', 0.01, 0.05),
'num_leaves': trial.suggest_int('num_leaves', 20, 150),
'subsample': trial.suggest_float('subsample', 0.6, 0.95),
'device': 'gpu' # Izmantojam GPU Ätrumam
}
model = lgb.LGBMClassifier(**params)
model.fit(X_train, y_train)
return roc_auc_score(y_val, model.predict_proba(X_val)[:, 1])
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=50)š» Koda ieskats: FinÄlais LightGBM modelis
import lightgbm as lgb
# š LabÄkie parametri, ko atradu ar Optuna
best_params = {
'n_estimators': 5000, # MaksimÄlais koku skaits
'learning_rate': 0.0327, # LÄna un stabila mÄcīŔanÄs
'num_leaves': 49, # Koka sarežģītība
'max_depth': 5, # Ierobežots dziļums pret "overfitting"
'subsample': 0.798, # Datu daļa katram kokam
'colsample_bytree': 0.718, # Pazīmju daļa katram kokam
'reg_alpha': 0.086, # L1 RegularizÄcija
'reg_lambda': 0.083, # L2 RegularizÄcija
'device': 'gpu', # GPU paÄtrinÄjums š
'objective': 'binary',
'metric': 'auc'
}
# Modeļa inicializÄÅ”ana
model = lgb.LGBMClassifier(**best_params)
# TrenÄjam ar "Early Stopping" (apstÄjas, ja 100 soļus nav uzlabojumu)
model.fit(
X_train, y_train,
eval_set=[(X_val, y_val)],
callbacks=[lgb.early_stopping(stopping_rounds=100)]
)š 4. Solis: RezultÄti un Biznesa StratÄÄ£ija ā Ko tas nozÄ«mÄ bankai? š¦
Datu zinÄtne nebeidzas ar augstu rezultÄtu ā tÄ beidzas ar lÄmumu. TÄ kÄ Å”is ir klasisks binÄrÄs klasifikÄcijas uzdevums (kur mums jÄprognozÄ viens no diviem iznÄkumiem: vai klients atmaksÄs kredÄ«tu, vai nÄ), precizitÄte ir izŔķiroÅ”a. Å is modelis sasniedza AUC 0.9227, kas ir izcils rÄdÄ«tÄjs Å”Ädas sarežģītÄ«bas problÄmai. Bet ko tas reÄli dod biznesam? š¤
4.1. Modeļa kvalitÄte ā
ROC lÄ«kne pierÄdÄ«ja, ka modelis spÄj stabili atŔķirt labos klientus no sliktajiem. AplÅ«kojot Feature Importance, trÄ«s galvenie faktori ir loÄ£iski un pamatoti:
- Debt-to-Income Ratio (DTI) š
- Credit Score š
- Interest Rate š
4.2. StratÄÄ£iskais lÄmums: Ķert āsliktosā kredÄ«tus š£
VislielÄkais izaicinÄjums ir izvÄlÄties pareizo āslieksniā (threshold). Standarta pieejÄ (50% varbÅ«tÄ«ba) modelis bija pÄrÄk āpiesardzÄ«gsā un palaida garÄm ~40% no sliktajiem kredÄ«tiem. Bankai vai citiem aizdevÄjiem tie ir milzÄ«gi zaudÄjumi. šø
Å ÄdÄ gadÄ«jumÄ var mainÄ«t biznesa lÄmumu un mainÄ«t stratÄÄ£iju āļø. Pazeminot slieksni uz 0.20, padarot modeli stingrÄku.
RezultÄts:
- š“ Pirms (Threshold 0.5): Modelis atklÄja tikai 62% no nemaksÄtÄjiem.
- š¢ PÄc (Threshold 0.2): Modelis veiksmÄ«gi identificÄja 80% no visiem nemaksÄtÄjiem!
SecinÄjums: Lai gan tas nozÄ«mÄ, ka mums manuÄli jÄpÄrbauda vairÄk pieteikumu, bankai tas ir finansiÄli izdevÄ«gÄk nekÄ izsniegt aizdevumus, kas nekad netiks atmaksÄti.
AplÅ«kojot rezultÄtus, redzams, ka stratÄÄ£ijas maiÅa atmaksÄjas. ā MÄs veiksmÄ«gi identificÄjÄm un apturÄjÄm 95 223 sliktos kredÄ«tus (True Positives), kas citÄdi bÅ«tu radÄ«juÅ”i tieÅ”us finansiÄlus zaudÄjumus. Protams, nekas nav perfekts ā 24 277 gadÄ«jumos (False Negatives) modelis tomÄr palaida garÄm nemaksÄtÄjus. š°
TaÄu ācenaā par Å”o augsto droŔību ir 54 528 labi klienti (False Positives), kurus modelis kļūdaini atzÄ«mÄja kÄ riskantus. š¤ Å eit sÄkas āaprÄÄ·inÄta riska vadÄ«baā: tÄ vietÄ, lai Å”iem cilvÄkiem automÄtiski atteiktu, banka novirza tos uz manuÄlo pÄrbaudi. KredÄ«tspeciÄlista laiks maksÄ naudu, taÄu tas ir nesalÄ«dzinÄmi lÄtÄk nekÄ izsniegt miljoniem eiro vÄrtus ātoksiskusā kredÄ«tus. ā
TikmÄr lielÄkÄ daļa ā 419 966 uzticami klienti (True Negatives) ā saÅem Ätru, automÄtisku apstiprinÄjumu, ļaujot darbiniekiem fokusÄties tikai uz sarežģītajiem gadÄ«jumiem. š°
5. Kopsavilkums un GalvenÄs AtziÅas
Å is projekts uzskatÄmi parÄda, ka veiksmÄ«gs maŔīnmÄcīŔanÄs risinÄjums nav tikai par koda rakstīŔanu vai modeļa precizitÄtes procentiem (AUC). Tas ir par biznesa problÄmu tulkoÅ”anu datu valodÄ.
MÄs redzÄjÄm, kÄ sistemÄtiska pieeja rada vÄrtÄ«bu:
- Dziļa izpÄte (EDA) ļÄva mums āsadzirdÄtā, ko dati stÄsta par klientu uzvedÄ«bu, nevis paļauties uz pieÅÄmumiem.
- Funkciju inženierija un Optuna palÄ«dzÄja izspiest maksimumu no pieejamÄs informÄcijas, sasniedzot 92% precizitÄti.
- SliekÅ”Åa pielÄgoÅ”ana (Threshold tuning) pierÄdÄ«ja, ka modelis ir elastÄ«gs instruments ā mÄs varam izvÄlÄties bÅ«t konservatÄ«vi (mazÄk riska) vai agresÄ«vi (vairÄk klientu), atkarÄ«bÄ no bankas stratÄÄ£ijas.
Galu galÄ, Å”Ädi modeļi neaizstÄj kredÄ«tspeciÄlistus, bet gan dod viÅiem āsuperspÄjasā ā iespÄju fokusÄties tikai uz svarÄ«gÄko, kamÄr algoritms paveic melno darbu, izsijÄjot tÅ«kstoÅ”iem pieteikumu sekundes laikÄ.

















