I develop a deep learning classification model to predict listing gains for Initial Public Offerings (IPO) in the Indian market. This model can be useful to make investment decisions in the IPO market.
The dataset is available under the file name data.csv
(https://github.com/magorshunov/predicting_ipo_gains/blob/main/data.csv). Listing gains are the percentage increase in the share price of a company from its IPO issue price on the day of listing.
The data consists of following columns:
Date
: date when the IPO was listedIPOName
: name of the IPOIssue_Size
: size of the IPO issue, in INR CroresSubscription_QIB
: number of times the IPO was subscribed by the QIB (Qualified Institutional Buyer) investor categorySubscription_HNI
: number of times the IPO was subscribed by the HNI (High Networth Individual) investor categorySubscription_RII
: number of times the IPO was subscribed by the RII (Retail Individual Investors) investor categorySubscription_Total
: total number of times the IPO was subscribed overallIssue_Price
: the price in INR at which the IPO was issuedListing_Gains_Percent
: is the percentage gain in the listing price over the issue priceimport numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from math import sqrt
df = pd.read_csv('data.csv')
print(df.shape)
df.head()
(319, 9)
Date | IPOName | Issue_Size | Subscription_QIB | Subscription_HNI | Subscription_RII | Subscription_Total | Issue_Price | Listing_Gains_Percent | |
---|---|---|---|---|---|---|---|---|---|
0 | 03/02/10 | Infinite Comp | 189.80 | 48.44 | 106.02 | 11.08 | 43.22 | 165 | 11.82 |
1 | 08/02/10 | Jubilant Food | 328.70 | 59.39 | 51.95 | 3.79 | 31.11 | 145 | -84.21 |
2 | 15/02/10 | Syncom Health | 56.25 | 0.99 | 16.60 | 6.25 | 5.17 | 75 | 17.13 |
3 | 15/02/10 | Vascon Engineer | 199.80 | 1.12 | 3.65 | 0.62 | 1.22 | 165 | -11.28 |
4 | 19/02/10 | Thangamayil | 0.00 | 0.52 | 1.52 | 2.26 | 1.12 | 75 | -5.20 |
df.describe(include='all')
Date | IPOName | Issue_Size | Subscription_QIB | Subscription_HNI | Subscription_RII | Subscription_Total | Issue_Price | Listing_Gains_Percent | |
---|---|---|---|---|---|---|---|---|---|
count | 319 | 319 | 319.000000 | 319.000000 | 319.000000 | 319.000000 | 319.000000 | 319.000000 | 319.000000 |
unique | 287 | 319 | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
top | 16/08/21 | Infinite Comp | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
freq | 4 | 1 | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
mean | NaN | NaN | 1192.859969 | 25.684138 | 70.091379 | 8.561599 | 27.447147 | 375.128527 | 4.742696 |
std | NaN | NaN | 2384.643786 | 40.716782 | 142.454416 | 14.508670 | 48.772203 | 353.897614 | 47.650946 |
min | NaN | NaN | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | -97.150000 |
25% | NaN | NaN | 169.005000 | 1.150000 | 1.255000 | 1.275000 | 1.645000 | 119.000000 | -11.555000 |
50% | NaN | NaN | 496.250000 | 4.940000 | 5.070000 | 3.420000 | 4.930000 | 250.000000 | 1.810000 |
75% | NaN | NaN | 1100.000000 | 34.635000 | 62.095000 | 8.605000 | 33.395000 | 536.000000 | 25.310000 |
max | NaN | NaN | 21000.000000 | 215.450000 | 958.070000 | 119.440000 | 326.490000 | 2150.000000 | 270.400000 |
df['Listing_Gains_Percent'].describe()
count 319.000000 mean 4.742696 std 47.650946 min -97.150000 25% -11.555000 50% 1.810000 75% 25.310000 max 270.400000 Name: Listing_Gains_Percent, dtype: float64
df.isnull().sum()
Date 0 IPOName 0 Issue_Size 0 Subscription_QIB 0 Subscription_HNI 0 Subscription_RII 0 Subscription_Total 0 Issue_Price 0 Listing_Gains_Percent 0 dtype: int64
The Listing_Gains_Percent
target variable is continous. Therfore, I will need to convert it into a categorical variable before I proceed. Approximately 55% of the IPOs listed in profit, and the data is fairly balanced. I have also dropped some of the variables that might not have predictive power.
df['Listing_Gains_Profit'] = df['Listing_Gains_Percent'].apply(lambda x: 1 if x > 0 else 0)
df['Listing_Gains_Profit'].describe()
count 319.000000 mean 0.545455 std 0.498712 min 0.000000 25% 0.000000 50% 1.000000 75% 1.000000 max 1.000000 Name: Listing_Gains_Profit, dtype: float64
df['Listing_Gains_Profit'].value_counts(normalize=True)
Listing_Gains_Profit 1 0.545455 0 0.454545 Name: proportion, dtype: float64
df.drop(['Date ', 'IPOName', 'Listing_Gains_Percent'], axis=1, inplace=True)
df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 319 entries, 0 to 318 Data columns (total 7 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Issue_Size 319 non-null float64 1 Subscription_QIB 319 non-null float64 2 Subscription_HNI 319 non-null float64 3 Subscription_RII 319 non-null float64 4 Subscription_Total 319 non-null float64 5 Issue_Price 319 non-null int64 6 Listing_Gains_Profit 319 non-null int64 dtypes: float64(5), int64(2) memory usage: 17.6 KB
I will check for the distribution of predictors with respect to the target variable, since they could be informative for modeling. To do that, I will:
Here are some of the findings:
The histogram and the boxplots show that outliers are present in the data and might need outlier treatment.
The boxplot of Issue_Price
, with respect to Listing_Gains_Profit
, shows that there are more outliers for IPOs that listed a loss than there are outliers for IPOs that listed a profit.
The scatterplot shows a correlation between Retail and Total IPO Subscription via a scatterplot.
# visualizing the target variable
sns.countplot(x='Listing_Gains_Profit', data=df)
plt.title('Distribution of IPO Listing Profit Category')
plt.xlabel('Listing Profit (No=0, Yes=1)')
plt.ylabel('Frequency')
plt.show()
plt.figure(figsize=[8,5])
sns.histplot(data=df, x='Issue_Price', bins=50).set(title='Distribution of Issue_Price', ylabel='Count')
plt.show()
plt.figure(figsize=[8,5])
sns.histplot(data=df, x='Issue_Size', bins=50).set(title='Distribution of Issue_Size', ylabel='Count')
plt.show()
sns.boxplot(data=df, y='Issue_Size')
plt.title('Boxplot of Issue_Size')
plt.show()
sns.boxplot(data=df, x='Listing_Gains_Profit', y='Issue_Price')
plt.title('Boxplot of Issue_Price with respect to Listing Gains Type')
plt.xlabel('Listing Profit (No=0, Yes=1)')
plt.show()
print(df.skew())
Issue_Size 4.853402 Subscription_QIB 2.143705 Subscription_HNI 3.078445 Subscription_RII 3.708274 Subscription_Total 2.911907 Issue_Price 1.696881 Listing_Gains_Profit -0.183438 dtype: float64
sns.boxplot(data=df, y='Subscription_QIB')
plt.title('Boxplot of Subscription_QIB')
plt.show()
sns.scatterplot(data=df, x='Subscription_RII', y='Subscription_Total')
plt.title('Scatterplot between Retail and Total IPO Subscription')
plt.show()
Apart from performing a visual inspection, outliers can also be identified with the skewness or the interquartile range (IQR) value. There are different approaches to outlier treatment, but the one I've used here is outlier identification using the interquartile menthod. Once I identified the outliers, I clipped the variable values between the upper and lower bounds.
q1 = df['Issue_Size'].quantile(q=0.25)
q3 = df['Issue_Size'].quantile(q=0.75)
iqr = q3 - q1
lower = (q1 - 1.5 * iqr)
upper = (q3 + 1.5 * iqr)
print('IQR = ', iqr, '\nlower = ', lower, '\nupper = ', upper, sep='')
IQR = 930.995 lower = -1227.4875000000002 upper = 2496.4925000000003
df['Issue_Size'] = df['Issue_Size'].clip(lower, upper)
df['Issue_Size'].describe()
count 319.000000 mean 763.561238 std 769.689122 min 0.000000 25% 169.005000 50% 496.250000 75% 1100.000000 max 2496.492500 Name: Issue_Size, dtype: float64
q1 = df['Subscription_QIB'].quantile(q=0.25)
q3 = df['Subscription_QIB'].quantile(q=0.75)
iqr = q3 - q1
lower = (q1 - 1.5 * iqr)
upper = (q3 + 1.5 * iqr)
print('IQR = ', iqr, '\nlower = ', lower, '\nupper = ', upper, sep='')
IQR = 33.48500000000001 lower = -49.07750000000001 upper = 84.86250000000001
df['Subscription_QIB'] = df['Subscription_QIB'].clip(lower, upper)
df['Subscription_QIB'].describe()
count 319.000000 mean 21.521183 std 29.104549 min 0.000000 25% 1.150000 50% 4.940000 75% 34.635000 max 84.862500 Name: Subscription_QIB, dtype: float64
q1 = df['Subscription_HNI'].quantile(q=0.25)
q3 = df['Subscription_HNI'].quantile(q=0.75)
iqr = q3 - q1
lower = (q1 - 1.5 * iqr)
upper = (q3 + 1.5 * iqr)
print('IQR = ', iqr, '\nlower = ', lower, '\nupper = ', upper, sep='')
IQR = 60.839999999999996 lower = -90.005 upper = 153.355
df['Subscription_HNI'] = df['Subscription_HNI'].clip(lower, upper)
df['Subscription_HNI'].describe()
count 319.000000 mean 40.356426 std 57.427921 min 0.000000 25% 1.255000 50% 5.070000 75% 62.095000 max 153.355000 Name: Subscription_HNI, dtype: float64
q1 = df['Subscription_RII'].quantile(q=0.25)
q3 = df['Subscription_RII'].quantile(q=0.75)
iqr = q3 - q1
lower = (q1 - 1.5 * iqr)
upper = (q3 + 1.5 * iqr)
print('IQR = ', iqr, '\nlower = ', lower, '\nupper = ', upper, sep='')
IQR = 7.33 lower = -9.72 upper = 19.6
df['Subscription_RII'] = df['Subscription_RII'].clip(lower, upper)
df['Subscription_RII'].describe()
count 319.000000 mean 6.060940 std 6.176882 min 0.000000 25% 1.275000 50% 3.420000 75% 8.605000 max 19.600000 Name: Subscription_RII, dtype: float64
q1 = df['Subscription_Total'].quantile(q=0.25)
q3 = df['Subscription_Total'].quantile(q=0.75)
iqr = q3 - q1
lower = (q1 - 1.5 * iqr)
upper = (q3 + 1.5 * iqr)
print('IQR = ', iqr, '\nlower = ', lower, '\nupper = ', upper, sep='')
IQR = 31.749999999999996 lower = -45.97999999999999 upper = 81.01999999999998
df['Subscription_Total'] = df['Subscription_Total'].clip(lower, upper)
df['Subscription_Total'].describe()
count 319.000000 mean 20.456646 std 27.217740 min 0.000000 25% 1.645000 50% 4.930000 75% 33.395000 max 81.020000 Name: Subscription_Total, dtype: float64
Before moving on to modelling, I will:
target_variable = ['Listing_Gains_Profit']
predictors = list(set(list(df.columns)) - set(target_variable))
df[predictors] = df[predictors]/df[predictors].max()
df.describe()
Issue_Size | Subscription_QIB | Subscription_HNI | Subscription_RII | Subscription_Total | Issue_Price | Listing_Gains_Profit | |
---|---|---|---|---|---|---|---|
count | 319.000000 | 319.000000 | 319.000000 | 319.000000 | 319.000000 | 319.000000 | 319.000000 |
mean | 0.305854 | 0.253601 | 0.263157 | 0.309232 | 0.252489 | 0.174478 | 0.545455 |
std | 0.308308 | 0.342961 | 0.374477 | 0.315147 | 0.335939 | 0.164604 | 0.498712 |
min | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
25% | 0.067697 | 0.013551 | 0.008184 | 0.065051 | 0.020304 | 0.055349 | 0.000000 |
50% | 0.198779 | 0.058212 | 0.033061 | 0.174490 | 0.060849 | 0.116279 | 1.000000 |
75% | 0.440618 | 0.408131 | 0.404910 | 0.439031 | 0.412182 | 0.249302 | 1.000000 |
max | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 |
I will use the hold out validation approach to model evaluation. In this approach, I will divide the data in the 70:30 ratio, where I will use 70% of the data for training the model, while I will use the other 30% of the data to test the model.
X = df[predictors].values
y = df[target_variable].values
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.30, random_state=100)
print(X_train.shape); print(X_test.shape)
(223, 6) (96, 6)
In this step, I've defined the model by instantiating the sequential model class in TensorFlow's Keras. The model architecture is comprised of four hidden layers with relu
as the activation function. The output layer uses a sigmoid
activation function, which is a good choice for a binary classification model.
# define model
tf.random.set_seed(100)
model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(32, input_shape = (X_train.shape[1],), activation = 'relu'))
model.add(tf.keras.layers.Dense(16, activation= 'relu'))
model.add(tf.keras.layers.Dense(8, activation= 'relu'))
model.add(tf.keras.layers.Dense(4, activation= 'relu'))
model.add(tf.keras.layers.Dense(1, activation='sigmoid'))
Once I have defined the model, the next steps are to compile and train it. Compiling a model requires specification of the following:
After compiling the model, I fitted it on the training set. The accuracy improved over epochs.
model.compile(optimizer=tf.keras.optimizers.Adam(0.001), loss=tf.keras.losses.BinaryCrossentropy(), metrics=['accuracy'])
print(model.summary())
Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense (Dense) (None, 32) 224 dense_1 (Dense) (None, 16) 528 dense_2 (Dense) (None, 8) 136 dense_3 (Dense) (None, 4) 36 dense_4 (Dense) (None, 1) 5 ================================================================= Total params: 929 Trainable params: 929 Non-trainable params: 0 _________________________________________________________________ None
model.fit(X_train, y_train, epochs=250)
Epoch 1/250 7/7 [==============================] - 1s 3ms/step - loss: 0.6899 - accuracy: 0.5874 Epoch 2/250 7/7 [==============================] - 0s 2ms/step - loss: 0.6859 - accuracy: 0.5650 Epoch 3/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6826 - accuracy: 0.5516 Epoch 4/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6771 - accuracy: 0.5561 Epoch 5/250 7/7 [==============================] - 0s 2ms/step - loss: 0.6729 - accuracy: 0.5561 Epoch 6/250 7/7 [==============================] - 0s 2ms/step - loss: 0.6680 - accuracy: 0.5561 Epoch 7/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6629 - accuracy: 0.5561 Epoch 8/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6586 - accuracy: 0.5561 Epoch 9/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6536 - accuracy: 0.5561 Epoch 10/250 7/7 [==============================] - 0s 2ms/step - loss: 0.6493 - accuracy: 0.5561 Epoch 11/250 7/7 [==============================] - 0s 2ms/step - loss: 0.6454 - accuracy: 0.5561 Epoch 12/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6416 - accuracy: 0.5561 Epoch 13/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6383 - accuracy: 0.5516 Epoch 14/250 7/7 [==============================] - 0s 2ms/step - loss: 0.6351 - accuracy: 0.5919 Epoch 15/250 7/7 [==============================] - 0s 2ms/step - loss: 0.6330 - accuracy: 0.6368 Epoch 16/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6303 - accuracy: 0.6502 Epoch 17/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6275 - accuracy: 0.6771 Epoch 18/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6262 - accuracy: 0.6726 Epoch 19/250 7/7 [==============================] - 0s 2ms/step - loss: 0.6249 - accuracy: 0.6592 Epoch 20/250 7/7 [==============================] - 0s 2ms/step - loss: 0.6232 - accuracy: 0.6816 Epoch 21/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6214 - accuracy: 0.6771 Epoch 22/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6206 - accuracy: 0.6682 Epoch 23/250 7/7 [==============================] - 0s 2ms/step - loss: 0.6190 - accuracy: 0.6726 Epoch 24/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6182 - accuracy: 0.6726 Epoch 25/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6167 - accuracy: 0.6682 Epoch 26/250 7/7 [==============================] - 0s 2ms/step - loss: 0.6164 - accuracy: 0.6771 Epoch 27/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6159 - accuracy: 0.6592 Epoch 28/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6138 - accuracy: 0.6637 Epoch 29/250 7/7 [==============================] - 0s 2ms/step - loss: 0.6127 - accuracy: 0.6592 Epoch 30/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6119 - accuracy: 0.6682 Epoch 31/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6103 - accuracy: 0.6726 Epoch 32/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6101 - accuracy: 0.6816 Epoch 33/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6082 - accuracy: 0.6726 Epoch 34/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6069 - accuracy: 0.6771 Epoch 35/250 7/7 [==============================] - 0s 2ms/step - loss: 0.6055 - accuracy: 0.6816 Epoch 36/250 7/7 [==============================] - 0s 2ms/step - loss: 0.6051 - accuracy: 0.6861 Epoch 37/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6036 - accuracy: 0.6861 Epoch 38/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6027 - accuracy: 0.6816 Epoch 39/250 7/7 [==============================] - 0s 2ms/step - loss: 0.6022 - accuracy: 0.6816 Epoch 40/250 7/7 [==============================] - 0s 1ms/step - loss: 0.6014 - accuracy: 0.6816 Epoch 41/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5998 - accuracy: 0.6861 Epoch 42/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5992 - accuracy: 0.6816 Epoch 43/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5980 - accuracy: 0.6861 Epoch 44/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5977 - accuracy: 0.6861 Epoch 45/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5966 - accuracy: 0.6906 Epoch 46/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5967 - accuracy: 0.6861 Epoch 47/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5951 - accuracy: 0.6816 Epoch 48/250 7/7 [==============================] - 0s 6ms/step - loss: 0.5938 - accuracy: 0.6771 Epoch 49/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5927 - accuracy: 0.6771 Epoch 50/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5919 - accuracy: 0.6861 Epoch 51/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5924 - accuracy: 0.6816 Epoch 52/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5903 - accuracy: 0.6771 Epoch 53/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5900 - accuracy: 0.6816 Epoch 54/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5895 - accuracy: 0.6816 Epoch 55/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5878 - accuracy: 0.6906 Epoch 56/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5878 - accuracy: 0.6816 Epoch 57/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5881 - accuracy: 0.6906 Epoch 58/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5854 - accuracy: 0.6816 Epoch 59/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5848 - accuracy: 0.6771 Epoch 60/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5844 - accuracy: 0.6861 Epoch 61/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5825 - accuracy: 0.6861 Epoch 62/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5820 - accuracy: 0.6816 Epoch 63/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5837 - accuracy: 0.6816 Epoch 64/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5818 - accuracy: 0.6861 Epoch 65/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5806 - accuracy: 0.6906 Epoch 66/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5800 - accuracy: 0.6861 Epoch 67/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5794 - accuracy: 0.6906 Epoch 68/250 7/7 [==============================] - 0s 3ms/step - loss: 0.5784 - accuracy: 0.6861 Epoch 69/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5789 - accuracy: 0.6771 Epoch 70/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5769 - accuracy: 0.6816 Epoch 71/250 7/7 [==============================] - 0s 3ms/step - loss: 0.5761 - accuracy: 0.6906 Epoch 72/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5760 - accuracy: 0.6906 Epoch 73/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5773 - accuracy: 0.6906 Epoch 74/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5762 - accuracy: 0.6726 Epoch 75/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5742 - accuracy: 0.6951 Epoch 76/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5727 - accuracy: 0.6951 Epoch 77/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5726 - accuracy: 0.6861 Epoch 78/250 7/7 [==============================] - 0s 3ms/step - loss: 0.5727 - accuracy: 0.6726 Epoch 79/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5728 - accuracy: 0.6951 Epoch 80/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5730 - accuracy: 0.6906 Epoch 81/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5706 - accuracy: 0.6771 Epoch 82/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5703 - accuracy: 0.6951 Epoch 83/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5696 - accuracy: 0.6906 Epoch 84/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5693 - accuracy: 0.6816 Epoch 85/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5677 - accuracy: 0.6906 Epoch 86/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5702 - accuracy: 0.6996 Epoch 87/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5673 - accuracy: 0.7040 Epoch 88/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5664 - accuracy: 0.6951 Epoch 89/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5679 - accuracy: 0.6951 Epoch 90/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5656 - accuracy: 0.6951 Epoch 91/250 7/7 [==============================] - 0s 5ms/step - loss: 0.5664 - accuracy: 0.6951 Epoch 92/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5664 - accuracy: 0.6816 Epoch 93/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5645 - accuracy: 0.6996 Epoch 94/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5646 - accuracy: 0.6996 Epoch 95/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5644 - accuracy: 0.6906 Epoch 96/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5642 - accuracy: 0.6906 Epoch 97/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5621 - accuracy: 0.6906 Epoch 98/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5634 - accuracy: 0.6951 Epoch 99/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5623 - accuracy: 0.6996 Epoch 100/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5616 - accuracy: 0.6996 Epoch 101/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5607 - accuracy: 0.6951 Epoch 102/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5606 - accuracy: 0.6951 Epoch 103/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5603 - accuracy: 0.6951 Epoch 104/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5594 - accuracy: 0.6996 Epoch 105/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5590 - accuracy: 0.6951 Epoch 106/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5603 - accuracy: 0.6906 Epoch 107/250 7/7 [==============================] - 0s 3ms/step - loss: 0.5582 - accuracy: 0.6951 Epoch 108/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5595 - accuracy: 0.6951 Epoch 109/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5593 - accuracy: 0.6906 Epoch 110/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5569 - accuracy: 0.6996 Epoch 111/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5602 - accuracy: 0.6996 Epoch 112/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5588 - accuracy: 0.6906 Epoch 113/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5573 - accuracy: 0.6951 Epoch 114/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5553 - accuracy: 0.6996 Epoch 115/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5563 - accuracy: 0.6906 Epoch 116/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5556 - accuracy: 0.6951 Epoch 117/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5558 - accuracy: 0.6996 Epoch 118/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5546 - accuracy: 0.6951 Epoch 119/250 7/7 [==============================] - 0s 7ms/step - loss: 0.5539 - accuracy: 0.6996 Epoch 120/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5586 - accuracy: 0.6951 Epoch 121/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5563 - accuracy: 0.6996 Epoch 122/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5536 - accuracy: 0.6996 Epoch 123/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5539 - accuracy: 0.6951 Epoch 124/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5539 - accuracy: 0.6951 Epoch 125/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5524 - accuracy: 0.6996 Epoch 126/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5523 - accuracy: 0.7040 Epoch 127/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5521 - accuracy: 0.6996 Epoch 128/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5560 - accuracy: 0.6906 Epoch 129/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5521 - accuracy: 0.6951 Epoch 130/250 7/7 [==============================] - 0s 3ms/step - loss: 0.5582 - accuracy: 0.6951 Epoch 131/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5535 - accuracy: 0.7085 Epoch 132/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5535 - accuracy: 0.6906 Epoch 133/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5521 - accuracy: 0.7040 Epoch 134/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5500 - accuracy: 0.7085 Epoch 135/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5489 - accuracy: 0.6996 Epoch 136/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5491 - accuracy: 0.6996 Epoch 137/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5497 - accuracy: 0.7040 Epoch 138/250 7/7 [==============================] - 0s 3ms/step - loss: 0.5479 - accuracy: 0.6951 Epoch 139/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5522 - accuracy: 0.7040 Epoch 140/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5480 - accuracy: 0.6951 Epoch 141/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5484 - accuracy: 0.6906 Epoch 142/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5467 - accuracy: 0.7040 Epoch 143/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5458 - accuracy: 0.6996 Epoch 144/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5461 - accuracy: 0.7085 Epoch 145/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5451 - accuracy: 0.7040 Epoch 146/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5463 - accuracy: 0.6951 Epoch 147/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5465 - accuracy: 0.6996 Epoch 148/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5471 - accuracy: 0.6951 Epoch 149/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5441 - accuracy: 0.7040 Epoch 150/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5447 - accuracy: 0.6996 Epoch 151/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5437 - accuracy: 0.6951 Epoch 152/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5430 - accuracy: 0.7040 Epoch 153/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5430 - accuracy: 0.6996 Epoch 154/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5433 - accuracy: 0.7040 Epoch 155/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5457 - accuracy: 0.6951 Epoch 156/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5419 - accuracy: 0.6996 Epoch 157/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5410 - accuracy: 0.6996 Epoch 158/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5424 - accuracy: 0.6996 Epoch 159/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5405 - accuracy: 0.6996 Epoch 160/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5420 - accuracy: 0.6996 Epoch 161/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5403 - accuracy: 0.7040 Epoch 162/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5420 - accuracy: 0.7040 Epoch 163/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5400 - accuracy: 0.6996 Epoch 164/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5402 - accuracy: 0.6996 Epoch 165/250 7/7 [==============================] - 0s 7ms/step - loss: 0.5392 - accuracy: 0.7040 Epoch 166/250 7/7 [==============================] - 0s 3ms/step - loss: 0.5383 - accuracy: 0.7040 Epoch 167/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5407 - accuracy: 0.6996 Epoch 168/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5399 - accuracy: 0.6996 Epoch 169/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5378 - accuracy: 0.6996 Epoch 170/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5429 - accuracy: 0.6951 Epoch 171/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5371 - accuracy: 0.6996 Epoch 172/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5412 - accuracy: 0.7040 Epoch 173/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5403 - accuracy: 0.6996 Epoch 174/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5384 - accuracy: 0.7085 Epoch 175/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5375 - accuracy: 0.6996 Epoch 176/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5390 - accuracy: 0.6996 Epoch 177/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5371 - accuracy: 0.7040 Epoch 178/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5365 - accuracy: 0.7085 Epoch 179/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5341 - accuracy: 0.6996 Epoch 180/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5339 - accuracy: 0.7085 Epoch 181/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5345 - accuracy: 0.7085 Epoch 182/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5340 - accuracy: 0.6996 Epoch 183/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5338 - accuracy: 0.7085 Epoch 184/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5344 - accuracy: 0.7130 Epoch 185/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5323 - accuracy: 0.7040 Epoch 186/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5335 - accuracy: 0.7040 Epoch 187/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5329 - accuracy: 0.7040 Epoch 188/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5317 - accuracy: 0.7040 Epoch 189/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5309 - accuracy: 0.7040 Epoch 190/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5312 - accuracy: 0.7130 Epoch 191/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5297 - accuracy: 0.7085 Epoch 192/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5434 - accuracy: 0.6906 Epoch 193/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5351 - accuracy: 0.7220 Epoch 194/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5352 - accuracy: 0.7130 Epoch 195/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5300 - accuracy: 0.7040 Epoch 196/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5301 - accuracy: 0.7085 Epoch 197/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5288 - accuracy: 0.7130 Epoch 198/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5309 - accuracy: 0.7085 Epoch 199/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5329 - accuracy: 0.7040 Epoch 200/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5289 - accuracy: 0.7175 Epoch 201/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5306 - accuracy: 0.7130 Epoch 202/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5285 - accuracy: 0.7130 Epoch 203/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5285 - accuracy: 0.7175 Epoch 204/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5302 - accuracy: 0.7175 Epoch 205/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5253 - accuracy: 0.7085 Epoch 206/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5283 - accuracy: 0.7175 Epoch 207/250 7/7 [==============================] - 0s 3ms/step - loss: 0.5265 - accuracy: 0.7220 Epoch 208/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5279 - accuracy: 0.7175 Epoch 209/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5293 - accuracy: 0.7130 Epoch 210/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5273 - accuracy: 0.7175 Epoch 211/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5259 - accuracy: 0.7130 Epoch 212/250 7/7 [==============================] - 0s 8ms/step - loss: 0.5260 - accuracy: 0.7175 Epoch 213/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5232 - accuracy: 0.7220 Epoch 214/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5235 - accuracy: 0.7130 Epoch 215/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5220 - accuracy: 0.7130 Epoch 216/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5216 - accuracy: 0.7085 Epoch 217/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5231 - accuracy: 0.7130 Epoch 218/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5244 - accuracy: 0.7130 Epoch 219/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5222 - accuracy: 0.7085 Epoch 220/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5197 - accuracy: 0.7130 Epoch 221/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5198 - accuracy: 0.7175 Epoch 222/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5199 - accuracy: 0.7130 Epoch 223/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5191 - accuracy: 0.7130 Epoch 224/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5181 - accuracy: 0.7175 Epoch 225/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5191 - accuracy: 0.7220 Epoch 226/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5186 - accuracy: 0.7309 Epoch 227/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5196 - accuracy: 0.7309 Epoch 228/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5208 - accuracy: 0.7085 Epoch 229/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5169 - accuracy: 0.7220 Epoch 230/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5179 - accuracy: 0.7220 Epoch 231/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5168 - accuracy: 0.7220 Epoch 232/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5157 - accuracy: 0.7354 Epoch 233/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5149 - accuracy: 0.7309 Epoch 234/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5158 - accuracy: 0.7309 Epoch 235/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5143 - accuracy: 0.7444 Epoch 236/250 7/7 [==============================] - 0s 7ms/step - loss: 0.5188 - accuracy: 0.7265 Epoch 237/250 7/7 [==============================] - 0s 3ms/step - loss: 0.5144 - accuracy: 0.7399 Epoch 238/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5142 - accuracy: 0.7354 Epoch 239/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5154 - accuracy: 0.7399 Epoch 240/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5136 - accuracy: 0.7220 Epoch 241/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5148 - accuracy: 0.7354 Epoch 242/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5123 - accuracy: 0.7354 Epoch 243/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5125 - accuracy: 0.7309 Epoch 244/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5116 - accuracy: 0.7265 Epoch 245/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5112 - accuracy: 0.7354 Epoch 246/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5116 - accuracy: 0.7220 Epoch 247/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5117 - accuracy: 0.7220 Epoch 248/250 7/7 [==============================] - 0s 2ms/step - loss: 0.5118 - accuracy: 0.7399 Epoch 249/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5132 - accuracy: 0.7444 Epoch 250/250 7/7 [==============================] - 0s 1ms/step - loss: 0.5092 - accuracy: 0.7354
<keras.callbacks.History at 0x290a4944cd0>
The model evaluation output shows the performance of the model on both training and test data. The accuracy was approximately 75% on the training data and 74% on the test data. It's noteworthy that the training and test set accuracies are close to each other, which shows that there is consistency, and that the accuracy doesn't drop too much when I test the model on unseen data.
model.evaluate(X_train, y_train)
7/7 [==============================] - 0s 2ms/step - loss: 0.5101 - accuracy: 0.7354
[0.5101242661476135, 0.7354260087013245]
model.evaluate(X_test, y_test)
3/3 [==============================] - 0s 1ms/step - loss: 0.6855 - accuracy: 0.7083
[0.6855059266090393, 0.7083333134651184]
I have built a deep learning classification model using the deep learning framework, Keras, in TensorFlow. I used a IPO dataset and built a classifier algorithm to predict whether an IPO will list at profit or not. I used the Sequential API to build the model, which is achieving a decent accuracy of 75% and 74% on training and test data, respectively. I see that the accuracy is consistent across the training and test datasets, which is a promising sign. This model can be useful to make investment decisions in the IPO market.
input_layer = tf.keras.Input(shape=(X_train.shape[1],))
hidden_layer1 = tf.keras.layers.Dense(128, activation='relu')(input_layer)
drop1 = tf.keras.layers.Dropout(rate=0.40)(hidden_layer1)
hidden_layer2 = tf.keras.layers.Dense(64, activation='relu')(drop1)
drop2 =tf.keras.layers.Dropout(rate=0.20)(hidden_layer2)
hidden_layer3 = tf.keras.layers.Dense(16, activation='relu')(drop2)
hidden_layer4 = tf.keras.layers.Dense(8, activation='relu')(hidden_layer3)
hidden_layer5 = tf.keras.layers.Dense(4, activation='relu')(hidden_layer4)
output_layer = tf.keras.layers.Dense(1, activation='sigmoid')(hidden_layer5)
model = tf.keras.Model(inputs=input_layer, outputs=output_layer)
print(model.summary())
optimizer = tf.keras.optimizers.Adam(0.001)
loss = tf.keras.losses.BinaryCrossentropy()
metrics = ['accuracy']
model.compile(optimizer=optimizer, loss=loss, metrics=metrics)
model.fit(X_train, y_train, epochs=250, verbose=0)
print(model.evaluate(X_train, y_train))
print(model.evaluate(X_test, y_test))
Model: "model_2" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_3 (InputLayer) [(None, 6)] 0 dense_17 (Dense) (None, 128) 896 dropout_4 (Dropout) (None, 128) 0 dense_18 (Dense) (None, 64) 8256 dropout_5 (Dropout) (None, 64) 0 dense_19 (Dense) (None, 16) 1040 dense_20 (Dense) (None, 8) 136 dense_21 (Dense) (None, 4) 36 dense_22 (Dense) (None, 1) 5 ================================================================= Total params: 10,369 Trainable params: 10,369 Non-trainable params: 0 _________________________________________________________________ None 7/7 [==============================] - 0s 2ms/step - loss: 0.4684 - accuracy: 0.7668 [0.4683583080768585, 0.7668161392211914] 3/3 [==============================] - 0s 3ms/step - loss: 0.6766 - accuracy: 0.6875 [0.6766266822814941, 0.6875]