آیا می توانم وام های بهتر از LendingClub را درجه بندی کنم؟

 عکس نمایه نویسنده

tywmickTy Mick

دانشمند داده ، عشایر سابق RV.

درصورت عدم حضور در آن ، من یک شبکه عصبی برای پیش بینی خطر وام با استفاده از یک مجموعه داده عمومی از LendingClub ایجاد کردم. سپس من یک API عمومی ساختم تا بتوانم پیش بینی مدل را ارائه دهم. خوب و همه چیز خوب است ، اما … مدل من چقدر خوب است؟

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

قرار دادن شبکه عصبی من در برابر معیار شرکت

  • قوانین پایه
  • معیار آزمون
  • نوبت LendingClub
  • نوبت من
  • پیروزی!

    وارد کردن لیست کار پوشه prev_notebook_folder = “../input/ ساخت-شبکه-عصبی-برای-پیش بینی-خطر-وام” /
    وامها = joblib.load (پوشه_پیشوند_نوت بوک + “وامهای_برای_سال_جیبل” )
    loan.shape
    (1110171، 70)
    loan.head ()
    ─────┬─────────────────┬─────────────┬──────────── ─────────┬────────┬──────────────┬──────────────── ───┬─────────────────┬──────┬────────────┬──────── ──────────┬────────────────────┬─────────────────┬ ─────────────────────────────┬──────────────────── ─┬───────────┬────────┬────────────┬────────────── ───┐
    │ │ وام nt مدت │ طول_اندازه مالکیت خانه │ سالانه inc هدف │ dti │ delinq_2yrs │ cr_hist_age_mths │ fico_range_low_low │ … │ مالیات_جوانان │ tot_hi_cred_lim │ total_bal_ex_cc___l
    ├────┼────────────┼────────────┼─────────────┼──── ─────────────┼─────────────┼─────────────────────┼ ────────┼──────────────┼───────────────────┼────── ───────────┼──────┼────────────┼────────────────── ┼────────────────────┼─────────────────┼────────── ───────────────────┼─────────────────────┼──────── ───┼────────┼────────────┼─────────────────┤
    │ 0 │ 3600.0 │ 36 ماه │ 10+ سال │ رهن │ 55000.0 │ ادغام بدهی │ 5.91 │ 0.0 │ 148.0 │ 675.0 │ … │ 0.0 │ 178050.0 │ 7746.0 │ 2400.0 │ 13734.0 │ 1.0 │ دسامبر-2015 │ C │ C4 4429.08
    │ 1 │ 24700.0 │ 36 ماه │ 10+ سال │ وام │ 65000.0 │ تجارت_ کوچک │ 16.06 │ 1.0 │ 192.0 │ 715.0 │ … │ 0.0 │ 314017.0 │ 39475.0 │ 79300.0 │ 24667.0 │ 1.0 │ دسامبر-2015 │ C │ C 1 29530.08
    │ 2 │ 20000.0 │ 60 ماه │ 10+ سال │ رهن 000 63000.0 │ بهبود _ بهبود خانه │ 10.78 │ 0.0 │ 184.0 │ 695.0 │ … │ 0.0 │ 218418.0 │ 18696.0 │ 6200.0 │ 14877.0 │ 1.0 │ دسامبر-2015 2015 B │ B4 25959.60 │
    │ 4 00 10400.0 │ 60 ماه │ 3 سال ORT رهن │ 104433.0 │ خرید عمده_ 25.37 │ 1.0 │ 210.0 │ 695.0 │ … │ 0.0 │ 439570.0 │ 95768.0 │ 20300.0 │ 88097.0 │ 1.0 │ دسامبر 2015 │ F │ F39 │
    5 │ 11950.0 │ 36 ماه │ 4 سال years اجاره │ 34000.0 │ ادغام بدهی 20 10.20 │ 0.0 │ 338.0 │ 690.0 │ … │ 0.0 │ 16900.0 │ 12798.0 │ 9400.0 │ 4000.0 │ 1.0 │ دسامبر 2015 │ C 48 C483 48 14586 │
    └────┴────────────┴────────────┴─────────────┴──── ─────────────┴─────────────┴─────────────────────┴ ────────┴──────────────┴───────────────────┴────── ───────────┴──────┴────────────┴────────────────── ┴────────────────────┴─────────────────┴────────── ───────────────────┴─────────────────────┴──────── ───┴────────┴────────────┴─────────────────┘
    5 ردیف × ستون 70

    ضمناً این پست از یک نوت بوک Jupyter اقتباس شده است ، بنابراین اگر دوست دارید در دفترچه یادداشت خود نیز این کار را انجام دهید ، پیش بروید و Kaggle را چنگال بزنید یا GitHub!

    قوانین اساسی

    این یک مبارزه پاک خواهد بود – مدل من از هیچ داده ای استفاده نمی کند که LendingClub در آن دسترسی ندارد آنها نمره وام را محاسبه می کنند (از جمله خود نمره).

    من می خواهم مجموعه داده را به ترتیب زمانی مرتب کنم (با استفاده از ستون

    Issue_d ، ماه و سال وام صادر شد) و آن را به دو قسمت تقسیم کرد. 80٪ اول را برای آموزش مدل مسابقه خود استفاده می کنم و عملکرد 20٪ آخر را مقایسه می کنم.

    از sklearn .model_select import train_test_split وام [ “تاریخ” ] = وام [ “موضوع_د” ] .astype ( “datetime64 [ns]” )
    loan.sort_values ​​( “date” ، axis = “index” ، inplace = True ، kind = “mergesort” ) قطار ، آزمون = قطار_آزمایش_شکل (وام ، اندازه_آزمون = 0.2 ، تغییر شکل = نادرست )
    قطار ، آزمون = train.copy () ، test.copy ()
    print ( f “مجموعه آزمون شامل {len (test) :،} وام ها است.” )
    مجموعه آزمون شامل 222،035 وام است.

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

    اتفاقاً ، من مجبور هستم به مایکل ورم اعتبار بدهم تا بتوانم عملکرد مدل خود را با درجه وام LendingClub مقایسه کنم ، اما روش من کاملا متفاوت است. من سعی در شبیه سازی عملکرد یک نمونه کارها سرمایه گذاری ندارم. من فقط ارزیابی می کنم که پیش بینی های من درمورد ریسک ساده چقدر خوب مقایسه شده است. بر اساس متغیر مستقل آخرین دفترچه من ، کسری از بازده وام مورد انتظار که وام گیرنده احتمالی پس خواهد داد (که من آن را مهندسی کردم به عنوان کسری_ترمیم).

    LendingClub ابتدا بشقاب. من تمام وام های درجه A آنها را از مجموعه آزمون جمع آوری می کنم ، آنها را می شمارم و میانگین کسر_ترمیم آنها را محاسبه می کنم. این میانگین معیار اندازه گیری مدل من خواهد بود.

    سپس مدل خود را با استفاده از همان خط لوله و پارامترهایی که در آخرین دفترچه یادداشت خود قرار داده ام ، روی مجموعه آموزشی آموزش می دهم. پس از آموزش ، من از آن برای پیش بینی مجموعه آزمون استفاده می کنم ، سپس تعداد پیش بینی های برتر برابر با تعداد وام های درجه A LendingClub را جمع می کنم. سرانجام ، من همان میانگین کسری_ترمیم شده در آن زیرمجموعه را محاسبه می کنم و خودمان یک برنده خواهیم داشت!

    نوبت LendingClub

    از آمار وارد کردن معنی دارد lc_grade_a = test [test [ “grade” ] == “A” ]
    print ( f “LendingClub {len (lc_grade_a) :،} وام در آزمون درجه A را تعیین کرد.” print ( “\ n متوسط” کسر_ترکیب شده “در وامهای درجه LendingClub:” )
    چاپ (دور (میانگین (lc_grade_a [ “کسر_بازیابی” ]) ، 5 ))]
    LendingClub در مجموعه آزمون 38779 وام داد. متوسط ​​”کسر_ترمیم” وامهای درجه A LendingClub:
    0.96021

    این درصد بسیار بالایی است. من کمی عصبی هستم.

    نوبت من

    اول ، من عملکرد

    run_pipeline خود را از دفترچه یادداشت قبلی خود کپی می کنم:

    from sklearn.model_selection import train_test_split
    از sklearn_pandas وارد کردن DataFrameMapper
    از sklearn.preprocessing وارد کردن OneHotEncoder ، OrdinalEncoder ، StandardScaler
    از tensorflow.keras وارد کردن ترتیب ، ورودی
    از tensorflow.keras.layers وارد کردن متراکم ، رها کردن def run_pipeline ( داده ها، onehot_cols ، مجموعه های_تشریفي ، اندازه دسته ای ، اعتبارسنجی = درست است ،
    )
    :
    X = data.drop (ستونها = [ “کسر_ترمیم شد” ]) y = داده [ “کسر_بازیابی شد” ] X_train ، X_valid ، y_train ، y_valid = ( split_test_split (X، y، test_size = 0.2 ، random_state = 0 ) اگر تأیید شود else (X ، هیچ ، y ، هیچ ) ) ترانسفورماتور = DataFrameMapper ( [ (onehot_cols ، OneHotEncoder (drop = “if_binary” )) ، ( لیست (colinal_cols.keys ()) ، OrdinalEncoder (دسته بندی ها = لیست (مقادیر_فرهنگی) ()) ، ) ، ] ، پیش فرض = StandardScaler () ، ) X_train = transformer.fit_transform (X_train) X_valid = transformer.transform (X_valid) اگر اعتبار دیگری هیچ input_nodes = X_train.shape [ 1 ] output_nodes = 1 مدل = متوالی () model.add (ورودی ((گره های ورودی))) model.add (متراکم ( 64 ، فعال سازی = “relu” ))) model.add (Dropout ( 0.3 ، seed = 0 ))) model.add (متراکم ( 32 ، فعال سازی = “relu” )) model.add (Dropout ( 0.3 ، seed = 1 ))) model.add (متراکم ( 16 ، فعال سازی = “relu” )) model.add (Dropout ( 0.3 ، seed = 2 ))) model.add (متراکم (گره های خروجی)) model.compile (بهینه ساز = “adam” ، loss = “mean_squared_logarithmic_error” ) تاریخچه = model.fit ( X_train ، y_train ، batch_size = batch_size ، epochs = 100 ، validation_data = (X_valid، y_valid) اگر اعتبار دیگری هیچ ، verbose = 2 ، ) بازگشت تاريخچه. تاريخچه ، مدل ، ترانسفورماتور onehot_cols = [ “اصطلاح” ، “نوع_کاربرد” ، “مالکیت خانه” ، “هدف” ]
    ستونهای_تعیین = { “emp_length” : [ “<1 سال" ، “1 سال” ، “2 سال” ، “3 سال” ، “4 سال” ، “5 سال” ، “6 سال” ، “7 سال” ، “8 سال” ، “9 سال” ، “10+ سال” ، ]
    }

    اکنون برای لحظه حقیقت:

    # آموزش مدل
    _ ، مدل ، ترانسفورماتور = run_pipeline ( train.drop (ستون ها = [ “Issue_d” ، “date” ، “grade” ، “sub_grade” ، “بازگشت_پیش بینی شده” ]) ، onehot_cols ، مجموعه های_تشریفي ، batch_size = 128 ، اعتبارسنجی = نادرست ،
    ) # پیش بینی کنید
    X_test = transformer.transform ( test.drop ( ستون ها = [ “کسر_ترمیم” ، “مسئله_د” ، “تاریخ” ، “درجه” ، “sub_grade” ، “بازگشت_پیش بینی شده” ، ] )
    )
    test [ “model_preditions” ] = model.predict (X_test) # پیش بینی های برتر را جمع کنید
    test_sorted = test.sort_values ​​( “پیش بینی های مدل” ، axis = “فهرست” ، صعودی = نادرست )
    ty_grade_a = test_sorted.iloc [ 0 : len (lc_grade_a)] # نمایش نتایج
    print ( “\ n متوسط” کسر_ترکیب شده “در وام های درجه A Ty:” )
    چاپ (قالب (میانگین (ty_grade_a [ “کسر_بازیابی” ]) ، “.5f” )))
    دوره 1/100
    6939/6939 – 13s – ضرر: 0.0249
    دوره 2/100
    6939/6939 – 13s – ضرر: 0.0204
    دوره 3/100
    6939/6939 – 13s – ضرر: 0.0202
    دوره 4/100
    6939/6939 – 13s – ضرر: 0.0202
    دوره 5/100
    6939/6939 – 13s – ضرر: 0.0202
    دوره 6/100
    6939/6939 – 14s – ضرر: 0.0201
    دوره 7/100
    6939/6939 – 14s – ضرر: 0.0201
    دوره 8/100
    6939/6939 – 14s – ضرر: 0.0201
    دوره 9/100
    6939/6939 – 13s – ضرر: 0.0201
    دوره 10/100
    6939/6939 – 12s – ضرر: 0.0201
    دوره 11/100
    6939/6939 – 13s – ضرر: 0.0201
    دوره 12/100
    6939/6939 – 13s – ضرر: 0.0201
    دوره 13/100
    6939/6939 – 13s – ضرر: 0.0201
    دوره 14/100
    6939/6939 – 13s – ضرر: 0.0201
    دوره 15/100
    6939/6939 – 12s – ضرر: 0.0201
    دوره 16/100
    6939/6939 – 12s – ضرر: 0.0201
    دوره 17/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 18/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 19/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 20/100
    6939/6939 – 14s – ضرر: 0.0200
    دوره 21/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 22/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 23/100
    6939/6939 – 12s – ضرر: 0.0200
    دوره 24/100
    6939/6939 – 12s – ضرر: 0.0200
    دوره 25/100
    6939/6939 – 12s – ضرر: 0.0200
    دوره 26/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 27/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 28/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 29/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 30/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 31/100
    6939/6939 – 15s – ضرر: 0.0200
    دوره 32/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 33/100
    6939/6939 – 12s – ضرر: 0.0200
    دوره 34/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 35/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 36/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 37/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 38/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 39/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 40/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 41/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 42/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 43/100
    6939/6939 – 14s – ضرر: 0.0200
    دوره 44/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 45/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 46/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 47/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 48/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 49/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 50/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 51/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 52/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 53/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 54/100
    6939/6939 – 14s – ضرر: 0.0200
    دوره 55/100
    6939/6939 – 14s – ضرر: 0.0200
    دوره 56/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 57/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 58/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 59/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 60/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 61/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 62/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 63/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 64/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 65/100
    6939/6939 – 12s – ضرر: 0.0200
    دوره 66/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 67/100
    6939/6939 – 14s – ضرر: 0.0200
    دوره 68/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 69/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 70/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 71/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 72/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 73/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 74/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 75/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 76/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 77/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 78/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 79/100
    6939/6939 – 14s – ضرر: 0.0200
    دوره 80/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 81/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 82/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 83/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 84/100
    6939/6939 – 12s – ضرر: 0.0200
    دوره 85/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 86/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 87/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 88/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 89/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 90/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 91/100
    6939/6939 – 14s – ضرر: 0.0200
    دوره 92/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 93/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 94/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 95/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 96/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 97/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 98/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 99/100
    6939/6939 – 13s – ضرر: 0.0200
    دوره 100/100
    6939/6939 – 13s – ضرر: 0.0200 متوسط ​​”کسر_ترمیم” وامهای درجه A Ty
    0.96166

    پیروزی!

    پیو ، این یک مورد نزدیک بود! پیروزی من ممکن است خیلی کوچک باشد تا از نظر آماری قابل توجه باشد ، اما سلام ، جالب است که می توانم با بهترین و درخشان ترین LendingClub همگام شوم.

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

    قبلاً در https://tymick.me/blog/loan-grading-showdown