diff --git a/.ipynb_checkpoints/Solutions-checkpoint.ipynb b/.ipynb_checkpoints/Solutions-checkpoint.ipynb new file mode 100644 index 0000000..fd4dfe2 --- /dev/null +++ b/.ipynb_checkpoints/Solutions-checkpoint.ipynb @@ -0,0 +1,2016 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "2e4f6e1b", + "metadata": {}, + "source": [ + "## Import libraries" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "ca212e64", + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "import datetime\n", + "import warnings\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "\n", + "from imblearn.over_sampling import SMOTE\n", + "from sklearn.model_selection import train_test_split\n", + "from sklearn.linear_model import LogisticRegression\n", + "from sklearn.metrics import confusion_matrix\n", + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "import pickle\n", + "\n", + "warnings.filterwarnings('ignore')" + ] + }, + { + "cell_type": "markdown", + "id": "879fa2fb", + "metadata": {}, + "source": [ + "## Load data" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "b6c0b1ed", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
genderSeniorCitizenPartnerDependentstenurePhoneServiceOnlineSecurityOnlineBackupDeviceProtectionTechSupportStreamingTVStreamingMoviesContractMonthlyChargesTotalChargesChurn
0Female0YesNo1NoNoYesNoNoNoNoMonth-to-month29.8529.85No
1Male0NoNo34YesYesNoYesNoNoNoOne year56.951889.5No
2Male0NoNo2YesYesYesNoNoNoNoMonth-to-month53.85108.15Yes
3Male0NoNo45NoYesNoYesYesNoNoOne year42.301840.75No
4Female0NoNo2YesNoNoNoNoNoNoMonth-to-month70.70151.65Yes
...................................................
7038Male0YesYes24YesYesNoYesYesYesYesOne year84.801990.5No
7039Female0YesYes72YesNoYesYesNoYesYesOne year103.207362.9No
7040Female0YesYes11NoYesNoNoNoNoNoMonth-to-month29.60346.45No
7041Male1YesNo4YesNoNoNoNoNoNoMonth-to-month74.40306.6Yes
7042Male0NoNo66YesYesNoYesYesYesYesTwo year105.656844.5No
\n", + "

7043 rows × 16 columns

\n", + "
" + ], + "text/plain": [ + " gender SeniorCitizen Partner Dependents tenure PhoneService \\\n", + "0 Female 0 Yes No 1 No \n", + "1 Male 0 No No 34 Yes \n", + "2 Male 0 No No 2 Yes \n", + "3 Male 0 No No 45 No \n", + "4 Female 0 No No 2 Yes \n", + "... ... ... ... ... ... ... \n", + "7038 Male 0 Yes Yes 24 Yes \n", + "7039 Female 0 Yes Yes 72 Yes \n", + "7040 Female 0 Yes Yes 11 No \n", + "7041 Male 1 Yes No 4 Yes \n", + "7042 Male 0 No No 66 Yes \n", + "\n", + " OnlineSecurity OnlineBackup DeviceProtection TechSupport StreamingTV \\\n", + "0 No Yes No No No \n", + "1 Yes No Yes No No \n", + "2 Yes Yes No No No \n", + "3 Yes No Yes Yes No \n", + "4 No No No No No \n", + "... ... ... ... ... ... \n", + "7038 Yes No Yes Yes Yes \n", + "7039 No Yes Yes No Yes \n", + "7040 Yes No No No No \n", + "7041 No No No No No \n", + "7042 Yes No Yes Yes Yes \n", + "\n", + " StreamingMovies Contract MonthlyCharges TotalCharges Churn \n", + "0 No Month-to-month 29.85 29.85 No \n", + "1 No One year 56.95 1889.5 No \n", + "2 No Month-to-month 53.85 108.15 Yes \n", + "3 No One year 42.30 1840.75 No \n", + "4 No Month-to-month 70.70 151.65 Yes \n", + "... ... ... ... ... ... \n", + "7038 Yes One year 84.80 1990.5 No \n", + "7039 Yes One year 103.20 7362.9 No \n", + "7040 No Month-to-month 29.60 346.45 No \n", + "7041 No Month-to-month 74.40 306.6 Yes \n", + "7042 Yes Two year 105.65 6844.5 No \n", + "\n", + "[7043 rows x 16 columns]" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "churndata = pd.read_csv('/Users/yuriawano/lab-handling-data-imbalance-classification/files_for_lab/Customer-Churn.csv')\n", + "churndata" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "3ad505a7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(7043, 16)" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "churndata.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "569f28be", + "metadata": {}, + "outputs": [], + "source": [ + "# standardize the header\n", + "churndata.columns = [columns.lower() for columns in churndata.columns]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "2fcd3922", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['gender', 'seniorcitizen', 'partner', 'dependents', 'tenure',\n", + " 'phoneservice', 'onlinesecurity', 'onlinebackup', 'deviceprotection',\n", + " 'techsupport', 'streamingtv', 'streamingmovies', 'contract',\n", + " 'monthlycharges', 'totalcharges', 'churn'],\n", + " dtype='object')" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "churndata.columns" + ] + }, + { + "cell_type": "markdown", + "id": "f4bc0be4", + "metadata": {}, + "source": [ + "## Check the datatypes of all the columns in the data. \n", + "You would see that the column TotalCharges is object type. Convert this column into numeric type using pd.to_numeric function." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "58628135", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "gender object\n", + "seniorcitizen int64\n", + "partner object\n", + "dependents object\n", + "tenure int64\n", + "phoneservice object\n", + "onlinesecurity object\n", + "onlinebackup object\n", + "deviceprotection object\n", + "techsupport object\n", + "streamingtv object\n", + "streamingmovies object\n", + "contract object\n", + "monthlycharges float64\n", + "totalcharges object\n", + "churn object\n", + "dtype: object" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "churndata.dtypes" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "e512e97d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
totalcharges
029.85
11889.50
2108.15
31840.75
4151.65
......
70381990.50
70397362.90
7040346.45
7041306.60
70426844.50
\n", + "

7043 rows × 1 columns

\n", + "
" + ], + "text/plain": [ + " totalcharges\n", + "0 29.85\n", + "1 1889.50\n", + "2 108.15\n", + "3 1840.75\n", + "4 151.65\n", + "... ...\n", + "7038 1990.50\n", + "7039 7362.90\n", + "7040 346.45\n", + "7041 306.60\n", + "7042 6844.50\n", + "\n", + "[7043 rows x 1 columns]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "churndata[['totalcharges']] = churndata[['totalcharges']].apply(pd.to_numeric, errors='coerce')\n", + "churndata[['totalcharges']]" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "c7247811", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "dtype('float64')" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "churndata['totalcharges'].dtypes" + ] + }, + { + "cell_type": "markdown", + "id": "2d98f917", + "metadata": {}, + "source": [ + "## Deal with null values" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "fa36e5d8", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "gender 0\n", + "seniorcitizen 0\n", + "partner 0\n", + "dependents 0\n", + "tenure 0\n", + "phoneservice 0\n", + "onlinesecurity 0\n", + "onlinebackup 0\n", + "deviceprotection 0\n", + "techsupport 0\n", + "streamingtv 0\n", + "streamingmovies 0\n", + "contract 0\n", + "monthlycharges 0\n", + "totalcharges 11\n", + "churn 0\n", + "dtype: int64" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "churndata.isna().sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "71037922", + "metadata": {}, + "outputs": [], + "source": [ + "def fill_mean(data, columns):\n", + " \"\"\"\n", + " data: dataframe\n", + " columns: columns\n", + " return: modified dataframe with mean filled \n", + " \"\"\"\n", + " \n", + " for col in columns:\n", + " mean_value = data[columns].mean()\n", + " data[columns] = data[columns].fillna(mean_value)\n", + " \n", + " return data" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "9eabb326", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
genderseniorcitizenpartnerdependentstenurephoneserviceonlinesecurityonlinebackupdeviceprotectiontechsupportstreamingtvstreamingmoviescontractmonthlychargestotalchargeschurn
0Female0YesNo1NoNoYesNoNoNoNoMonth-to-month29.8529.85No
1Male0NoNo34YesYesNoYesNoNoNoOne year56.951889.50No
2Male0NoNo2YesYesYesNoNoNoNoMonth-to-month53.85108.15Yes
3Male0NoNo45NoYesNoYesYesNoNoOne year42.301840.75No
4Female0NoNo2YesNoNoNoNoNoNoMonth-to-month70.70151.65Yes
...................................................
7038Male0YesYes24YesYesNoYesYesYesYesOne year84.801990.50No
7039Female0YesYes72YesNoYesYesNoYesYesOne year103.207362.90No
7040Female0YesYes11NoYesNoNoNoNoNoMonth-to-month29.60346.45No
7041Male1YesNo4YesNoNoNoNoNoNoMonth-to-month74.40306.60Yes
7042Male0NoNo66YesYesNoYesYesYesYesTwo year105.656844.50No
\n", + "

7043 rows × 16 columns

\n", + "
" + ], + "text/plain": [ + " gender seniorcitizen partner dependents tenure phoneservice \\\n", + "0 Female 0 Yes No 1 No \n", + "1 Male 0 No No 34 Yes \n", + "2 Male 0 No No 2 Yes \n", + "3 Male 0 No No 45 No \n", + "4 Female 0 No No 2 Yes \n", + "... ... ... ... ... ... ... \n", + "7038 Male 0 Yes Yes 24 Yes \n", + "7039 Female 0 Yes Yes 72 Yes \n", + "7040 Female 0 Yes Yes 11 No \n", + "7041 Male 1 Yes No 4 Yes \n", + "7042 Male 0 No No 66 Yes \n", + "\n", + " onlinesecurity onlinebackup deviceprotection techsupport streamingtv \\\n", + "0 No Yes No No No \n", + "1 Yes No Yes No No \n", + "2 Yes Yes No No No \n", + "3 Yes No Yes Yes No \n", + "4 No No No No No \n", + "... ... ... ... ... ... \n", + "7038 Yes No Yes Yes Yes \n", + "7039 No Yes Yes No Yes \n", + "7040 Yes No No No No \n", + "7041 No No No No No \n", + "7042 Yes No Yes Yes Yes \n", + "\n", + " streamingmovies contract monthlycharges totalcharges churn \n", + "0 No Month-to-month 29.85 29.85 No \n", + "1 No One year 56.95 1889.50 No \n", + "2 No Month-to-month 53.85 108.15 Yes \n", + "3 No One year 42.30 1840.75 No \n", + "4 No Month-to-month 70.70 151.65 Yes \n", + "... ... ... ... ... ... \n", + "7038 Yes One year 84.80 1990.50 No \n", + "7039 Yes One year 103.20 7362.90 No \n", + "7040 No Month-to-month 29.60 346.45 No \n", + "7041 No Month-to-month 74.40 306.60 Yes \n", + "7042 Yes Two year 105.65 6844.50 No \n", + "\n", + "[7043 rows x 16 columns]" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fill_mean(churndata, ['totalcharges'])" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "7811892c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "churndata['totalcharges'].isna().sum()" + ] + }, + { + "cell_type": "markdown", + "id": "ef4677c5", + "metadata": {}, + "source": [ + "## Use the following features: tenure, SeniorCitizen, MonthlyCharges and TotalCharges\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "3c235b3b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
tenureseniorcitizenmonthlychargestotalchargeschurn
01029.8529.85No
134056.951889.50No
22053.85108.15Yes
345042.301840.75No
42070.70151.65Yes
..................
703824084.801990.50No
7039720103.207362.90No
704011029.60346.45No
70414174.40306.60Yes
7042660105.656844.50No
\n", + "

7043 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " tenure seniorcitizen monthlycharges totalcharges churn\n", + "0 1 0 29.85 29.85 No\n", + "1 34 0 56.95 1889.50 No\n", + "2 2 0 53.85 108.15 Yes\n", + "3 45 0 42.30 1840.75 No\n", + "4 2 0 70.70 151.65 Yes\n", + "... ... ... ... ... ...\n", + "7038 24 0 84.80 1990.50 No\n", + "7039 72 0 103.20 7362.90 No\n", + "7040 11 0 29.60 346.45 No\n", + "7041 4 1 74.40 306.60 Yes\n", + "7042 66 0 105.65 6844.50 No\n", + "\n", + "[7043 rows x 5 columns]" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = churndata[['tenure', 'seniorcitizen', 'monthlycharges', 'totalcharges', 'churn']]\n", + "\n", + "data" + ] + }, + { + "cell_type": "markdown", + "id": "ae6f5abc", + "metadata": {}, + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5738d6d3", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "00118eee", + "metadata": {}, + "source": [ + "## Split the data into a training set and a test set.\n" + ] + }, + { + "cell_type": "markdown", + "id": "fdc871ee", + "metadata": {}, + "source": [ + "Here I will split first before normalizing / standardizing so it is similar to real time cases when we want to predict future customers " + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "2ed9856c", + "metadata": {}, + "outputs": [], + "source": [ + "X = data.drop('churn', axis =1)\n", + "y = data['churn']" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "af7dd0d7", + "metadata": {}, + "outputs": [], + "source": [ + "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "5033977b", + "metadata": {}, + "outputs": [], + "source": [ + "X_train_num = X_train.select_dtypes(np.number)\n", + "X_test_num = X_test.select_dtypes(np.number)" + ] + }, + { + "cell_type": "markdown", + "id": "feba8302", + "metadata": {}, + "source": [ + "## Scale the features either by using normalizer or a standard scaler." + ] + }, + { + "cell_type": "markdown", + "id": "8c45c86b", + "metadata": {}, + "source": [ + "### Scale the numericals" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "f70f1cb0", + "metadata": {}, + "outputs": [], + "source": [ + "transformer = StandardScaler().fit(X_train_num)\n", + "x_train_stand = transformer.transform(X_train_num)\n", + "\n", + "\n", + "# saving in a pickle\n", + "with open('num_train_transformer.pickle', 'wb') as file:\n", + " pickle.dump(transformer, file)\n", + " \n", + "# loading from a pickle \n", + "with open('num_train_transformer.pickle', 'rb') as file:\n", + " loaded_transformer = pickle.load(file)\n", + "\n", + "X_train_n = loaded_transformer.transform(X_train_num)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "2334aa7e", + "metadata": {}, + "outputs": [], + "source": [ + "transformer = StandardScaler().fit(X_test_num)\n", + "X_test_n = transformer.transform(X_test_num)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "d0abd101", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((5634, 4), (1409, 4))" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X_train_n.shape, X_test_n.shape" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "00d423f5", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "526cc711", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "b3fe43db", + "metadata": {}, + "source": [ + "## Fit a logistic regression model on the training data.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "2b0192a9", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "LogisticRegression(max_iter=10000, random_state=42)" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "classification = LogisticRegression(random_state=42, max_iter=10000)\n", + "classification.fit(X, y)" + ] + }, + { + "cell_type": "markdown", + "id": "07fb139e", + "metadata": {}, + "source": [ + "## Check the accuracy on the test data." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "50ce28a4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.8069552874378992" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "classification.score(X_test, y_test) # checking the score without the need for predictions" + ] + }, + { + "cell_type": "markdown", + "id": "587e2a45", + "metadata": {}, + "source": [ + "## Check for the imbalance" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "7a92c40c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "No 5174\n", + "Yes 1869\n", + "Name: churn, dtype: int64" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data['churn'].value_counts()" + ] + }, + { + "cell_type": "markdown", + "id": "24f0ea7d", + "metadata": {}, + "source": [ + "## Use the resampling strategies used in class for upsampling and downsampling to create a balance between the two classes" + ] + }, + { + "cell_type": "markdown", + "id": "818bebb1", + "metadata": {}, + "source": [ + "### Upsampling" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "876e424d", + "metadata": {}, + "outputs": [], + "source": [ + "category_No = data[data['churn'] == 'No']\n", + "category_Yes = data[data['churn'] == 'Yes']" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "33965b67", + "metadata": {}, + "outputs": [], + "source": [ + "category_Yes = category_Yes.sample(len(category_No), replace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "965a8ee7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(5174, 5) (5174, 5)\n" + ] + } + ], + "source": [ + "print(category_No.shape, category_Yes.shape)" + ] + }, + { + "cell_type": "markdown", + "id": "310717f7", + "metadata": {}, + "source": [ + "### Downsampling" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "e8500acd", + "metadata": {}, + "outputs": [], + "source": [ + "category_No_down = data[data['churn'] == 'No']\n", + "category_Yes_down = data[data['churn'] == 'Yes']" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "c2cb832b", + "metadata": {}, + "outputs": [], + "source": [ + "category_No_down = category_No_down.sample(len(category_Yes_down), replace = True)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "edabb733", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(1869, 5) (1869, 5)\n" + ] + } + ], + "source": [ + "print(category_No_down.shape, category_Yes_down.shape)" + ] + }, + { + "cell_type": "markdown", + "id": "2194aabe", + "metadata": {}, + "source": [ + "## Each time fit the model and see how the accuracy of the model is" + ] + }, + { + "cell_type": "markdown", + "id": "9fbb515c", + "metadata": {}, + "source": [ + "### Upsampling's accuracy" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "7a81ed43", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
tenureseniorcitizenmonthlychargestotalchargeschurn
01029.8529.85No
134056.951889.50No
345042.301840.75No
622089.101949.40No
710029.75301.90No
..................
167529078.902384.15Yes
25261019.4019.40Yes
50231070.3070.30Yes
49011074.7074.70Yes
23971088.3588.35Yes
\n", + "

10348 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " tenure seniorcitizen monthlycharges totalcharges churn\n", + "0 1 0 29.85 29.85 No\n", + "1 34 0 56.95 1889.50 No\n", + "3 45 0 42.30 1840.75 No\n", + "6 22 0 89.10 1949.40 No\n", + "7 10 0 29.75 301.90 No\n", + "... ... ... ... ... ...\n", + "1675 29 0 78.90 2384.15 Yes\n", + "2526 1 0 19.40 19.40 Yes\n", + "5023 1 0 70.30 70.30 Yes\n", + "4901 1 0 74.70 74.70 Yes\n", + "2397 1 0 88.35 88.35 Yes\n", + "\n", + "[10348 rows x 5 columns]" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "upsample_df = pd.concat([category_No, category_Yes])\n", + "upsample_df" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "b936b3fa", + "metadata": {}, + "outputs": [], + "source": [ + "X_up = upsample_df.drop('churn', axis = 1)\n", + "y_up = upsample_df['churn']" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "042a47df", + "metadata": {}, + "outputs": [], + "source": [ + "X_train, X_test, y_train, y_test = train_test_split(X_up, y_up, test_size=0.2, random_state=42)" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "3e51b049", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "LogisticRegression(max_iter=10000, random_state=42)" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "classification = LogisticRegression(random_state=42, max_iter=10000)\n", + "classification.fit(X_up, y_up)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "08361547", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.7328502415458937" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "classification.score(X_test, y_test) # checking the score without the need for predictions" + ] + }, + { + "cell_type": "markdown", + "id": "f921f113", + "metadata": {}, + "source": [ + "### Downscaling accuracy" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "8dd7d388", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
tenureseniorcitizenmonthlychargestotalchargeschurn
570419086.851564.40No
131248070.953629.20No
2684690105.207386.05No
482472197.257133.10No
40425051.35262.30No
..................
702112059.80727.80Yes
70269044.20403.35Yes
70321175.7575.75Yes
7034670102.956886.25Yes
70414174.40306.60Yes
\n", + "

3738 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " tenure seniorcitizen monthlycharges totalcharges churn\n", + "5704 19 0 86.85 1564.40 No\n", + "1312 48 0 70.95 3629.20 No\n", + "2684 69 0 105.20 7386.05 No\n", + "4824 72 1 97.25 7133.10 No\n", + "4042 5 0 51.35 262.30 No\n", + "... ... ... ... ... ...\n", + "7021 12 0 59.80 727.80 Yes\n", + "7026 9 0 44.20 403.35 Yes\n", + "7032 1 1 75.75 75.75 Yes\n", + "7034 67 0 102.95 6886.25 Yes\n", + "7041 4 1 74.40 306.60 Yes\n", + "\n", + "[3738 rows x 5 columns]" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "downsample_df = pd.concat([category_No_down, category_Yes_down])\n", + "downsample_df" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "6e2205be", + "metadata": {}, + "outputs": [], + "source": [ + "X_down = upsample_df.drop('churn', axis = 1)\n", + "y_down = upsample_df['churn']" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "223bff54", + "metadata": {}, + "outputs": [], + "source": [ + "X_train, X_test, y_train, y_test = train_test_split(X_down, y_down, test_size=0.2, random_state=42)" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "62370cbf", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "LogisticRegression(max_iter=10000, random_state=42)" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "classification = LogisticRegression(random_state=42, max_iter=10000)\n", + "classification.fit(X_down, y_down)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "507b16b7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.7328502415458937" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "classification.score(X_test, y_test) # checking the score without the need for predictions" + ] + }, + { + "cell_type": "markdown", + "id": "bad81c15", + "metadata": {}, + "source": [ + "### Result of upsampling and downsampling score" + ] + }, + { + "cell_type": "markdown", + "id": "8d85b2f7", + "metadata": {}, + "source": [ + "Same accuracy score is produced and I am not sure if that happens..... " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b88b869f", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.8.8" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": true + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Solutions.ipynb b/Solutions.ipynb new file mode 100644 index 0000000..fd4dfe2 --- /dev/null +++ b/Solutions.ipynb @@ -0,0 +1,2016 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "2e4f6e1b", + "metadata": {}, + "source": [ + "## Import libraries" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "ca212e64", + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "import datetime\n", + "import warnings\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "\n", + "from imblearn.over_sampling import SMOTE\n", + "from sklearn.model_selection import train_test_split\n", + "from sklearn.linear_model import LogisticRegression\n", + "from sklearn.metrics import confusion_matrix\n", + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "import pickle\n", + "\n", + "warnings.filterwarnings('ignore')" + ] + }, + { + "cell_type": "markdown", + "id": "879fa2fb", + "metadata": {}, + "source": [ + "## Load data" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "b6c0b1ed", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
genderSeniorCitizenPartnerDependentstenurePhoneServiceOnlineSecurityOnlineBackupDeviceProtectionTechSupportStreamingTVStreamingMoviesContractMonthlyChargesTotalChargesChurn
0Female0YesNo1NoNoYesNoNoNoNoMonth-to-month29.8529.85No
1Male0NoNo34YesYesNoYesNoNoNoOne year56.951889.5No
2Male0NoNo2YesYesYesNoNoNoNoMonth-to-month53.85108.15Yes
3Male0NoNo45NoYesNoYesYesNoNoOne year42.301840.75No
4Female0NoNo2YesNoNoNoNoNoNoMonth-to-month70.70151.65Yes
...................................................
7038Male0YesYes24YesYesNoYesYesYesYesOne year84.801990.5No
7039Female0YesYes72YesNoYesYesNoYesYesOne year103.207362.9No
7040Female0YesYes11NoYesNoNoNoNoNoMonth-to-month29.60346.45No
7041Male1YesNo4YesNoNoNoNoNoNoMonth-to-month74.40306.6Yes
7042Male0NoNo66YesYesNoYesYesYesYesTwo year105.656844.5No
\n", + "

7043 rows × 16 columns

\n", + "
" + ], + "text/plain": [ + " gender SeniorCitizen Partner Dependents tenure PhoneService \\\n", + "0 Female 0 Yes No 1 No \n", + "1 Male 0 No No 34 Yes \n", + "2 Male 0 No No 2 Yes \n", + "3 Male 0 No No 45 No \n", + "4 Female 0 No No 2 Yes \n", + "... ... ... ... ... ... ... \n", + "7038 Male 0 Yes Yes 24 Yes \n", + "7039 Female 0 Yes Yes 72 Yes \n", + "7040 Female 0 Yes Yes 11 No \n", + "7041 Male 1 Yes No 4 Yes \n", + "7042 Male 0 No No 66 Yes \n", + "\n", + " OnlineSecurity OnlineBackup DeviceProtection TechSupport StreamingTV \\\n", + "0 No Yes No No No \n", + "1 Yes No Yes No No \n", + "2 Yes Yes No No No \n", + "3 Yes No Yes Yes No \n", + "4 No No No No No \n", + "... ... ... ... ... ... \n", + "7038 Yes No Yes Yes Yes \n", + "7039 No Yes Yes No Yes \n", + "7040 Yes No No No No \n", + "7041 No No No No No \n", + "7042 Yes No Yes Yes Yes \n", + "\n", + " StreamingMovies Contract MonthlyCharges TotalCharges Churn \n", + "0 No Month-to-month 29.85 29.85 No \n", + "1 No One year 56.95 1889.5 No \n", + "2 No Month-to-month 53.85 108.15 Yes \n", + "3 No One year 42.30 1840.75 No \n", + "4 No Month-to-month 70.70 151.65 Yes \n", + "... ... ... ... ... ... \n", + "7038 Yes One year 84.80 1990.5 No \n", + "7039 Yes One year 103.20 7362.9 No \n", + "7040 No Month-to-month 29.60 346.45 No \n", + "7041 No Month-to-month 74.40 306.6 Yes \n", + "7042 Yes Two year 105.65 6844.5 No \n", + "\n", + "[7043 rows x 16 columns]" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "churndata = pd.read_csv('/Users/yuriawano/lab-handling-data-imbalance-classification/files_for_lab/Customer-Churn.csv')\n", + "churndata" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "3ad505a7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(7043, 16)" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "churndata.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "569f28be", + "metadata": {}, + "outputs": [], + "source": [ + "# standardize the header\n", + "churndata.columns = [columns.lower() for columns in churndata.columns]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "2fcd3922", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['gender', 'seniorcitizen', 'partner', 'dependents', 'tenure',\n", + " 'phoneservice', 'onlinesecurity', 'onlinebackup', 'deviceprotection',\n", + " 'techsupport', 'streamingtv', 'streamingmovies', 'contract',\n", + " 'monthlycharges', 'totalcharges', 'churn'],\n", + " dtype='object')" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "churndata.columns" + ] + }, + { + "cell_type": "markdown", + "id": "f4bc0be4", + "metadata": {}, + "source": [ + "## Check the datatypes of all the columns in the data. \n", + "You would see that the column TotalCharges is object type. Convert this column into numeric type using pd.to_numeric function." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "58628135", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "gender object\n", + "seniorcitizen int64\n", + "partner object\n", + "dependents object\n", + "tenure int64\n", + "phoneservice object\n", + "onlinesecurity object\n", + "onlinebackup object\n", + "deviceprotection object\n", + "techsupport object\n", + "streamingtv object\n", + "streamingmovies object\n", + "contract object\n", + "monthlycharges float64\n", + "totalcharges object\n", + "churn object\n", + "dtype: object" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "churndata.dtypes" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "e512e97d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
totalcharges
029.85
11889.50
2108.15
31840.75
4151.65
......
70381990.50
70397362.90
7040346.45
7041306.60
70426844.50
\n", + "

7043 rows × 1 columns

\n", + "
" + ], + "text/plain": [ + " totalcharges\n", + "0 29.85\n", + "1 1889.50\n", + "2 108.15\n", + "3 1840.75\n", + "4 151.65\n", + "... ...\n", + "7038 1990.50\n", + "7039 7362.90\n", + "7040 346.45\n", + "7041 306.60\n", + "7042 6844.50\n", + "\n", + "[7043 rows x 1 columns]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "churndata[['totalcharges']] = churndata[['totalcharges']].apply(pd.to_numeric, errors='coerce')\n", + "churndata[['totalcharges']]" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "c7247811", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "dtype('float64')" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "churndata['totalcharges'].dtypes" + ] + }, + { + "cell_type": "markdown", + "id": "2d98f917", + "metadata": {}, + "source": [ + "## Deal with null values" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "fa36e5d8", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "gender 0\n", + "seniorcitizen 0\n", + "partner 0\n", + "dependents 0\n", + "tenure 0\n", + "phoneservice 0\n", + "onlinesecurity 0\n", + "onlinebackup 0\n", + "deviceprotection 0\n", + "techsupport 0\n", + "streamingtv 0\n", + "streamingmovies 0\n", + "contract 0\n", + "monthlycharges 0\n", + "totalcharges 11\n", + "churn 0\n", + "dtype: int64" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "churndata.isna().sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "71037922", + "metadata": {}, + "outputs": [], + "source": [ + "def fill_mean(data, columns):\n", + " \"\"\"\n", + " data: dataframe\n", + " columns: columns\n", + " return: modified dataframe with mean filled \n", + " \"\"\"\n", + " \n", + " for col in columns:\n", + " mean_value = data[columns].mean()\n", + " data[columns] = data[columns].fillna(mean_value)\n", + " \n", + " return data" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "9eabb326", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
genderseniorcitizenpartnerdependentstenurephoneserviceonlinesecurityonlinebackupdeviceprotectiontechsupportstreamingtvstreamingmoviescontractmonthlychargestotalchargeschurn
0Female0YesNo1NoNoYesNoNoNoNoMonth-to-month29.8529.85No
1Male0NoNo34YesYesNoYesNoNoNoOne year56.951889.50No
2Male0NoNo2YesYesYesNoNoNoNoMonth-to-month53.85108.15Yes
3Male0NoNo45NoYesNoYesYesNoNoOne year42.301840.75No
4Female0NoNo2YesNoNoNoNoNoNoMonth-to-month70.70151.65Yes
...................................................
7038Male0YesYes24YesYesNoYesYesYesYesOne year84.801990.50No
7039Female0YesYes72YesNoYesYesNoYesYesOne year103.207362.90No
7040Female0YesYes11NoYesNoNoNoNoNoMonth-to-month29.60346.45No
7041Male1YesNo4YesNoNoNoNoNoNoMonth-to-month74.40306.60Yes
7042Male0NoNo66YesYesNoYesYesYesYesTwo year105.656844.50No
\n", + "

7043 rows × 16 columns

\n", + "
" + ], + "text/plain": [ + " gender seniorcitizen partner dependents tenure phoneservice \\\n", + "0 Female 0 Yes No 1 No \n", + "1 Male 0 No No 34 Yes \n", + "2 Male 0 No No 2 Yes \n", + "3 Male 0 No No 45 No \n", + "4 Female 0 No No 2 Yes \n", + "... ... ... ... ... ... ... \n", + "7038 Male 0 Yes Yes 24 Yes \n", + "7039 Female 0 Yes Yes 72 Yes \n", + "7040 Female 0 Yes Yes 11 No \n", + "7041 Male 1 Yes No 4 Yes \n", + "7042 Male 0 No No 66 Yes \n", + "\n", + " onlinesecurity onlinebackup deviceprotection techsupport streamingtv \\\n", + "0 No Yes No No No \n", + "1 Yes No Yes No No \n", + "2 Yes Yes No No No \n", + "3 Yes No Yes Yes No \n", + "4 No No No No No \n", + "... ... ... ... ... ... \n", + "7038 Yes No Yes Yes Yes \n", + "7039 No Yes Yes No Yes \n", + "7040 Yes No No No No \n", + "7041 No No No No No \n", + "7042 Yes No Yes Yes Yes \n", + "\n", + " streamingmovies contract monthlycharges totalcharges churn \n", + "0 No Month-to-month 29.85 29.85 No \n", + "1 No One year 56.95 1889.50 No \n", + "2 No Month-to-month 53.85 108.15 Yes \n", + "3 No One year 42.30 1840.75 No \n", + "4 No Month-to-month 70.70 151.65 Yes \n", + "... ... ... ... ... ... \n", + "7038 Yes One year 84.80 1990.50 No \n", + "7039 Yes One year 103.20 7362.90 No \n", + "7040 No Month-to-month 29.60 346.45 No \n", + "7041 No Month-to-month 74.40 306.60 Yes \n", + "7042 Yes Two year 105.65 6844.50 No \n", + "\n", + "[7043 rows x 16 columns]" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fill_mean(churndata, ['totalcharges'])" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "7811892c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "churndata['totalcharges'].isna().sum()" + ] + }, + { + "cell_type": "markdown", + "id": "ef4677c5", + "metadata": {}, + "source": [ + "## Use the following features: tenure, SeniorCitizen, MonthlyCharges and TotalCharges\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "3c235b3b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
tenureseniorcitizenmonthlychargestotalchargeschurn
01029.8529.85No
134056.951889.50No
22053.85108.15Yes
345042.301840.75No
42070.70151.65Yes
..................
703824084.801990.50No
7039720103.207362.90No
704011029.60346.45No
70414174.40306.60Yes
7042660105.656844.50No
\n", + "

7043 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " tenure seniorcitizen monthlycharges totalcharges churn\n", + "0 1 0 29.85 29.85 No\n", + "1 34 0 56.95 1889.50 No\n", + "2 2 0 53.85 108.15 Yes\n", + "3 45 0 42.30 1840.75 No\n", + "4 2 0 70.70 151.65 Yes\n", + "... ... ... ... ... ...\n", + "7038 24 0 84.80 1990.50 No\n", + "7039 72 0 103.20 7362.90 No\n", + "7040 11 0 29.60 346.45 No\n", + "7041 4 1 74.40 306.60 Yes\n", + "7042 66 0 105.65 6844.50 No\n", + "\n", + "[7043 rows x 5 columns]" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = churndata[['tenure', 'seniorcitizen', 'monthlycharges', 'totalcharges', 'churn']]\n", + "\n", + "data" + ] + }, + { + "cell_type": "markdown", + "id": "ae6f5abc", + "metadata": {}, + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5738d6d3", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "00118eee", + "metadata": {}, + "source": [ + "## Split the data into a training set and a test set.\n" + ] + }, + { + "cell_type": "markdown", + "id": "fdc871ee", + "metadata": {}, + "source": [ + "Here I will split first before normalizing / standardizing so it is similar to real time cases when we want to predict future customers " + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "2ed9856c", + "metadata": {}, + "outputs": [], + "source": [ + "X = data.drop('churn', axis =1)\n", + "y = data['churn']" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "af7dd0d7", + "metadata": {}, + "outputs": [], + "source": [ + "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "5033977b", + "metadata": {}, + "outputs": [], + "source": [ + "X_train_num = X_train.select_dtypes(np.number)\n", + "X_test_num = X_test.select_dtypes(np.number)" + ] + }, + { + "cell_type": "markdown", + "id": "feba8302", + "metadata": {}, + "source": [ + "## Scale the features either by using normalizer or a standard scaler." + ] + }, + { + "cell_type": "markdown", + "id": "8c45c86b", + "metadata": {}, + "source": [ + "### Scale the numericals" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "f70f1cb0", + "metadata": {}, + "outputs": [], + "source": [ + "transformer = StandardScaler().fit(X_train_num)\n", + "x_train_stand = transformer.transform(X_train_num)\n", + "\n", + "\n", + "# saving in a pickle\n", + "with open('num_train_transformer.pickle', 'wb') as file:\n", + " pickle.dump(transformer, file)\n", + " \n", + "# loading from a pickle \n", + "with open('num_train_transformer.pickle', 'rb') as file:\n", + " loaded_transformer = pickle.load(file)\n", + "\n", + "X_train_n = loaded_transformer.transform(X_train_num)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "2334aa7e", + "metadata": {}, + "outputs": [], + "source": [ + "transformer = StandardScaler().fit(X_test_num)\n", + "X_test_n = transformer.transform(X_test_num)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "d0abd101", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((5634, 4), (1409, 4))" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X_train_n.shape, X_test_n.shape" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "00d423f5", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "526cc711", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "b3fe43db", + "metadata": {}, + "source": [ + "## Fit a logistic regression model on the training data.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "2b0192a9", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "LogisticRegression(max_iter=10000, random_state=42)" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "classification = LogisticRegression(random_state=42, max_iter=10000)\n", + "classification.fit(X, y)" + ] + }, + { + "cell_type": "markdown", + "id": "07fb139e", + "metadata": {}, + "source": [ + "## Check the accuracy on the test data." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "50ce28a4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.8069552874378992" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "classification.score(X_test, y_test) # checking the score without the need for predictions" + ] + }, + { + "cell_type": "markdown", + "id": "587e2a45", + "metadata": {}, + "source": [ + "## Check for the imbalance" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "7a92c40c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "No 5174\n", + "Yes 1869\n", + "Name: churn, dtype: int64" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data['churn'].value_counts()" + ] + }, + { + "cell_type": "markdown", + "id": "24f0ea7d", + "metadata": {}, + "source": [ + "## Use the resampling strategies used in class for upsampling and downsampling to create a balance between the two classes" + ] + }, + { + "cell_type": "markdown", + "id": "818bebb1", + "metadata": {}, + "source": [ + "### Upsampling" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "876e424d", + "metadata": {}, + "outputs": [], + "source": [ + "category_No = data[data['churn'] == 'No']\n", + "category_Yes = data[data['churn'] == 'Yes']" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "33965b67", + "metadata": {}, + "outputs": [], + "source": [ + "category_Yes = category_Yes.sample(len(category_No), replace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "965a8ee7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(5174, 5) (5174, 5)\n" + ] + } + ], + "source": [ + "print(category_No.shape, category_Yes.shape)" + ] + }, + { + "cell_type": "markdown", + "id": "310717f7", + "metadata": {}, + "source": [ + "### Downsampling" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "e8500acd", + "metadata": {}, + "outputs": [], + "source": [ + "category_No_down = data[data['churn'] == 'No']\n", + "category_Yes_down = data[data['churn'] == 'Yes']" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "c2cb832b", + "metadata": {}, + "outputs": [], + "source": [ + "category_No_down = category_No_down.sample(len(category_Yes_down), replace = True)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "edabb733", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(1869, 5) (1869, 5)\n" + ] + } + ], + "source": [ + "print(category_No_down.shape, category_Yes_down.shape)" + ] + }, + { + "cell_type": "markdown", + "id": "2194aabe", + "metadata": {}, + "source": [ + "## Each time fit the model and see how the accuracy of the model is" + ] + }, + { + "cell_type": "markdown", + "id": "9fbb515c", + "metadata": {}, + "source": [ + "### Upsampling's accuracy" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "7a81ed43", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
tenureseniorcitizenmonthlychargestotalchargeschurn
01029.8529.85No
134056.951889.50No
345042.301840.75No
622089.101949.40No
710029.75301.90No
..................
167529078.902384.15Yes
25261019.4019.40Yes
50231070.3070.30Yes
49011074.7074.70Yes
23971088.3588.35Yes
\n", + "

10348 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " tenure seniorcitizen monthlycharges totalcharges churn\n", + "0 1 0 29.85 29.85 No\n", + "1 34 0 56.95 1889.50 No\n", + "3 45 0 42.30 1840.75 No\n", + "6 22 0 89.10 1949.40 No\n", + "7 10 0 29.75 301.90 No\n", + "... ... ... ... ... ...\n", + "1675 29 0 78.90 2384.15 Yes\n", + "2526 1 0 19.40 19.40 Yes\n", + "5023 1 0 70.30 70.30 Yes\n", + "4901 1 0 74.70 74.70 Yes\n", + "2397 1 0 88.35 88.35 Yes\n", + "\n", + "[10348 rows x 5 columns]" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "upsample_df = pd.concat([category_No, category_Yes])\n", + "upsample_df" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "b936b3fa", + "metadata": {}, + "outputs": [], + "source": [ + "X_up = upsample_df.drop('churn', axis = 1)\n", + "y_up = upsample_df['churn']" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "042a47df", + "metadata": {}, + "outputs": [], + "source": [ + "X_train, X_test, y_train, y_test = train_test_split(X_up, y_up, test_size=0.2, random_state=42)" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "3e51b049", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "LogisticRegression(max_iter=10000, random_state=42)" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "classification = LogisticRegression(random_state=42, max_iter=10000)\n", + "classification.fit(X_up, y_up)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "08361547", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.7328502415458937" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "classification.score(X_test, y_test) # checking the score without the need for predictions" + ] + }, + { + "cell_type": "markdown", + "id": "f921f113", + "metadata": {}, + "source": [ + "### Downscaling accuracy" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "8dd7d388", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
tenureseniorcitizenmonthlychargestotalchargeschurn
570419086.851564.40No
131248070.953629.20No
2684690105.207386.05No
482472197.257133.10No
40425051.35262.30No
..................
702112059.80727.80Yes
70269044.20403.35Yes
70321175.7575.75Yes
7034670102.956886.25Yes
70414174.40306.60Yes
\n", + "

3738 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " tenure seniorcitizen monthlycharges totalcharges churn\n", + "5704 19 0 86.85 1564.40 No\n", + "1312 48 0 70.95 3629.20 No\n", + "2684 69 0 105.20 7386.05 No\n", + "4824 72 1 97.25 7133.10 No\n", + "4042 5 0 51.35 262.30 No\n", + "... ... ... ... ... ...\n", + "7021 12 0 59.80 727.80 Yes\n", + "7026 9 0 44.20 403.35 Yes\n", + "7032 1 1 75.75 75.75 Yes\n", + "7034 67 0 102.95 6886.25 Yes\n", + "7041 4 1 74.40 306.60 Yes\n", + "\n", + "[3738 rows x 5 columns]" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "downsample_df = pd.concat([category_No_down, category_Yes_down])\n", + "downsample_df" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "6e2205be", + "metadata": {}, + "outputs": [], + "source": [ + "X_down = upsample_df.drop('churn', axis = 1)\n", + "y_down = upsample_df['churn']" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "223bff54", + "metadata": {}, + "outputs": [], + "source": [ + "X_train, X_test, y_train, y_test = train_test_split(X_down, y_down, test_size=0.2, random_state=42)" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "62370cbf", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "LogisticRegression(max_iter=10000, random_state=42)" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "classification = LogisticRegression(random_state=42, max_iter=10000)\n", + "classification.fit(X_down, y_down)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "507b16b7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.7328502415458937" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "classification.score(X_test, y_test) # checking the score without the need for predictions" + ] + }, + { + "cell_type": "markdown", + "id": "bad81c15", + "metadata": {}, + "source": [ + "### Result of upsampling and downsampling score" + ] + }, + { + "cell_type": "markdown", + "id": "8d85b2f7", + "metadata": {}, + "source": [ + "Same accuracy score is produced and I am not sure if that happens..... " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b88b869f", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.8.8" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": true + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/num_train_transformer.pickle b/num_train_transformer.pickle new file mode 100644 index 0000000..c620100 Binary files /dev/null and b/num_train_transformer.pickle differ