# задача с конкурса Tinkoff: https://boosters.pro/champ_3
#Датасет содержит данные о кредитах на покупку электроники, которые были одобрены Tinkoff.ru.
# Необходимо предсказать, выберет ли покупатель кредит от Tinkoff.ru
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
# записываем CSV-файл в объект DataFrame
data = pd.read_csv('https://raw.githubusercontent.com/Gewissta/Learning_Pandas_russian_translation/master/Notebooks/Data/credit_train.csv', encoding='cp1251', sep=';')
# смотрим на первые пять строк
data.head()
#проверяем типы данных и заполненность столбцов
data.info()
#удаляем столбец с номером клиента (так как он незначимый)
# и с регионом проживания (так как он нуждается в серьезной предобработке)
data.drop(['client_id', 'living_region'], axis=1, inplace=True)
# анализируем зависимую переменную: какие значения она принимает и сколько раз
data['open_account_flg'].value_counts(dropna=False)
# считаем, какая точность (доля правильных ответов) была бы у модели, если всем подряд пресказывать, что кредит они не выберут
d=140690/(140690+30056)
d
# анализируем столбец marital_status, смотрим, какое значение в нем является самым частым
data['marital_status'].describe()
# анализируем столбец education, смотрим, какое в нем самое частое значение
data['education'].describe()
# дозаполняем нечисловые столбцы с пропусками самыми часто встречающимися значениями
data['marital_status'].fillna('MAR', inplace=True)
data['education'].fillna('SCH', inplace=True)
# дозаполняем числовые столбцы с пропусками медианными значениями
data['age'].fillna(data['age'].median(), inplace=True)
data['credit_count'].fillna(data['credit_count'].median(), inplace=True)
data['overdue_credit_count'].fillna(data['overdue_credit_count'].median(), inplace=True)
#меняем в столбцах 'credit_sum', 'score_shk' запятые на точки и преобразуем их в числовой формат
for i in ['credit_sum', 'score_shk']:
data[i] = data[i].str.replace(',', '.').astype('float')
# дозаполняем ставшие теперь числовыми столбцы 'credit_sum', 'score_shk' медианными значениями
data['score_shk'].fillna(data['score_shk'].median(), inplace=True)
data['monthly_income'].fillna(data['monthly_income'].median(), inplace=True)
data['credit_sum'].fillna(data['credit_sum'].median(), inplace=True)
# смотрим, что получилось
data.info()
# кодируем нечисловые столбцы методом дамми-кодирования
data = pd.concat([data,
pd.get_dummies(data['gender'], prefix="gender"),
pd.get_dummies(data['job_position'], prefix="job_position"),
pd.get_dummies(data['education'], prefix="education"),
pd.get_dummies(data['marital_status'], prefix="marital_status")],
axis=1)
#удаляем старые нечисловые столбцы, вместо них уже появились новые числовые
data.drop(['gender','job_position','education','marital_status'], axis=1, inplace=True)
# указываем входы и выход модели
y = data['open_account_flg']
X = data.drop(('open_account_flg'), axis=1)
# формируем из набора данных тестовую и обучающую выборки
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=21)
# обучаем логистическую регрессию
from sklearn.linear_model import LogisticRegression
clf = LogisticRegression()
clf.fit(X_train, y_train);
#считаем точность (долю правильных ответов) на тестовой выборке
clf.score(X_test, y_test)
# вычисляем метрику точности ROC-AUC (по ней оцениваются результаты конкурса)
y_pred = clf.predict_proba(X_test)[:, 1]
from sklearn.metrics import roc_auc_score
roc_auc_score(y_test, y_pred)
#для логистической регрессии точность оказалась очень низкой, поэтому строим случайный лес
from sklearn.ensemble import RandomForestClassifier
rfc = RandomForestClassifier(n_estimators = 10, max_depth=5, random_state=21)
rfc.fit(X_train, y_train)
rfc.score (X_test, y_test)
#считаем точность (долю правильных ответов) на тестовой выборке
# вычисляем метрику точности ROC-AUC для случайного леса
y_pred = rfc.predict_proba(X_test)[:, 1]
from sklearn.metrics import roc_auc_score
roc_auc_score(y_test, y_pred)
# случайный лес оказался гораздо лучше
# проверяем, нельзя ли улучшить логистическую регрессию, добавив полиномиальные признаки
from sklearn.preprocessing import PolynomialFeatures
pf = PolynomialFeatures(degree=2)
X_train_polynomial = pf.fit_transform(X_train)
X_test_polynomial = pf.fit_transform(X_test)
# обучаем логистическую регрессию с полиномиальными признаками
clf = LogisticRegression()
clf.fit(X_train_polynomial, y_train);
clf.score(X_test_polynomial, y_test)
y_pred = clf.predict_proba(X_test_polynomial)[:, 1]
roc_auc_score(y_test, y_pred)
#сильно лучше не стало
#нужно добавлять регион и использовать случайный лес
#у победителя ROC-AUC=0.78, у нашего случайного леса 0.70, это где-то 300-я позиция в рейтинге (из 600)