Skip to content
This repository has been archived by the owner on Mar 8, 2020. It is now read-only.

Feature/iss46 create tabular data case study #42

Merged
merged 3 commits into from
Oct 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,392 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### (Home credit competition 중심으로)\n",
"## 4.1 모델개발 - Sklearn model \n",
"---\n",
"### 소스 및 데이터는 아래 kaggle을 참조하였습니다. \n",
"* 캐글 주소 : https://www.kaggle.com/willkoehrsen/start-here-a-gentle-introduction\n",
"* 해당 커널의 한글 번역은 파파고와 구글을 활용하였습니다.\n",
"___"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"# 라이브러리 \n",
"import pandas as pd\n",
"import numpy as np\n",
"import os\n",
"\n",
"from sklearn.preprocessing import LabelEncoder\n",
"import warnings\n",
"warnings.filterwarnings('ignore')\n",
"\n",
"import matplotlib.pyplot as plt\n",
"import seaborn as sns\n",
"\n",
"%matplotlib inline "
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"# 데이터 셋\n",
"app_train = pd.read_csv('d:/Projects/Cp/input/application_train.csv')\n",
"app_test = pd.read_csv('d:/Projects/Cp/input/application_test.csv')"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# 레이블 인코딩 \n",
"le = LabelEncoder()\n",
"le_count = 0\n",
"\n",
"for col in app_train: \n",
" if app_train[col].dtype == 'object':\n",
" if len(list(app_train[col].unique())) <= 2: \n",
" le.fit(app_train[col])\n",
" app_train[col] = le.transform(app_train[col])\n",
" app_test[col] = le.transform(app_test [col]) \n",
" le_count += 1"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# 원 핫 인코딩\n",
"app_train = pd.get_dummies(app_train)\n",
"app_test = pd.get_dummies(app_test)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"# 원 핫 인코딩 후 훈련/테스트 용 데이터 열(컬럼) 일치화\n",
"\n",
"# TARGET(대출금 상환여부)열 따로 보관\n",
"train_labels = app_train['TARGET']\n",
"\n",
"# 열(컬럼)기준 데이터 정렬하여 서로 없는 열(컬럼) 삭제\n",
"app_train, app_test = app_train.align(app_test, join = 'inner', axis = 1)\n",
"\n",
"# 학습용 데이터에 TARGET(대출금 상환여부)열 추가\n",
"app_train['TARGET'] = train_labels"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"# 취업일(DAYS_EMPLOYED) 이상치 데이터 처리\n",
"\n",
"# 훈련용 셋\n",
"app_train['DAYS_EMPLOYED_ANOM'] = app_train[\"DAYS_EMPLOYED\"] == 365243\n",
"app_train['DAYS_EMPLOYED'].replace({365243: np.nan}, inplace = True)\n",
"\n",
"# 테스트용 셋\n",
"app_test['DAYS_EMPLOYED_ANOM'] = app_test[\"DAYS_EMPLOYED\"] == 365243\n",
"app_test[\"DAYS_EMPLOYED\"].replace({365243: np.nan}, inplace = True)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"#편의를 위해 DAYS_BIRTH의 절대값을 취하여 양수를 만듭니다\n",
"app_train['DAYS_BIRTH'] = abs(app_train['DAYS_BIRTH'])"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"# 연령대 정보를 다른 데이터프레임에 저장하고 년으로 환산\n",
"age_data = app_train[['TARGET', 'DAYS_BIRTH']]\n",
"age_data['YEARS_BIRTH'] = age_data['DAYS_BIRTH'] / 365\n",
"\n",
"# 나이 구간 설정\n",
"age_data['YEARS_BINNED'] = pd.cut(age_data['YEARS_BIRTH'], bins = np.linspace(20, 70, num = 11))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 기준선\n",
"* 단순한 기준에서 우리는 테스트 데이터의 모든 예제에 대해 동일한 값을 추측할 수 있다.\n",
"* 대출금을 제떼에 상환하지 않을 가능성을 예측해 달라는 요청을 받았으므로 만약 우리가 완전히 확신할 수 없다면 테스트 데이터의 모든 관측치에 대해 0.5를 추측할 것이다.\n",
"* 이러게 하면 경쟁에서 커브(ROC)가 0.5가 됩니다.\n",
"> (분류작업에서 무작위 추측이 0.5점을 받는다)\n",
"* 우리는 이미 어떤 점수를 받을 수 알고 있기 때문에 단순한 기준선 예측을 할 필요가 없다 \n",
"* 이제 실제 기준에 약간 더 정교한 로지스틱 회귀분석 모델을 사용한다."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Logistic Regression \n",
"* 기준선을 얻으려면 범주형 변수를 인코딩한 후에 모든 피쳐들을 사용한다.\n",
"* 결측값을 채우고 범위를 정규화하여 데이터를 사전 처리한다.\n",
"* 다음 코드는 이러한 사전 처리 단계를 모두 수행한다."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Training data shape: (307511, 240)\n",
"Testing data shape: (48744, 240)\n"
]
}
],
"source": [
"from sklearn.preprocessing import MinMaxScaler, Imputer\n",
"\n",
"# 훈련용 데이터에서 대출금 상환여부(Target)열 제외 한 값을 train 데이터 프레임에 복사\n",
"if 'TARGET' in app_train:\n",
" train = app_train.drop(columns = ['TARGET'])\n",
"else:\n",
" train = app_train.copy()\n",
" \n",
"features = list(train.columns)\n",
"\n",
"# test 테이터프레임에 테스트용 데이터 복사\n",
"test = app_test.copy()\n",
"\n",
"# 누락된 값을 중앙값으로 대체\n",
"imputer = Imputer(strategy = 'median')\n",
"\n",
"# 각 피쳐를 0~1로 스케일\n",
"scaler = MinMaxScaler(feature_range = (0, 1))\n",
"\n",
"# 훈련용 데이터에 모델 학습\n",
"imputer.fit(train)\n",
"\n",
"# 훈련용 및 테스트용 데이터 모두 변환\n",
"train = imputer.transform(train)\n",
"test = imputer.transform(app_test)\n",
"\n",
"# 스칼러 사용하여 반복\n",
"scaler.fit(train)\n",
"train = scaler.transform(train)\n",
"test = scaler.transform(test)\n",
"\n",
"print('Training data shape: ', train.shape)\n",
"print('Testing data shape: ', test.shape)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* LogisticRegression 사용\n",
"* 기본 모델 설정에서 변경한 유일한 사항은 오버핏 양을 제어하는 정규화 매개 변수 C를 낮추는 것입니다\n",
"> 낮은 값은 오버핏을 감소\n",
"* 이렇게 하면 기본 LogisticRegression보다 약간 더 나은 결과를 얻을 수 있지만, 향후 모델에서는 여전히 낮은 수준을 유지할 수 있습니다."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"LogisticRegression(C=0.0001, class_weight=None, dual=False,\n",
" fit_intercept=True, intercept_scaling=1, max_iter=100,\n",
" multi_class='ovr', n_jobs=1, penalty='l2', random_state=None,\n",
" solver='liblinear', tol=0.0001, verbose=0, warm_start=False)"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.linear_model import LogisticRegression\n",
"\n",
"# 지정된 정규화 매개변수를 사용하여 모형 만들기\n",
"log_reg = LogisticRegression(C = 0.0001)\n",
"\n",
"# 훈련용 데이터 학습\n",
"log_reg.fit(train, train_labels)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* 우리는 대출금을 갚지 않을 확률을 예측하기를 원하기 때문에 predict.proba 메쏘드를 사용합니다.\n",
"* m x 2 배열을 반환하는데 m은 관측치의 수입니다. \n",
"* 첫 번째 열은 대상이 0(대출금 상환)일 확률이고 \n",
"* 두 번째 열은 대상이 1(대출금 미상환)일 확률입니다.\n",
"* (따라서 한 행의 경우 두 열의 합은 1이어야 함). \n",
"* 대출금을 상환하지 않을 가능성을 원하므로 두 번째 열을 선택합니다."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"# 예측 수행 후 두번째 열 선택\n",
"log_reg_pred = log_reg.predict_proba(test)[:, 1]"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>SK_ID_CURR</th>\n",
" <th>TARGET</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>100001</td>\n",
" <td>0.087750</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>100005</td>\n",
" <td>0.163957</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>100013</td>\n",
" <td>0.110238</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>100028</td>\n",
" <td>0.076575</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>100038</td>\n",
" <td>0.154924</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" SK_ID_CURR TARGET\n",
"0 100001 0.087750\n",
"1 100005 0.163957\n",
"2 100013 0.110238\n",
"3 100028 0.076575\n",
"4 100038 0.154924"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"submit = app_test[['SK_ID_CURR']]\n",
"submit['TARGET'] = log_reg_pred\n",
"\n",
"submit.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* 예측은 대출금이 상환되지 않을 확률이 0과 1 사이라는 것을 나타낸니다. \n",
"* 이러한 예측을 사용하여 지원자를 분류하는 경우 대출이 위험하다는 것을 판단하는 확률 임계값을 설정할 수 있습니다."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"# 제출물을 CSV 파일에 저장\n",
"submit.to_csv('log_reg_baseline.csv', index = False)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}