{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Identifying Locations with High Growth Potential\n", "\n", " \n", "### Overview\n", "Our objective is to identify areas across the country with high growth potential for life insurance sales. Current tools in the market can provide underlying data, but they rely on users to perform their own analysis, and the software can be costly.\n", "\n", "To address this problem, we use publicly available tax data and a deep learning algorithm to generate a growth index. This index effectively identifies areas with the highest growth potential for life insurance sales.\n", "\n", "### Source Data\n", "We are using a publicly available data set: Individual income tax data by zip code, available from the [IRS Website](https://www.irs.gov/statistics/soi-tax-stats-individual-income-tax-statistics-zip-code-data-soi). This data contains information such as number of joint returns, number of dependents, salaries & wages, and number of returns with property taxes. The data is split by state, zip code, and adjusted gross income (AGI) bucket.\n", "\n", "### Predictive Model\n", "To create a growth index by zip code and AGI bucket, we need to project the number of returns, number of dependents, etc. over the next several years. To do so, we need a regression algorithm that is specific to each zip code and AGI bucket. There are about 80,000+ combinations of zip code and AGI bucket in the U.S., so creating 80,000+ regressions can be computationally intensive. Therefore, we utilize a deep learning algorithm which has some advantages:\n", "- Traditional regression algorithms have improved performance by carefully selecting and designing input variables. The performance of a deep learning algorithm is less dependent on variable selection and design due to the complex, non-linear nature of the algorithm.\n", "- For cohorts with sparse data, it will rely on aggregate trends to supplement credibility gaps.\n", "- The run time and model performance is superior to creating individual regression models for each cohort.\n", "- Multiple output variables can be modeled simultaniously in the same model\n", "\n", "\n", "--------------------------------------------------------------" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Beginning of Code\n", "\n", "We start by importing the necessary libraries for the model. We will be using the Keras library for the deep learning algorithm. Note that we are using Python and Keras versions 3.7.3 and 2.2.4 respectively." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Using TensorFlow backend.\n" ] } ], "source": [ "#Import Libraries\n", "import csv\n", "import itertools\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import keras\n", "from keras import regularizers\n", "from keras.models import Sequential\n", "from keras.utils import to_categorical\n", "from keras.layers import Dense, Activation, BatchNormalization" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Data Preprocessing - Part 1\n", "\n", "In the next code block, we load data for years 2009 - 2016. The data can be downloaded from the [IRS Website](https://www.irs.gov/statistics/soi-tax-stats-individual-income-tax-statistics-zip-code-data-soi). To effectively run the code, extract the csv files for each year in the same folder as this python notebook. We have included state and AGI bucket filters to illustrate the model capabilities while managing run time.\n", "\n", "Seven fields are plucked from the data sets:\n", "1. State\n", "2. Zip Code\n", "3. AGI Cohort\n", "4. Number of joint returns - represents households with married couples\n", "5. Number of dependents - represents households with children\n", "6. Income and Wages - represents financial health\n", "7. Number of returns with real estate taxes - represents home ownership\n", "\n", "Fields 1-3 are model inputs and fields 4-7 are the outputs. These outputs are associated with life events which are key drivers of life insurance sales, based on an [article published by Deloitte](https://www2.deloitte.com/insights/us/en/industry/financial-services/marketing-life-insurance-in-a-digital-age.html )\n", "\n", "In the subsequent code block, we remove zip codes \"00000\" which represent totals for each state, and \"99999\" which are unknown zip codes." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "#read in file names and append values of specific columns to rows of array\n", "filename_list = ['09zpallagi.csv','10zpallagi.csv','11zpallagi.csv','12zpallagi.csv','13zpallagi.csv','14zpallagi.csv','15zpallagi.csv','16zpallagi.csv']\n", "year_list = ['2009','2010','2011','2012','2013','2014','2015','2016']\n", "state_list = ['NV']\n", "agi_filter = ['4']\n", "data = []\n", "file_count = 0\n", "\n", "#Lowercase keys in Python Dictionaries\n", "def lower_first(iterator):\n", " return itertools.chain([next(iterator).lower()],iterator)\n", "\n", "def load_data(filename, year):\n", " with open(filename) as taxinput_file:\n", " reader = csv.DictReader(lower_first(taxinput_file))\n", " for row in reader:\n", " if row['state'] in state_list and row['agi_stub'] in agi_filter:\n", " data.append([row['zipcode'].zfill(5),row['agi_stub'],year,row['mars2'],row['numdep'],row['a00200'],row['n18500']])\n", " return;\n", "\n", "for file in filename_list:\n", " load_data(file, year_list[file_count])\n", " file_count += 1" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# Strip out the zip codes \"00000\" (Totals for each state) and \"99999\" (unknown zip codes/not reported\n", "data_clean = []\n", "\n", "for row in data:\n", " if row[0]=='00000' or row[0]=='99999':\n", " continue\n", " else:\n", " data_clean.append(row)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Data Preprocessing - Part 2\n", "\n", "We continue preprocessing the data by splitting it into separate train and test data sets. The test data set allows us to identify when overfitting is occuring, and we apply an L2 regularization parameter to compensate. Notice that the training data is based on years 2009-2015, and the test data is based on 2016. We chose this approach instead of a random sampling because the model's objective is optimize extrapolation of data points instead of interpolation and extrapolation.\n", "\n", "Then, we create a unique list of all zip codes and remove data set records where zip codes were newly created or removed throughout time. This provides a cleaner basis for the data." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "#Split data between test and train\n", "train_year = ['2009','2010','2011','2012','2013','2014','2015']\n", "train_data = []\n", "test_data = []\n", "\n", "for row in data_clean:\n", " if row[2] in train_year:\n", " train_data.append(row)\n", " else:\n", " test_data.append(row)\n", "\n", "train_data = np.array(train_data)\n", "test_data = np.array(test_data)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "#Create a unique list of zip codes and filter to include only zip codes in all years\n", "unique_zipcode_list = []\n", "\n", "for row in train_data:\n", " if row[2] == train_year[0] and row[0] not in unique_zipcode_list:\n", " unique_zipcode_list.append(row[0])\n", " else:\n", " continue\n", "\n", "for zipcode in unique_zipcode_list:\n", " if zipcode not in train_data[:,0] or zipcode not in test_data[:,0]:\n", " unique_zipcode_list.remove(zipcode)\n", " else:\n", " continue" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "#Delete records from the training data with zip codes not in the unique zip code list\n", "filter_list = []\n", "row_count = 0\n", "\n", "for row in train_data:\n", " if row[0] in unique_zipcode_list:\n", " filter_list.append(row_count)\n", " row_count += 1\n", "\n", "train_data = train_data[filter_list]" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "#Delete records from the training data with zip codes not in the unique zip code list\n", "filter_list = []\n", "row_count = 0\n", "\n", "for row in test_data:\n", " if row[0] in unique_zipcode_list:\n", " filter_list.append(row_count)\n", " row_count += 1\n", " \n", "test_data = test_data[filter_list]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Data Preprocessing - Part 3\n", "\n", "The next three code blocks perform the following functions:\n", "\n", "1. We shuffle the data to improve mini-batch gradient descent performance\n", "2. Columns are split into input variables (x) and output variables (y)\n", "3. Output variables are normalized to improve training performance\n", "4. Zip codes are nominal variables (the order does not matter). Deep learning algorithms perform significantly better if nominal values are one-hot encoded. This means creating a separate column for each zip code with a binary indicator (1 or 0) for each row where the zip code is applicable." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "#Shuffle training data by row and split input and output for use in model\n", "row = np.random.choice(train_data.shape[0], train_data.shape[0], replace = False)\n", "train_data = train_data[row]\n", "\n", "x_columns = 3\n", "y_columns = train_data.shape[1]\n", "\n", "x_train = train_data[0:,0:x_columns]\n", "y_train = np.array(train_data[0:,x_columns:y_columns], dtype=float)\n", "x_test = test_data[0:,0:x_columns]\n", "y_test = np.array(test_data[0:,x_columns:y_columns], dtype=float)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "#Normalize Output Variables\n", "y_train_mean = np.mean(y_train, axis=0)\n", "y_train_stdev = np.std(y_train, axis=0)\n", "\n", "y_train_norm = np.divide(y_train - y_train_mean, y_train_stdev)\n", "y_test_norm = np.divide(y_test - y_train_mean, y_train_stdev)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "#One hot encode training data\n", "x_train_encode = np.zeros((x_train.shape[0],len(unique_zipcode_list)))\n", "unique_zipcode_list = np.array(unique_zipcode_list)\n", "\n", "for row in range(x_train.shape[0]): \n", " x_train_encode[row,x_train[row,0]== unique_zipcode_list] = 1\n", "\n", "x_train_encode = np.array(np.append(x_train_encode,x_train[0:,1:3],axis = 1), dtype=float)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "#One hot encode test data\n", "x_test_encode = np.zeros((x_test.shape[0],len(unique_zipcode_list)))\n", "unique_zipcode_list = np.array(unique_zipcode_list)\n", "\n", "for row in range(x_test.shape[0]): \n", " x_test_encode[row,x_test[row,0]== unique_zipcode_list] = 1\n", " \n", "x_test_encode = np.array(np.append(x_test_encode,x_test[0:,1:3],axis = 1), dtype=float)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Building and Training the Model\n", "- We clear any parameters that may have been run previously.\n", "- We defined the deep network architecture using the `model.add` method from Keras\n", " - `BatchNormalization()` at the start and between layers normalizes inputs for faster training\n", " - The model has 4 hidden layers with 100, 50, 25, 10 activation nodes respectively. \n", " - Each hidden layer uses a rectified linear unit (ReLU) activation function. This returns a linear function for positive parameters, and zero for negative parameters.\n", " - The model has an output layer with 4 linear regression outputs. The deep learning algorithm allows us to model all four target output variables simultaniously instead of needing 4 separate models.\n", " - The model employs L2 regularization in each layer, and the regularization parameter has been tuned to reduce overfitting in the output.\n", "- For the model optimizer, we are using Adam optimization, a variant of gradient descent\n", "- Since the output layer is linear, we decided to use mean squared error for the loss function\n", "- The model is trained using mini-batches (runs 5,000 records at a time), and 20,000 epochs (full iterations of the data set)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "#Clear weights between model runs\n", "keras.backend.clear_session()" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "#Deep Learning Model\n", "model = Sequential()\n", "model.add(BatchNormalization())\n", "model.add(Dense(100, activation='relu', kernel_regularizer=regularizers.l2(0.2)))\n", "model.add(BatchNormalization())\n", "model.add(Dense(50, activation='relu', kernel_regularizer=regularizers.l2(0.2)))\n", "model.add(BatchNormalization())\n", "model.add(Dense(25, activation='relu', kernel_regularizer=regularizers.l2(0.2)))\n", "model.add(BatchNormalization())\n", "model.add(Dense(10, activation='relu', kernel_regularizer=regularizers.l2(0.2)))\n", "model.add(BatchNormalization())\n", "model.add(Dense(4,kernel_regularizer=regularizers.l2(0.2)))" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "#Loss Function\n", "adam_opt = keras.optimizers.Adam(lr=0.001,beta_1=0.99)\n", "model.compile(optimizer = adam_opt, loss='mean_squared_error')" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Starting Loss=1082.6692254\n", "Epoch 1000 complete : Train_Loss=0.1271545 : Test_Loss:0.1467361\n", "Epoch 2000 complete : Train_Loss=0.0538417 : Test_Loss:0.0715677\n", "Epoch 3000 complete : Train_Loss=0.0412756 : Test_Loss:0.0589698\n", "Epoch 4000 complete : Train_Loss=0.0324949 : Test_Loss:0.051852\n", "Epoch 5000 complete : Train_Loss=0.0278636 : Test_Loss:0.0448968\n", "Epoch 6000 complete : Train_Loss=0.0240046 : Test_Loss:0.0397897\n", "Epoch 7000 complete : Train_Loss=0.0207874 : Test_Loss:0.0350065\n", "Epoch 8000 complete : Train_Loss=0.1340252 : Test_Loss:0.1298236\n", "Epoch 9000 complete : Train_Loss=0.0159977 : Test_Loss:0.0284639\n", "Epoch 10000 complete : Train_Loss=0.0151543 : Test_Loss:0.0269539\n", "Epoch 11000 complete : Train_Loss=0.0146448 : Test_Loss:0.0256589\n", "Epoch 12000 complete : Train_Loss=0.1179967 : Test_Loss:0.1353134\n", "Epoch 13000 complete : Train_Loss=0.0052528 : Test_Loss:0.0139628\n", "Epoch 14000 complete : Train_Loss=0.0053809 : Test_Loss:0.013802\n", "Epoch 15000 complete : Train_Loss=0.0065301 : Test_Loss:0.0159719\n", "Epoch 16000 complete : Train_Loss=0.003388 : Test_Loss:0.0133884\n", "Epoch 17000 complete : Train_Loss=0.0039044 : Test_Loss:0.0142689\n", "Epoch 18000 complete : Train_Loss=0.0080016 : Test_Loss:0.0167013\n", "Epoch 19000 complete : Train_Loss=0.0037693 : Test_Loss:0.0132897\n", "Epoch 20000 complete : Train_Loss=0.0035554 : Test_Loss:0.0143958\n", "\n", "Test set loss: 0.014395815926411796\n" ] } ], "source": [ "#Train Model (takes < 5 minutes to run)\n", "print(\"Starting Loss=\"+str(round(model.evaluate(x_train_encode, y_train_norm, verbose = 0),7)))\n", "\n", "for i in range(20):\n", " model.fit(x_train_encode, y_train_norm, verbose = 0, epochs = 1000, batch_size = 5000)\n", " print(\"Epoch \"+str((i+1)*1000)+\" complete : Train_Loss=\"+\n", " str(round(model.evaluate(x_train_encode, y_train_norm, verbose=0),7))+\n", " \" : Test_Loss:\" + str(round(model.evaluate(x_test_encode, y_test_norm, verbose=0),7)))\n", " i += 1\n", "\n", "print(\"\")\n", "print(\"Test set loss: \" + str(model.evaluate(x_test_encode, y_test_norm, verbose=0)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Model Summary\n", "The next cell provides a summary of the deep network architecture. Notice that ***20,155*** parameters are being trained! This is how the model is able to create regression functions for all the different zip code and AGI bucket cohorts." ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "_________________________________________________________________\n", "Layer (type) Output Shape Param # \n", "=================================================================\n", "batch_normalization_1 (Batch (None, 128) 512 \n", "_________________________________________________________________\n", "dense_1 (Dense) (None, 100) 12900 \n", "_________________________________________________________________\n", "batch_normalization_2 (Batch (None, 100) 400 \n", "_________________________________________________________________\n", "dense_2 (Dense) (None, 50) 5050 \n", "_________________________________________________________________\n", "batch_normalization_3 (Batch (None, 50) 200 \n", "_________________________________________________________________\n", "dense_3 (Dense) (None, 25) 1275 \n", "_________________________________________________________________\n", "batch_normalization_4 (Batch (None, 25) 100 \n", "_________________________________________________________________\n", "dense_4 (Dense) (None, 10) 260 \n", "_________________________________________________________________\n", "batch_normalization_5 (Batch (None, 10) 40 \n", "_________________________________________________________________\n", "dense_5 (Dense) (None, 4) 44 \n", "=================================================================\n", "Total params: 20,781\n", "Trainable params: 20,155\n", "Non-trainable params: 626\n", "_________________________________________________________________\n" ] } ], "source": [ "model.summary()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Visualizing a Sample Zip Code\n", "The following code block creates a graph for a sample zip code. Notice how the model is able to effectively trend each of the output variables from 2017 through 2020." ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "#Plot the projections for a sample zip code\n", "sample_zip_code = '89117'\n", "sample_list_train = x_train[:,0] == sample_zip_code\n", "forecast_yrs = np.array([2016, 2017, 2018, 2019, 2020])\n", "\n", "enc_1 = x_test_encode[x_test[:,0] == sample_zip_code,:-1]\n", "x_forecast = np.column_stack((np.vstack((enc_1,enc_1,enc_1,enc_1,enc_1)),forecast_yrs))\n", "y_forecast = np.column_stack((x_train[sample_list_train,:-1][0:5,:],forecast_yrs,\n", " model.predict(x_forecast) * y_train_stdev + y_train_mean)) \n", "\n", "sample_zip_train = np.hstack((x_train[sample_list_train],y_train[sample_list_train]))\n", "sample_zip = np.vstack((sample_zip_train[np.argsort(sample_zip_train[:,2])],y_forecast))\n", "\n", "plt.plot(sample_zip[:,2], sample_zip[:,3].astype(np.float), '.-', label='Married Couples')\n", "plt.plot(sample_zip[:,2], sample_zip[:,4].astype(np.float), '.-', label='Children')\n", "plt.plot(sample_zip[:,2], sample_zip[:,6].astype(np.float), '.-', label='Home Ownership')\n", "plt.ylabel('Count')\n", "plt.xlabel('Tax Reporting Year')\n", "plt.legend()\n", "plt.title(\"Key Indicators Forecast for zip code \" + sample_zip_code)\n", "\n", "plt.show" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Generating a Growth Index\n", "Finally, we use the predictive model we've created to estimate output variables (# of returns, dependents, etc.) for all zip codes. This information is transformed into a growth index which can be used to inform life insurance companies of high potential zip codes for growth opportunities. The weights for each output variable in the growth index is based on the previously mentioned [Deloitte article](https://www2.deloitte.com/insights/us/en/industry/financial-services/marketing-life-insurance-in-a-digital-age.html).\n", "\n", "In the output, we are reporting the top ten locations with highest growth potential." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Top 10 Locations with Growth Potential:\n", "\n", "Zip Code - Growth Index\n", "[['89117' '0.378']\n", " ['89031' '0.313']\n", " ['89123' '0.311']\n", " ['89130' '0.298']\n", " ['89147' '0.294']\n", " ['89143' '0.282']\n", " ['89128' '0.276']\n", " ['89115' '0.273']\n", " ['89002' '0.267']\n", " ['89523' '0.258']]\n" ] } ], "source": [ "#Generate 2020 predictions\n", "x_forecast = np.column_stack((x_test_encode[:,:-1],np.ones(x_test_encode.shape[0])*2017))\n", "y_forecast_norm = model.predict(x_forecast)\n", "\n", "#Calculate growth index\n", "growth_factors = [0.24, 0.28, 0.24, 0.24]\n", "y_test_growth = np.sum(np.multiply(y_test_norm,growth_factors),axis=1)\n", "\n", "y_forecast_growth = np.sum(np.multiply(y_forecast_norm,growth_factors),axis=1)\n", "\n", "growth_index = np.column_stack((x_test[:,0:2],np.round(y_forecast_growth - y_test_growth, 3)))\n", "growth_index = growth_index[np.argsort(-growth_index[:,2].astype(np.float))]\n", "\n", "print(\"Top 10 Locations with Growth Potential:\")\n", "print(\"\")\n", "print(\"Zip Code - Growth Index\")\n", "print(growth_index[0:10,[0,2]])" ] }, { "cell_type": "code", "execution_count": null, "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.7.3" } }, "nbformat": 4, "nbformat_minor": 2 }