filepath = "loan.csv"Main Aim:
Determine patters that will allow us to understand somehow factors that contribute to a loan being defaulted
Lending Club is a peer to peer lending company based in the United States, in which investors provide funds for potential borrowers and investors earn a profit depending on the risk they take (the borrowers credit score). Lending Club provides the “bridge” between investors and borrowers.
filepath = "loan.csv"pip install seaborn scikit-learn imbalanced-learn chart-studio plotly tensorflow
# Import libraries we are going to use for our data analysis.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style("white")
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import roc_curve, auc, classification_report, confusion_matrix, precision_recall_curve
# Plotly visualizations (using chart-studio)
from plotly import tools
from chart_studio import plotly as py
import plotly.figure_factory as ff
import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
init_notebook_mode(connected=True)
# For oversampling Library (Dealing with Imbalanced Datasets)
from imblearn.over_sampling import SMOTE
from collections import Counter
# Other Libraries
import time
import tensorflow as tf
%matplotlib inline
sns.set_style('whitegrid')/Users/rishigovind/Library/Python/3.9/lib/python/site-packages/urllib3/__init__.py:35: NotOpenSSLWarning:
urllib3 v2 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'LibreSSL 2.8.3'. See: https://github.com/urllib3/urllib3/issues/3020
df = pd.read_csv(filepath, low_memory=False)
# Copy of the dataframe
original_df = df.copy()
df.head()| id | member_id | loan_amnt | funded_amnt | funded_amnt_inv | term | int_rate | installment | grade | sub_grade | ... | total_bal_il | il_util | open_rv_12m | open_rv_24m | max_bal_bc | all_util | total_rev_hi_lim | inq_fi | total_cu_tl | inq_last_12m | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1077501 | 1296599 | 5000.0 | 5000.0 | 4975.0 | 36 months | 10.65 | 162.87 | B | B2 | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 1 | 1077430 | 1314167 | 2500.0 | 2500.0 | 2500.0 | 60 months | 15.27 | 59.83 | C | C4 | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 2 | 1077175 | 1313524 | 2400.0 | 2400.0 | 2400.0 | 36 months | 15.96 | 84.33 | C | C5 | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 3 | 1076863 | 1277178 | 10000.0 | 10000.0 | 10000.0 | 36 months | 13.49 | 339.31 | C | C1 | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 4 | 1075358 | 1311748 | 3000.0 | 3000.0 | 3000.0 | 60 months | 12.69 | 67.79 | B | B5 | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
5 rows × 74 columns
df.info()<class 'pandas.core.frame.DataFrame'>
RangeIndex: 887379 entries, 0 to 887378
Data columns (total 74 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 id 887379 non-null int64
1 member_id 887379 non-null int64
2 loan_amnt 887379 non-null float64
3 funded_amnt 887379 non-null float64
4 funded_amnt_inv 887379 non-null float64
5 term 887379 non-null object
6 int_rate 887379 non-null float64
7 installment 887379 non-null float64
8 grade 887379 non-null object
9 sub_grade 887379 non-null object
10 emp_title 835917 non-null object
11 emp_length 842554 non-null object
12 home_ownership 887379 non-null object
13 annual_inc 887375 non-null float64
14 verification_status 887379 non-null object
15 issue_d 887379 non-null object
16 loan_status 887379 non-null object
17 pymnt_plan 887379 non-null object
18 url 887379 non-null object
19 desc 126026 non-null object
20 purpose 887379 non-null object
21 title 887226 non-null object
22 zip_code 887379 non-null object
23 addr_state 887379 non-null object
24 dti 887379 non-null float64
25 delinq_2yrs 887350 non-null float64
26 earliest_cr_line 887350 non-null object
27 inq_last_6mths 887350 non-null float64
28 mths_since_last_delinq 433067 non-null float64
29 mths_since_last_record 137053 non-null float64
30 open_acc 887350 non-null float64
31 pub_rec 887350 non-null float64
32 revol_bal 887379 non-null float64
33 revol_util 886877 non-null float64
34 total_acc 887350 non-null float64
35 initial_list_status 887379 non-null object
36 out_prncp 887379 non-null float64
37 out_prncp_inv 887379 non-null float64
38 total_pymnt 887379 non-null float64
39 total_pymnt_inv 887379 non-null float64
40 total_rec_prncp 887379 non-null float64
41 total_rec_int 887379 non-null float64
42 total_rec_late_fee 887379 non-null float64
43 recoveries 887379 non-null float64
44 collection_recovery_fee 887379 non-null float64
45 last_pymnt_d 869720 non-null object
46 last_pymnt_amnt 887379 non-null float64
47 next_pymnt_d 634408 non-null object
48 last_credit_pull_d 887326 non-null object
49 collections_12_mths_ex_med 887234 non-null float64
50 mths_since_last_major_derog 221703 non-null float64
51 policy_code 887379 non-null float64
52 application_type 887379 non-null object
53 annual_inc_joint 511 non-null float64
54 dti_joint 509 non-null float64
55 verification_status_joint 511 non-null object
56 acc_now_delinq 887350 non-null float64
57 tot_coll_amt 817103 non-null float64
58 tot_cur_bal 817103 non-null float64
59 open_acc_6m 21372 non-null float64
60 open_il_6m 21372 non-null float64
61 open_il_12m 21372 non-null float64
62 open_il_24m 21372 non-null float64
63 mths_since_rcnt_il 20810 non-null float64
64 total_bal_il 21372 non-null float64
65 il_util 18617 non-null float64
66 open_rv_12m 21372 non-null float64
67 open_rv_24m 21372 non-null float64
68 max_bal_bc 21372 non-null float64
69 all_util 21372 non-null float64
70 total_rev_hi_lim 817103 non-null float64
71 inq_fi 21372 non-null float64
72 total_cu_tl 21372 non-null float64
73 inq_last_12m 21372 non-null float64
dtypes: float64(49), int64(2), object(23)
memory usage: 501.0+ MB
# Replace the name of some columns
df = df.rename(columns={"loan_amnt": "loan_amount", "funded_amnt": "funded_amount", "funded_amnt_inv": "investor_funds",
"int_rate": "interest_rate", "annual_inc": "annual_income"})
# Drop irrelevant columns
df.drop(['id', 'member_id', 'emp_title', 'url', 'desc', 'zip_code', 'title'], axis=1, inplace=True)We will start by exploring the distribution of the loan amounts and see when did the loan amount issued increased significantly.
fig, ax = plt.subplots(1, 3, figsize=(16,5))
# Loan applied by the borrower
sns.histplot(
df["loan_amount"],
ax=ax[0],
kde=True,
color="#F7522F"
)
ax[0].set_title("Loan Applied by the Borrower", fontsize=14)
# Amount funded by the lender
sns.histplot(
df["funded_amount"],
ax=ax[1],
kde=True,
color="#2F8FF7"
)
ax[1].set_title("Amount Funded by the Lender", fontsize=14)
# Total committed by investors
sns.histplot(
df["investor_funds"],
ax=ax[2],
kde=True,
color="#2EAD46"
)
ax[2].set_title("Total Committed by Investors", fontsize=14)
for a in ax:
a.grid(False)
plt.tight_layout()
plt.show()
# strip any stray whitespace
df['issue_d_clean'] = df['issue_d'].str.strip()
# try parsing as abbreviated‐month + 2-digit year
dt1 = pd.to_datetime(df['issue_d_clean'],
format='%b-%y',
errors='coerce')
# try parsing as abbreviated‐month + 4-digit year
dt2 = pd.to_datetime(df['issue_d_clean'],
format='%b-%Y',
errors='coerce')
# combine: prefer dt1, fall back to dt2
dt = dt1.fillna(dt2)
# if you still get NaT for some rows, you can inspect them:
missing = df.loc[dt.isna(), 'issue_d_clean'].unique()
print("Unparsed patterns:", missing)
# finally extract the year
df['year'] = dt.dt.yearUnparsed patterns: []
# The year of 2015 was the year were the highest amount of loans were issued
# This is an indication that the economy is quiet recovering itself.
fig, ax = plt.subplots(figsize=(12,8))
sns.barplot(x='year', y='loan_amount', data=df, palette='tab10', ax=ax)
# Turn off grid lines
ax.grid(False)
# (Optional) Tidy up spines for a cleaner look
sns.despine(fig=fig, trim=True)
plt.title('Issuance of Loans', fontsize=16)
plt.xlabel('Year', fontsize=14)
plt.ylabel('Average loan amount issued', fontsize=14)
plt.tight_layout()
plt.show()/var/folders/nm/h5zmyl7d0bb9ww_617yygd5c0000gn/T/ipykernel_79479/1520398887.py:4: FutureWarning:
Passing `palette` without assigning `hue` is deprecated and will be removed in v0.14.0. Assign the `x` variable to `hue` and set `legend=False` for the same effect.

In this section, we will see what is the amount of bad loans Lending Club has declared so far, of course we have to understand that there are still loans that are at a risk of defaulting in the future.
The amount of bad loans could increment as the days pass by, since we still have a great amount of current loans.
Average annual income is an important key metric for finding possible opportunities of investments in a specific region.
df["loan_status"].value_counts()loan_status
Current 601779
Fully Paid 207723
Charged Off 45248
Late (31-120 days) 11591
Issued 8460
In Grace Period 6253
Late (16-30 days) 2357
Does not meet the credit policy. Status:Fully Paid 1988
Default 1219
Does not meet the credit policy. Status:Charged Off 761
Name: count, dtype: int64
# Determining the loans that are bad from loan_status column
bad_loan = ["Charged Off", "Default", "Does not meet the credit policy. Status:Charged Off", "In Grace Period",
"Late (16-30 days)", "Late (31-120 days)"]
df['loan_condition'] = np.nan
def loan_condition(status):
if status in bad_loan:
return 'Bad Loan'
else:
return 'Good Loan'
df['loan_condition'] = df['loan_status'].apply(loan_condition)f, ax = plt.subplots(1,2, figsize=(16,8))
colors = ["#3791D7", "#D72626"]
labels ="Good Loans", "Bad Loans"
plt.suptitle('Information on Loan Conditions', fontsize=20)
df["loan_condition"].value_counts().plot.pie(explode=[0,0.25], autopct='%1.2f%%', ax=ax[0], shadow=True, colors=colors,
labels=labels, fontsize=12, startangle=70)
# ax[0].set_title('State of Loan', fontsize=16)
ax[0].set_ylabel('% of Condition of Loans', fontsize=14)
# sns.countplot('loan_condition', data=df, ax=ax[1], palette=colors)
# ax[1].set_title('Condition of Loans', fontsize=20)
# ax[1].set_xticklabels(['Good', 'Bad'], rotation='horizontal')
palette = ["#3791D7", "#E01E1B"]
sns.barplot(x="year", y="loan_amount", hue="loan_condition", data=df, palette=palette, estimator=lambda x: len(x) / len(df) * 100)
ax[1].set(ylabel="(%)")
In this section we want to analyse loans issued by region in order to see region patters that will allow us to understand which region gives Lending Club.
df['addr_state'].unique()
# Make a list with each of the regions by state.
west = ['CA', 'OR', 'UT','WA', 'CO', 'NV', 'AK', 'MT', 'HI', 'WY', 'ID']
south_west = ['AZ', 'TX', 'NM', 'OK']
south_east = ['GA', 'NC', 'VA', 'FL', 'KY', 'SC', 'LA', 'AL', 'WV', 'DC', 'AR', 'DE', 'MS', 'TN' ]
mid_west = ['IL', 'MO', 'MN', 'OH', 'WI', 'KS', 'MI', 'SD', 'IA', 'NE', 'IN', 'ND']
north_east = ['CT', 'NY', 'PA', 'NJ', 'RI','MA', 'MD', 'VT', 'NH', 'ME']
df['region'] = np.nan
def finding_regions(state):
if state in west:
return 'West'
elif state in south_west:
return 'SouthWest'
elif state in south_east:
return 'SouthEast'
elif state in mid_west:
return 'MidWest'
elif state in north_east:
return 'NorthEast'
df['region'] = df['addr_state'].apply(finding_regions)# This code will take the current date and transform it into a year-month format
df['issue_period'] = (
pd.to_datetime(df['issue_d'].str.strip(),
format='%b-%Y', # e.g. "Dec-2011"
errors='coerce') # (should be none, but just in case)
.dt.to_period('M')
)good = df.dropna(subset=['issue_period'])
# Sum loan_amount (in thousands) per month & region
df_dates = (
good
.groupby(['issue_period','region'], as_index=False)['loan_amount']
.sum()
)
df_dates['loan_amount'] /= 1_000
# Rename for clarity (and plotting)
df_dates.rename(columns={'issue_period':'year_month'}, inplace=True)
print(df_dates.head()) year_month region loan_amount
0 2007-06 MidWest 6.90
1 2007-06 NorthEast 67.70
2 2007-06 SouthEast 13.45
3 2007-06 SouthWest 1.20
4 2007-06 West 2.60
pivot = df_dates.pivot_table(
index='year_month',
columns='region',
values='loan_amount',
aggfunc='sum'
).fillna(0)
# convert PeriodIndex to string for nice ticks
pivot.index = pivot.index.astype(str)
plt.style.use('dark_background')
ax = pivot.plot(
figsize=(15,6),
colormap=plt.cm.Set3,
grid=False # ⟵ turns grid off
)
ax.set_title('Loans issued by Region', fontsize=16)
ax.set_xlabel('Year-Month', fontsize=14)
ax.set_ylabel('Loan Amount (thousands)', fontsize=14)
plt.tight_layout()
plt.show()
employment_length = ['10+ years', '< 1 year', '1 year', '3 years', '8 years', '9 years',
'4 years', '5 years', '6 years', '2 years', '7 years', 'n/a']
# Create a new column and convert emp_length to integers.
lst = [df]
df['emp_length_int'] = np.nan
for col in lst:
col.loc[col['emp_length'] == '10+ years', "emp_length_int"] = 10
col.loc[col['emp_length'] == '9 years', "emp_length_int"] = 9
col.loc[col['emp_length'] == '8 years', "emp_length_int"] = 8
col.loc[col['emp_length'] == '7 years', "emp_length_int"] = 7
col.loc[col['emp_length'] == '6 years', "emp_length_int"] = 6
col.loc[col['emp_length'] == '5 years', "emp_length_int"] = 5
col.loc[col['emp_length'] == '4 years', "emp_length_int"] = 4
col.loc[col['emp_length'] == '3 years', "emp_length_int"] = 3
col.loc[col['emp_length'] == '2 years', "emp_length_int"] = 2
col.loc[col['emp_length'] == '1 year', "emp_length_int"] = 1
col.loc[col['emp_length'] == '< 1 year', "emp_length_int"] = 0.5
col.loc[col['emp_length'] == 'n/a', "emp_length_int"] = 0# Loan issued by Region and by Credit Score grade
sns.set_style('whitegrid')
f, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)
cmap = plt.cm.inferno
by_interest_rate = df.groupby(['year', 'region']).interest_rate.mean()
by_interest_rate.unstack().plot(kind='area', stacked=True, colormap=cmap, grid=False, legend=False, ax=ax1, figsize=(16,12))
ax1.set_title('Average Interest Rate by Region', fontsize=14)
by_employment_length = df.groupby(['year', 'region']).emp_length_int.mean()
by_employment_length.unstack().plot(kind='area', stacked=True, colormap=cmap, grid=False, legend=False, ax=ax2, figsize=(16,12))
ax2.set_title('Average Employment Length by Region', fontsize=14)
# plt.xlabel('Year of Issuance', fontsize=14)
by_dti = df.groupby(['year', 'region']).dti.mean()
by_dti.unstack().plot(kind='area', stacked=True, colormap=cmap, grid=False, legend=False, ax=ax3, figsize=(16,12))
ax3.set_title('Average Debt-to-Income by Region', fontsize=14)
by_income = df.groupby(['year', 'region']).annual_income.mean()
by_income.unstack().plot(kind='area', stacked=True, colormap=cmap, grid=False, ax=ax4, figsize=(16,12))
ax4.set_title('Average Annual Income by Region', fontsize=14)
ax4.legend(bbox_to_anchor=(-1.0, -0.5, 1.8, 0.1), loc=10,prop={'size':12},
ncol=5, mode="expand", borderaxespad=0.)
# We have 67429 loans categorized as bad loans
badloans_df = df.loc[df["loan_condition"] == "Bad Loan"]
# loan_status cross
loan_status_cross = pd.crosstab(badloans_df['region'], badloans_df['loan_status']).apply(lambda x: x/x.sum() * 100)
number_of_loanstatus = pd.crosstab(badloans_df['region'], badloans_df['loan_status'])
# Round our values
loan_status_cross['Charged Off'] = loan_status_cross['Charged Off'].apply(lambda x: round(x, 2))
loan_status_cross['Default'] = loan_status_cross['Default'].apply(lambda x: round(x, 2))
loan_status_cross['Does not meet the credit policy. Status:Charged Off'] = loan_status_cross['Does not meet the credit policy. Status:Charged Off'].apply(lambda x: round(x, 2))
loan_status_cross['In Grace Period'] = loan_status_cross['In Grace Period'].apply(lambda x: round(x, 2))
loan_status_cross['Late (16-30 days)'] = loan_status_cross['Late (16-30 days)'].apply(lambda x: round(x, 2))
loan_status_cross['Late (31-120 days)'] = loan_status_cross['Late (31-120 days)'].apply(lambda x: round(x, 2))
number_of_loanstatus['Total'] = number_of_loanstatus.sum(axis=1)
# number_of_badloans
number_of_loanstatus| loan_status | Charged Off | Default | Does not meet the credit policy. Status:Charged Off | In Grace Period | Late (16-30 days) | Late (31-120 days) | Total |
|---|---|---|---|---|---|---|---|
| region | |||||||
| MidWest | 7361 | 175 | 142 | 926 | 354 | 1820 | 10778 |
| NorthEast | 10671 | 263 | 190 | 1625 | 585 | 2799 | 16133 |
| SouthEast | 11094 | 297 | 184 | 1579 | 600 | 2925 | 16679 |
| SouthWest | 4774 | 166 | 79 | 708 | 273 | 1407 | 7407 |
| West | 11348 | 318 | 166 | 1415 | 545 | 2640 | 16432 |
# Average interest rates clients pay
df['interest_rate'].mean()
# Average annual income of clients
df['annual_income'].mean()np.float64(75027.5877607663)
Now we will have a closer look at the operative side of business by state. This will give us a clearer idea in which state we have a higher operating activity. This will allow us to ask further questions such as Why do we have a higher level of operating activity in this state? Could it be because of economic factors? or the risk level is low and returns are fairly decent? Let’s explore!
# Plotting by states
# Grouping by our metrics
# First Plotly Graph (We evaluate the operative side of the business)
by_loan_amount = df.groupby(['region','addr_state'], as_index=False).loan_amount.sum()
by_interest_rate = df.groupby(['region', 'addr_state'], as_index=False).interest_rate.mean()
by_income = df.groupby(['region', 'addr_state'], as_index=False).annual_income.mean()
# Take the values to a list for visualization purposes.
states = by_loan_amount['addr_state'].values.tolist()
average_loan_amounts = by_loan_amount['loan_amount'].values.tolist()
average_interest_rates = by_interest_rate['interest_rate'].values.tolist()
average_annual_income = by_income['annual_income'].values.tolist()
from collections import OrderedDict
# Figure Number 1 (Perspective for the Business Operations)
metrics_data = OrderedDict([('state_codes', states),
('issued_loans', average_loan_amounts),
('interest_rate', average_interest_rates),
('annual_income', average_annual_income)])
metrics_df = pd.DataFrame.from_dict(metrics_data)
metrics_df = metrics_df.round(decimals=2)
metrics_df.head()| state_codes | issued_loans | interest_rate | annual_income | |
|---|---|---|---|---|
| 0 | IA | 114075.0 | 12.63 | 44756.21 |
| 1 | IL | 539068450.0 | 13.10 | 76898.22 |
| 2 | IN | 202493900.0 | 13.46 | 67989.31 |
| 3 | KS | 116395875.0 | 13.28 | 68841.31 |
| 4 | MI | 326467800.0 | 13.30 | 69378.67 |
# Now it comes the part where we plot out plotly United States map
import plotly.graph_objs as go
for col in metrics_df.columns:
metrics_df[col] = metrics_df[col].astype(str)
scl = [[0.0, 'rgb(210, 241, 198)'],[0.2, 'rgb(188, 236, 169)'],[0.4, 'rgb(171, 235, 145)'],\
[0.6, 'rgb(140, 227, 105)'],[0.8, 'rgb(105, 201, 67)'],[1.0, 'rgb(59, 159, 19)']]
metrics_df['text'] = metrics_df['state_codes'] + '<br>' +\
'Average loan interest rate: ' + metrics_df['interest_rate'] + '<br>'+\
'Average annual income: ' + metrics_df['annual_income']
data = [ dict(
type='choropleth',
colorscale = scl,
autocolorscale = False,
locations = metrics_df['state_codes'],
z = metrics_df['issued_loans'],
locationmode = 'USA-states',
text = metrics_df['text'],
marker = dict(
line = dict (
color = 'rgb(255,255,255)',
width = 2
) ),
colorbar = dict(
title = "$s USD")
) ]
layout = dict(
title = 'Lending Clubs Issued Loans <br> (A Perspective for the Business Operations)',
geo = dict(
scope = 'usa',
projection=dict(type='albers usa'),
showlakes = True,
lakecolor = 'rgb(255, 255, 255)')
)
fig = dict(data=data, layout=layout)
iplot(fig, filename='d3-cloropleth-map')In this section we will create different income categories in order to detect important patters and go more into depth in our analysis.
# Let's create categories for annual_income since most of the bad loans are located below 100k
df['income_category'] = "" # empty string defaults the dtype to object
for col in [df]:
col.loc[col['annual_income'] <= 100_000, 'income_category'] = 'Low'
col.loc[(col['annual_income'] > 100_000) & (col['annual_income'] <= 200_000), 'income_category'] = 'Medium'
col.loc[col['annual_income'] > 200_000, 'income_category'] = 'High'
# define your bins and labels
bins = [-np.inf, 100_000, 200_000, np.inf]
labels = ['Low', 'Medium', 'High']
# this creates a Categorical column directly
df['income_category'] = pd.cut(df['annual_income'], bins=bins, labels=labels)# Let's transform the column loan_condition into integrers.
lst = [df]
df['loan_condition_int'] = np.nan
for col in lst:
col.loc[df['loan_condition'] == 'Good Loan', 'loan_condition_int'] = 0 # Negative (Bad Loan)
col.loc[df['loan_condition'] == 'Bad Loan', 'loan_condition_int'] = 1 # Positive (Good Loan)
# Convert from float to int the column (This is our label)
df['loan_condition_int'] = df['loan_condition_int'].astype(int)fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2, figsize=(14,6))
# Violin of loan_amount by income_category
sns.violinplot(
x="income_category",
y="loan_amount",
hue="income_category",
data=df,
palette="Set2",
legend=False,
ax=ax1
)
ax1.set_title("Loan Amount by Income Category")
# Violin of loan_condition_int by income_category
sns.violinplot(
x="income_category",
y="loan_condition_int",
hue="income_category",
data=df,
palette="Set2",
legend=False,
ax=ax2
)
ax2.set_title("Loan Condition by Income Category")
# Boxplot of emp_length_int by income_category
sns.boxplot(
x="income_category",
y="emp_length_int",
hue="income_category",
data=df,
palette="Set2",
legend=False,
ax=ax3
)
ax3.set_title("Employment Length by Income Category")
# Boxplot of interest_rate by income_category
sns.boxplot(
x="income_category",
y="interest_rate",
hue="income_category",
data=df,
palette="Set2",
legend=False,
ax=ax4
)
ax4.set_title("Interest Rate by Income Category")
# clean up
for ax in (ax1, ax2, ax3, ax4):
ax.set_xlabel("") # to remove repeated x-label
ax.set_ylabel("") # likewise for y-labels
ax.tick_params(axis='x', rotation=45)
plt.tight_layout()
plt.show()
Although the operative side of business is important, we have to also analyze the level of risk in each state. Credit scores are important metrics to analyze the level of risk of an individual customer. However, there are also other important metrics to somehow estimate the level of risk of other states.
by_condition = df.groupby('addr_state')['loan_condition'].value_counts()/ df.groupby('addr_state')['loan_condition'].count()
by_emp_length = df.groupby(['region', 'addr_state'], as_index=False).emp_length_int.mean().sort_values(by="addr_state")
loan_condition_bystate = pd.crosstab(df['addr_state'], df['loan_condition'] )
cross_condition = pd.crosstab(df["addr_state"], df["loan_condition"])
# Percentage of condition of loan
percentage_loan_contributor = pd.crosstab(df['addr_state'], df['loan_condition']).apply(lambda x: x/x.sum() * 100)
condition_ratio = cross_condition["Bad Loan"]/cross_condition["Good Loan"]
by_dti = df.groupby(['region', 'addr_state'], as_index=False).dti.mean()
state_codes = sorted(states)
# Take to a list
default_ratio = condition_ratio.values.tolist()
average_dti = by_dti['dti'].values.tolist()
average_emp_length = by_emp_length["emp_length_int"].values.tolist()
number_of_badloans = loan_condition_bystate['Bad Loan'].values.tolist()
percentage_ofall_badloans = percentage_loan_contributor['Bad Loan'].values.tolist()
# Figure Number 2
risk_data = OrderedDict([('state_codes', state_codes),
('default_ratio', default_ratio),
('badloans_amount', number_of_badloans),
('percentage_of_badloans', percentage_ofall_badloans),
('average_dti', average_dti),
('average_emp_length', average_emp_length)])
# Figure 2 Dataframe
risk_df = pd.DataFrame.from_dict(risk_data)
risk_df = risk_df.round(decimals=3)
risk_df.head()| state_codes | default_ratio | badloans_amount | percentage_of_badloans | average_dti | average_emp_length | |
|---|---|---|---|---|---|---|
| 0 | AK | 0.074 | 151 | 0.224 | 13.656 | 6.256 |
| 1 | AL | 0.097 | 993 | 1.473 | 17.821 | 6.607 |
| 2 | AR | 0.083 | 507 | 0.752 | 19.681 | 6.404 |
| 3 | AZ | 0.084 | 1581 | 2.345 | 19.284 | 5.793 |
| 4 | CA | 0.088 | 10518 | 15.599 | 18.683 | 5.967 |
for col in risk_df.columns:
risk_df[col] = risk_df[col].astype(str)
scl = [[0.0, 'rgb(202, 202, 202)'],[0.2, 'rgb(253, 205, 200)'],[0.4, 'rgb(252, 169, 161)'],\
[0.6, 'rgb(247, 121, 108 )'],[0.8, 'rgb(232, 70, 54)'],[1.0, 'rgb(212, 31, 13)']]
risk_df['text'] = risk_df['state_codes'] + '<br>' +\
'Number of Bad Loans: ' + risk_df['badloans_amount'] + '<br>' + \
'Percentage of all Bad Loans: ' + risk_df['percentage_of_badloans'] + '%' + '<br>' + \
'Average Debt-to-Income Ratio: ' + risk_df['average_dti'] + '<br>'+\
'Average Length of Employment: ' + risk_df['average_emp_length']
data = [ dict(
type='choropleth',
colorscale = scl,
autocolorscale = False,
locations = risk_df['state_codes'],
z = risk_df['default_ratio'],
locationmode = 'USA-states',
text = risk_df['text'],
marker = dict(
line = dict (
color = 'rgb(255,255,255)',
width = 2
) ),
colorbar = dict(
title = "%")
) ]
layout = dict(
title = 'Lending Clubs Default Rates <br> (Analysing Risks)',
geo = dict(
scope = 'usa',
projection=dict(type='albers usa'),
showlakes = True,
lakecolor = 'rgb(255, 255, 255)')
)
fig = dict(data=data, layout=layout)
iplot(fig, filename='d3-cloropleth-map')Credit scores are important metrics for assesing the overall level of risk. In this section we will analyze the level of risk as a whole and how many loans were bad loans by the type of grade received in the credit score of the customer.
# Let's visualise how many loans were issued by creditscore
f, ((ax1, ax2)) = plt.subplots(1, 2)
cmap = plt.cm.coolwarm
by_credit_score = df.groupby(['year', 'grade']).loan_amount.mean()
by_credit_score.unstack().plot(legend=False, ax=ax1, figsize=(14, 4), colormap=cmap)
ax1.set_title('Loans issued by Credit Score', fontsize=14)
by_inc = df.groupby(['year', 'grade']).interest_rate.mean()
by_inc.unstack().plot(ax=ax2, figsize=(14, 4), colormap=cmap)
ax2.set_title('Interest Rates by Credit Score', fontsize=14)
ax2.legend(bbox_to_anchor=(-1.0, -0.3, 1.7, 0.1), loc=5, prop={'size':12},
ncol=7, mode="expand", borderaxespad=0.)
fig = plt.figure(figsize=(16,12))
ax1 = fig.add_subplot(221)
ax2 = fig.add_subplot(222)
ax3 = fig.add_subplot(212)
cmap = plt.cm.coolwarm_r
loans_by_region = df.groupby(['grade', 'loan_condition']).size()
loans_by_region.unstack().plot(kind='bar', stacked=True, colormap=cmap, ax=ax1, grid=False)
ax1.set_title('Type of Loans by Grade', fontsize=14)
loans_by_grade = df.groupby(['sub_grade', 'loan_condition']).size()
loans_by_grade.unstack().plot(kind='bar', stacked=True, colormap=cmap, ax=ax2, grid=False)
ax2.set_title('Type of Loans by Sub-Grade', fontsize=14)
by_interest = df.groupby(['year', 'loan_condition']).interest_rate.mean()
by_interest.unstack().plot(ax=ax3, colormap=cmap)
ax3.set_title('Average Interest rate by Loan Condition', fontsize=14)
ax3.set_ylabel('Interest Rate (%)', fontsize=12)Text(0, 0.5, 'Interest Rate (%)')

My main aim in this section is to find the main factors that causes for a loan to be considered a “Bad Loan”. Logically, we could assume that factors such as a low credit grade or a high debt to income could be possible contributors in determining whether a loan is at a high risk of being defaulted.
# Just get the numeric variables
numeric_df = df.select_dtypes(include=[np.number])
df_correlations = numeric_df.corr()print(df['interest_rate'].dtype)float64
import plotly.graph_objs as go
import plotly.io as pio
from IPython.display import HTML, display
# Select only numeric columns and build the correlation matrix
numeric_df = df.select_dtypes(include=[np.number])
df_correlations = numeric_df.corr()
# Use a Quarto-friendly renderer
pio.renderers.default = "iframe_connected"
custom_scale = [
[0.0, 'rgb(165,0,38)'],
[0.111, 'rgb(215,48,39)'],
[0.222, 'rgb(244,109,67)'],
[0.333, 'rgb(253,174,97)'],
[0.444, 'rgb(254,224,144)'],
[0.556, 'rgb(224,243,248)'],
[0.667, 'rgb(171,217,233)'],
[0.778, 'rgb(116,173,209)'],
[0.889, 'rgb(69,117,180)'],
[1.0, 'rgb(49,54,149)']
]
# Build the heatmap trace, dropping unsupported 'titleside'
trace = go.Heatmap(
z=df_correlations.values,
x=df_correlations.columns,
y=df_correlations.index,
colorscale=custom_scale,
zmin=-1,
zmax=1,
colorbar=dict(
title='Level of Correlation', # no titleside here
tickmode='array',
tickvals=[-1, 0, 1],
ticktext=['−1', '0', '+1'],
ticks='outside'
)
)
fig = go.Figure(data=[trace])
fig.update_layout(title='Feature Correlation Heatmap', width=800, height=800)
# Display inline in Quarto
fig.show()This data looks a little but messy maybe if we focus our correlation heatmap into columns that are more worth it we might actually see a trend with the condition of the loan.
title = 'Bad Loans: Loan Statuses'
labels = bad_loan # All the elements that comprise a bad loan.
len(labels)
colors = ['rgba(236, 112, 99, 1)', 'rgba(235, 152, 78, 1)', 'rgba(52, 73, 94, 1)', 'rgba(128, 139, 150, 1)',
'rgba(255, 87, 51, 1)', 'rgba(255, 195, 0, 1)']
mode_size = [8,8,8,8,8,8]
line_size = [2,2,2,2,2,2]
x_data = [
sorted(df['year'].unique().tolist()),
sorted(df['year'].unique().tolist()),
sorted(df['year'].unique().tolist()),
sorted(df['year'].unique().tolist()),
sorted(df['year'].unique().tolist()),
sorted(df['year'].unique().tolist()),
]
# type of loans
charged_off = df['loan_amount'].loc[df['loan_status'] == 'Charged Off'].values.tolist()
defaults = df['loan_amount'].loc[df['loan_status'] == 'Default'].values.tolist()
not_credit_policy = df['loan_amount'].loc[df['loan_status'] == 'Does not meet the credit policy. Status:Charged Off'].values.tolist()
grace_period = df['loan_amount'].loc[df['loan_status'] == 'In Grace Period'].values.tolist()
short_late = df['loan_amount'].loc[df['loan_status'] == 'Late (16-30 days)'].values.tolist()
long_late = df['loan_amount'].loc[df['loan_status'] == 'Late (31-120 days)'].values.tolist()
y_data = [
charged_off,
defaults,
not_credit_policy,
grace_period,
short_late,
long_late,
]
p_charged_off = go.Scatter(
x = x_data[0],
y = y_data[0],
name = 'A. Charged Off',
line = dict(
color = colors[0],
width = 3,
dash='dash')
)
p_defaults = go.Scatter(
x = x_data[1],
y = y_data[1],
name = 'A. Defaults',
line = dict(
color = colors[1],
width = 3,
dash='dash')
)
p_credit_policy = go.Scatter(
x = x_data[2],
y = y_data[2],
name = 'Not Meet C.P',
line = dict(
color = colors[2],
width = 3,
dash='dash')
)
p_graced = go.Scatter(
x = x_data[3],
y = y_data[3],
name = 'A. Graced Period',
line = dict(
color = colors[3],
width = 3,
dash='dash')
)
p_short_late = go.Scatter(
x = x_data[4],
y = y_data[4],
name = 'Late (16-30 days)',
line = dict(
color = colors[4],
width = 3,
dash='dash')
)
p_long_late = go.Scatter(
x = x_data[5],
y = y_data[5],
name = 'Late (31-120 days)',
line = dict(
color = colors[5],
width = 3,
dash='dash')
)
data=[p_charged_off, p_defaults, p_credit_policy, p_graced, p_short_late, p_long_late]
layout = dict(title = 'Types of Bad Loans <br> (Amount Borrowed Throughout the Years)',
xaxis = dict(title = 'Year'),
yaxis = dict(title = 'Amount Issued'),
)
fig = dict(data=data, layout=layout)
iplot(fig, filename='line-mode')plt.figure(figsize=(18,10))
bad_df = df[df['loan_condition'] == 'Bad Loan']
# ── First subplot: boxplots of loan_amount by home_ownership, all in red ──
ax1 = plt.subplot(2, 1, 1)
sns.boxplot(
x='home_ownership',
y='loan_amount',
hue='loan_condition',
data=bad_df,
palette={'Bad Loan': 'r'},
ax=ax1
)
ax1.tick_params(axis='x', rotation=45) # rotate labels safely
ax1.set_xlabel("Type of Home Ownership", fontsize=12)
ax1.set_ylabel("Loan Amount", fontsize=12)
ax1.set_title("Distribution of Amount Borrowed\nby Home Ownership", fontsize=16)
ax1.legend_.remove()
# ── Second subplot: boxplots of loan_amount by year, faceted by home_ownership ──
ax2 = plt.subplot(2, 1, 2)
sns.boxplot(
x='year',
y='loan_amount',
hue='home_ownership',
data=bad_df,
palette="Set3",
ax=ax2
)
ax2.tick_params(axis='x', rotation=45)
ax2.set_xlabel("Year", fontsize=12)
ax2.set_ylabel("Loan Amount", fontsize=12)
ax2.set_title("Distribution of Amount Borrowed\nThrough the Years", fontsize=16)
plt.tight_layout()
plt.show()
From all the bad loans the one we are most interested about are the loans that are defaulted. Therefore, in this section we will implement an in-depth analysis of these types of Loans and see if we can gain any insight as to which features have a high correlation with the loan being defaulted.
Determine patters that will allow us to understand somehow factors that contribute to a loan being defaulted
# Get the loan amount for loans that were defaulted by each region.
northe_defaults = df['loan_amount'].loc[(df['region'] == 'NorthEast') & (df['loan_status'] == 'Default')].values.tolist()
southw_defaults = df['loan_amount'].loc[(df['region'] == 'SouthWest') & (df['loan_status'] == 'Default')].values.tolist()
southe_defaults = df['loan_amount'].loc[(df['region'] == 'SouthEast') & (df['loan_status'] == 'Default')].values.tolist()
west_defaults = df['loan_amount'].loc[(df['region'] == 'West') & (df['loan_status'] == 'Default')].values.tolist()
midw_defaults = df['loan_amount'].loc[(df['region'] == 'MidWest') & (df['loan_status'] == 'Default')].values.tolist()
# Cumulative Values
y0_stck=northe_defaults
y1_stck=[y0+y1 for y0, y1 in zip(northe_defaults, southw_defaults)]
y2_stck=[y0+y1+y2 for y0, y1, y2 in zip(northe_defaults, southw_defaults, southe_defaults)]
y3_stck=[y0+y1+y2+y3 for y0, y1, y2, y3 in zip(northe_defaults, southw_defaults, southe_defaults, west_defaults)]
y4_stck=[y0+y1+y2+y3+y4 for y0, y1, y2, y3, y4 in zip(northe_defaults, southw_defaults, southe_defaults, west_defaults, midw_defaults)]
# Make original values strings and add % for hover text
y0_txt=['$' + str(y0) for y0 in northe_defaults]
y1_txt=['$' + str(y1) for y1 in southw_defaults]
y2_txt=['$' + str(y2) for y2 in southe_defaults]
y3_txt=['$' + str(y3) for y3 in west_defaults]
y4_txt=['$'+ str(y4) for y4 in midw_defaults]
year = sorted(df["year"].unique().tolist())
NorthEast_defaults = go.Scatter(
x= year,
y= y0_stck,
text=y0_txt,
hoverinfo='x+text',
name='NorthEast',
mode= 'lines',
line=dict(width=0.5,
color='rgb(131, 90, 241)'),
fill='tonexty'
)
SouthWest_defaults = go.Scatter(
x=year,
y=y1_stck,
text=y1_txt,
hoverinfo='x+text',
name='SouthWest',
mode= 'lines',
line=dict(width=0.5,
color='rgb(255, 140, 0)'),
fill='tonexty'
)
SouthEast_defaults = go.Scatter(
x= year,
y= y2_stck,
text=y2_txt,
hoverinfo='x+text',
name='SouthEast',
mode= 'lines',
line=dict(width=0.5,
color='rgb(240, 128, 128)'),
fill='tonexty'
)
West_defaults = go.Scatter(
x= year,
y= y3_stck,
text=y3_txt,
hoverinfo='x+text',
name='West',
mode= 'lines',
line=dict(width=0.5,
color='rgb(135, 206, 235)'),
fill='tonexty'
)
MidWest_defaults = go.Scatter(
x= year,
y= y4_stck,
text=y4_txt,
hoverinfo='x+text',
name='MidWest',
mode= 'lines',
line=dict(width=0.5,
color='rgb(240, 230, 140)'),
fill='tonexty'
)
data = [NorthEast_defaults, SouthWest_defaults, SouthEast_defaults, West_defaults, MidWest_defaults]
layout = dict(title = 'Amount Defaulted by Region',
xaxis = dict(title = 'Year'),
yaxis = dict(title = 'Amount Defaulted')
)
fig = dict(data=data, layout=layout)
iplot(fig, filename='basic-area-no-bound')# create the column up front as empty strings → object dtype
df['interest_payments'] = ''
# now assign without any dtype mismatch
df.loc[df['interest_rate'] <= 13.23, 'interest_payments'] = 'Low'
df.loc[df['interest_rate'] > 13.23, 'interest_payments'] = 'High'
# define your break at the descriptive mean ~13.26
bins = [-np.inf, 13.23, np.inf]
labels = ['Low', 'High']
df['interest_payments'] = pd.cut(
df['interest_rate'],
bins=bins,
labels=labels
).astype(str)
df.head()| loan_amount | funded_amount | investor_funds | term | interest_rate | installment | grade | sub_grade | emp_length | home_ownership | ... | inq_last_12m | issue_d_clean | year | loan_condition | region | issue_period | emp_length_int | income_category | loan_condition_int | interest_payments | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 5000.0 | 5000.0 | 4975.0 | 36 months | 10.65 | 162.87 | B | B2 | 10+ years | RENT | ... | NaN | Dec-2011 | 2011 | Good Loan | SouthWest | 2011-12 | 10.0 | Low | 0 | Low |
| 1 | 2500.0 | 2500.0 | 2500.0 | 60 months | 15.27 | 59.83 | C | C4 | < 1 year | RENT | ... | NaN | Dec-2011 | 2011 | Bad Loan | SouthEast | 2011-12 | 0.5 | Low | 1 | High |
| 2 | 2400.0 | 2400.0 | 2400.0 | 36 months | 15.96 | 84.33 | C | C5 | 10+ years | RENT | ... | NaN | Dec-2011 | 2011 | Good Loan | MidWest | 2011-12 | 10.0 | Low | 0 | High |
| 3 | 10000.0 | 10000.0 | 10000.0 | 36 months | 13.49 | 339.31 | C | C1 | 10+ years | RENT | ... | NaN | Dec-2011 | 2011 | Good Loan | West | 2011-12 | 10.0 | Low | 0 | High |
| 4 | 3000.0 | 3000.0 | 3000.0 | 60 months | 12.69 | 67.79 | B | B5 | 1 year | RENT | ... | NaN | Dec-2011 | 2011 | Good Loan | West | 2011-12 | 1.0 | Low | 0 | Low |
5 rows × 76 columns
df['term'].value_counts()term
36 months 621125
60 months 266254
Name: count, dtype: int64
from scipy.stats import norm
plt.figure(figsize=(20,10))
palette = ['#009393', '#930000']
bad = df[df['loan_condition']=='Bad Loan']
# ── Subplot 1: interest_payments vs loan_condition ──
plt.subplot(221)
ax = sns.countplot(
x='interest_payments',
data=df,
palette=palette,
hue='loan_condition'
)
ax.set_title('The impact of interest rate \n on the condition of the loan', fontsize=14)
ax.set_xlabel('Level of Interest Payments', fontsize=12)
ax.set_ylabel('Count')
# ── Subplot 2: interest_payments vs term ──
plt.subplot(222)
ax1 = sns.countplot(
x='interest_payments',
data=df,
palette=palette,
hue='term'
)
ax1.set_title('The impact of maturity date \n on interest rates', fontsize=14)
ax1.set_xlabel('Level of Interest Payments', fontsize=12)
ax1.set_ylabel('Count')
# ── Subplot 3: distributions with KDE + normal fit ──
plt.subplot(212)
low = df.loc[df['interest_payments']=='Low', 'loan_amount']
high = df.loc[df['interest_payments']=='High', 'loan_amount']
# Plot histograms with KDE
ax2 = sns.histplot(
low,
stat='density',
kde=True,
color='#009393',
label='Low Interest Payments',
alpha=0.6
)
ax3 = sns.histplot(
high,
stat='density',
kde=True,
color='#930000',
label='High Interest Payments',
alpha=0.6
)
# Compute and overlay normal fits
for data, color, linecolor in [
(low, '#009393', '#483d8b'),
(high, '#930000', '#c71585'),
]:
mu, sigma = norm.fit(data)
xmin, xmax = data.min(), data.max()
x = np.linspace(xmin, xmax, 200)
plt.plot(x, norm.pdf(x, mu, sigma),
color=linecolor, lw=2)
plt.axis([0, 36000, 0, 0.00016])
plt.legend()
plt.title("Loan Amount Distributions by Interest-Payment Level", fontsize=14)
plt.xlabel("Loan Amount", fontsize=12)
plt.ylabel("Density", fontsize=12)
plt.tight_layout()
plt.show()
The main aim in this section is to compare the average interest rate for the loan status belonging to each type of loans (Good loan or bad loan) and see if there is any significant difference in the average of interest rate for each of the groups.
# Interest rate good loans
avg_fully_paid = round(np.mean(df['interest_rate'].loc[df['loan_status'] == 'Fully Paid'].values), 2)
avg_current = round(np.mean(df['interest_rate'].loc[df['loan_status'] == 'Current'].values), 2)
avg_issued = round(np.mean(df['interest_rate'].loc[df['loan_status'] == 'Issued'].values), 2)
avg_long_fully_paid = round(np.mean(df['interest_rate'].loc[df['loan_status'] == 'Does not meet the credit policy. Status:Fully Paid'].values), 2)
# Interest rate bad loans
avg_default_rates = round(np.mean(df['interest_rate'].loc[df['loan_status'] == 'Default'].values), 2)
avg_charged_off = round(np.mean(df['interest_rate'].loc[df['loan_status'] == 'Charged Off'].values), 2)
avg_long_charged_off = round(np.mean(df['interest_rate'].loc[df['loan_status'] == 'Does not meet the credit policy. Status:Charged Off'].values), 2)
avg_grace_period = round(np.mean(df['interest_rate'].loc[df['loan_status'] == 'In Grace Period'].values), 2)
avg_short_late = round(np.mean(df['interest_rate'].loc[df['loan_status'] == 'Late (16-30 days)'].values), 2)
avg_long_late = round(np.mean(df['interest_rate'].loc[df['loan_status'] == 'Late (31-120 days)'].values), 2)
# Take to a dataframe
data = [
go.Scatterpolar(
mode='lines+markers',
r = [avg_fully_paid, avg_current, avg_issued, avg_long_fully_paid],
theta = ['Fully Paid', 'Current', 'Issued', 'No C.P. Fully Paid'],
fill = 'toself',
name = 'Good Loans',
line = dict(
color = "#63AF63"
),
marker = dict(
color = "#B3FFB3",
symbol = "square",
size = 8
),
subplot = "polar",
),
go.Scatterpolar(
mode='lines+markers',
r = [avg_default_rates, avg_charged_off, avg_long_charged_off, avg_grace_period, avg_short_late, avg_long_late],
theta = ['Default Rate', 'Charged Off', 'C.P. Charged Off', 'In Grace Period', 'Late (16-30 days)', 'Late (31-120 days)'],
fill = 'toself',
name = 'Bad Loans',
line = dict(
color = "#C31414"
),
marker = dict(
color = "#FF5050",
symbol = "square",
size = 8
),
subplot = "polar2"
)
]
layout = go.Layout(
title="Average Interest Rates <br> Loan Status Distribution",
showlegend = False,
paper_bgcolor = "rgb(255, 248, 243)",
polar = dict(
domain = dict(
x = [0,0.4],
y = [0,1]
),
radialaxis = dict(
tickfont = dict(
size = 8
)
),
angularaxis = dict(
tickfont = dict(
size = 8
),
rotation = 90,
direction = "counterclockwise"
)
),
polar2 = dict(
domain = dict(
x = [0.6,1],
y = [0,1]
),
radialaxis = dict(
tickfont = dict(
size = 8
)
),
angularaxis = dict(
tickfont = dict(
size = 8
),
rotation = 90,
direction = "clockwise"
),
)
)
fig = go.Figure(data=data, layout=layout)
iplot(fig, filename='polar/directions')In this section we will go into depth regarding the reasons for clients to apply for a loan. Our main aim is to see if there are purposes that contribute to a “higher” risk whether the loan will be repaid or not.
df['purpose'].value_counts()
# Education, renewable energy, wedding are the purposed that contains highest bad loans percent wise.
purpose_condition = round(pd.crosstab(df['loan_condition'], df['purpose']).apply(lambda x: x/x.sum() * 100), 2)
purpose_bad_loans = purpose_condition.values[0].tolist()
purpose_good_loans = purpose_condition.values[1].tolist()
purpose = purpose_condition.columns
bad_plot = go.Bar(
x=purpose,
y=purpose_bad_loans,
name = 'Bad Loans',
text='%',
marker=dict(
color='rgba(219, 64, 82, 0.7)',
line = dict(
color='rgba(219, 64, 82, 1.0)',
width=2
)
)
)
good_plot = go.Bar(
x=purpose,
y=purpose_good_loans,
name='Good Loans',
text='%',
marker=dict(
color='rgba(50, 171, 96, 0.7)',
line = dict(
color='rgba(50, 171, 96, 1.0)',
width=2
)
)
)
data = [bad_plot, good_plot]
layout = go.Layout(
title='Condition of Loan by Purpose',
xaxis=dict(
title=''
),
yaxis=dict(
title='% of the Loan',
),
paper_bgcolor='#FFF8DC',
plot_bgcolor='#FFF8DC',
showlegend=True
)
fig = dict(data=data, layout=layout)
iplot(fig, filename='condition_purposes')# Average interest by income category and purposes
# Which purpose carries a higher interest rate and does income category have an influence on risk?
# Is LendingClub deploying loan amount where there is a high risk (interest_rate)
# Remember we learned that interest_rates is a key metric in evaluating risk.
group_income_purpose = (
df
.groupby(
['income_category','purpose'],
as_index=False,
observed=False # explicit current behavior
)['interest_rate']
.mean()
)
group_dti_purpose = (
df
.groupby(
['income_category','purpose'],
as_index=False,
observed=False
)['loan_amount']
.mean()
)
loan_a = group_dti_purpose['loan_amount'].values
# High Car 10.32 15669
new_groupby = group_income_purpose.assign(total_loan_amount=loan_a)
sort_group_income_purpose = new_groupby.sort_values(by="income_category", ascending=True)loan_count = df.groupby(['income_category', 'purpose'])['loan_condition'].apply(lambda x: x.value_counts())
d={"loan_c": loan_count}
loan_c_df = pd.DataFrame(data=d).reset_index()
loan_c_df = loan_c_df.rename(columns={"level_2": "loan_condition"})
# Good loans & Bad Loans
good_loans = loan_c_df.loc[loan_c_df['loan_condition'] == "Good Loan"].sort_values(by="income_category", ascending=True)
bad_loans = loan_c_df.loc[loan_c_df['loan_condition'] == "Bad Loan"].sort_values(by="income_category", ascending=True)
sort_group_income_purpose['good_loans_count'] = good_loans['loan_c'].values
sort_group_income_purpose['bad_loans_count'] = bad_loans['loan_c'].values
sort_group_income_purpose['total_loans_issued'] = (good_loans['loan_c'].values + bad_loans['loan_c'].values)
sort_group_income_purpose['bad/good ratio (%)'] = np.around(bad_loans['loan_c'].values / (bad_loans['loan_c'].values + good_loans['loan_c'].values), 4) * 100
final_df = sort_group_income_purpose.sort_values(by='income_category', ascending=True)
final_df.style.background_gradient('coolwarm')/var/folders/nm/h5zmyl7d0bb9ww_617yygd5c0000gn/T/ipykernel_79479/3982170917.py:1: FutureWarning:
The default of observed=False is deprecated and will be changed to True in a future version of pandas. Pass observed=False to retain current behavior or observed=True to adopt the future default and silence this warning.
| income_category | purpose | interest_rate | total_loan_amount | good_loans_count | bad_loans_count | total_loans_issued | bad/good ratio (%) | |
|---|---|---|---|---|---|---|---|---|
| 0 | Low | car | 12.183347 | 8296.477955 | 7126 | 540 | 7666 | 7.040000 |
| 6 | Low | major_purchase | 12.858240 | 10236.059941 | 12785 | 1112 | 13897 | 8.000000 |
| 1 | Low | credit_card | 11.970933 | 13822.853040 | 158338 | 10354 | 168692 | 6.140000 |
| 2 | Low | debt_consolidation | 13.756933 | 14075.203764 | 398907 | 36523 | 435430 | 8.390000 |
| 4 | Low | home_improvement | 13.242259 | 12437.364771 | 35176 | 2815 | 37991 | 7.410000 |
| 5 | Low | house | 16.122573 | 12936.505339 | 2542 | 361 | 2903 | 12.440000 |
| 10 | Low | renewable_energy | 15.428473 | 8744.979079 | 413 | 65 | 478 | 13.600000 |
| 3 | Low | educational | 12.169160 | 6037.270341 | 301 | 80 | 381 | 21.000000 |
| 8 | Low | moving | 15.802668 | 6884.091403 | 4053 | 553 | 4606 | 12.010000 |
| 9 | Low | other | 15.130934 | 8861.874881 | 32933 | 3720 | 36653 | 10.150000 |
| 11 | Low | small_business | 16.176433 | 13270.941431 | 6215 | 1417 | 7632 | 18.570000 |
| 12 | Low | vacation | 14.438294 | 5791.768516 | 3726 | 365 | 4091 | 8.920000 |
| 13 | Low | wedding | 14.078105 | 9726.839881 | 1761 | 250 | 2011 | 12.430000 |
| 7 | Low | medical | 14.622236 | 8155.625957 | 6471 | 710 | 7181 | 9.890000 |
| 19 | Medium | house | 15.438882 | 20772.500000 | 626 | 54 | 680 | 7.940000 |
| 14 | Medium | car | 10.926642 | 12300.115955 | 1027 | 51 | 1078 | 4.730000 |
| 15 | Medium | credit_card | 10.917918 | 21723.054359 | 32395 | 1270 | 33665 | 3.770000 |
| 16 | Medium | debt_consolidation | 12.877192 | 21729.229793 | 75708 | 4686 | 80394 | 5.830000 |
| 17 | Medium | educational | 11.688250 | 11910.000000 | 33 | 7 | 40 | 17.500000 |
| 18 | Medium | home_improvement | 12.475930 | 18624.757407 | 11015 | 630 | 11645 | 5.410000 |
| 20 | Medium | major_purchase | 11.846883 | 16552.919463 | 2817 | 163 | 2980 | 5.470000 |
| 21 | Medium | medical | 14.247550 | 13014.395833 | 1120 | 80 | 1200 | 6.670000 |
| 23 | Medium | other | 14.387957 | 15022.142323 | 4963 | 391 | 5354 | 7.300000 |
| 24 | Medium | renewable_energy | 15.277558 | 15322.383721 | 80 | 6 | 86 | 6.980000 |
| 25 | Medium | small_business | 16.385968 | 20551.165631 | 1950 | 302 | 2252 | 13.410000 |
| 26 | Medium | vacation | 13.771210 | 9139.453782 | 561 | 34 | 595 | 5.710000 |
| 27 | Medium | wedding | 14.605216 | 14257.724252 | 266 | 35 | 301 | 11.630000 |
| 22 | Medium | moving | 15.332461 | 12887.022631 | 660 | 47 | 707 | 6.650000 |
| 28 | High | car | 10.326050 | 15669.537815 | 114 | 5 | 119 | 4.200000 |
| 29 | High | credit_card | 10.606745 | 26007.836601 | 3694 | 131 | 3825 | 3.420000 |
| 30 | High | debt_consolidation | 12.467733 | 25287.176737 | 7992 | 399 | 8391 | 4.760000 |
| 40 | High | vacation | 13.097600 | 13103.000000 | 47 | 3 | 50 | 6.000000 |
| 32 | High | home_improvement | 12.225727 | 24097.799818 | 2085 | 108 | 2193 | 4.920000 |
| 31 | High | educational | 11.420000 | 11000.000000 | 1 | 1 | 2 | 50.000000 |
| 36 | High | moving | 15.150792 | 18868.564356 | 94 | 7 | 101 | 6.930000 |
| 35 | High | medical | 14.249308 | 17861.792453 | 145 | 14 | 159 | 8.810000 |
| 33 | High | house | 16.460403 | 25617.741935 | 122 | 2 | 124 | 1.610000 |
| 37 | High | other | 14.360464 | 21433.776897 | 831 | 52 | 883 | 5.890000 |
| 38 | High | renewable_energy | 14.720909 | 20222.727273 | 10 | 1 | 11 | 9.090000 |
| 39 | High | small_business | 16.410730 | 25259.127789 | 431 | 62 | 493 | 12.580000 |
| 34 | High | major_purchase | 12.416300 | 22087.625000 | 381 | 19 | 400 | 4.750000 |
| 41 | High | wedding | 14.477143 | 20503.571429 | 31 | 4 | 35 | 11.430000 |
final_df = final_df.sort_values(by="purpose", ascending=False)# Work on a plot to explain better the correlations between the different columns in final_df dataframe.
# We will do a Subplot in Plotly with
pio.renderers.default = 'colab'
purpose_labels = final_df['purpose'].unique().tolist()
high_income = final_df.loc[final_df['income_category']=='High','interest_rate'].tolist()
medium_income = final_df.loc[final_df['income_category']=='Medium','interest_rate'].tolist()
low_income = final_df.loc[final_df['income_category']=='Low','interest_rate'].tolist()
trace1 = go.Scatter(x=high_income, y=purpose_labels, mode='markers',
name='High Income', marker=dict(color='#0040FF', size=12))
trace2 = go.Scatter(x=medium_income, y=purpose_labels, mode='markers',
name='Medium Income', marker=dict(color='#FE9A2E', size=12))
trace3 = go.Scatter(x=low_income, y=purpose_labels, mode='markers',
name='Low Income', marker=dict(color='#FE2E2E', size=12))
fig = go.Figure(data=[trace1, trace2, trace3])
fig.update_layout(
title="Average Purpose Interest Rate<br><i>by Income Category</i>",
xaxis_title="Average Interest Rate",
yaxis_title="Purpose",
xaxis=dict(type='linear') # ensure numeric axis
)
fig.show()from plotly.subplots import make_subplots
# make it render in Colab
pio.renderers.default = "colab"
# your labels
purpose_labels = final_df['purpose'].unique()
# Good‐loan counts
good_high_cnt = final_df.loc[final_df['income_category']=="High", 'good_loans_count'].tolist()
good_med_cnt = final_df.loc[final_df['income_category']=="Medium", 'good_loans_count'].tolist()
good_low_cnt = final_df.loc[final_df['income_category']=="Low", 'good_loans_count'].tolist()
# Bad‐loan counts
bad_high_cnt = final_df.loc[final_df['income_category']=="High", 'bad_loans_count'].tolist()
bad_med_cnt = final_df.loc[final_df['income_category']=="Medium", 'bad_loans_count'].tolist()
bad_low_cnt = final_df.loc[final_df['income_category']=="Low", 'bad_loans_count'].tolist()
# build bar traces
good_traces = [
go.Bar(x=good_high_cnt, y=purpose_labels, name='High Income', orientation='h', marker_color='#0040FF', legendgroup='good'),
go.Bar(x=good_med_cnt, y=purpose_labels, name='Medium Income', orientation='h', marker_color='#FE9A2E', legendgroup='good'),
go.Bar(x=good_low_cnt, y=purpose_labels, name='Low Income', orientation='h', marker_color='#FE2E2E', legendgroup='good'),
]
bad_traces = [
go.Bar(x=bad_high_cnt, y=purpose_labels, showlegend=False, name='High Income', orientation='h', marker_color='#0040FF', legendgroup='bad'),
go.Bar(x=bad_med_cnt, y=purpose_labels, showlegend=False, name='Medium Income', orientation='h', marker_color='#FE9A2E', legendgroup='bad'),
go.Bar(x=bad_low_cnt, y=purpose_labels, showlegend=False, name='Low Income', orientation='h', marker_color='#FE2E2E', legendgroup='bad'),
]
# make 2×1 subplots
fig = make_subplots(
rows=2, cols=1,
shared_xaxes=False,
vertical_spacing=0.15,
subplot_titles=("Good Loans Issued", "Bad Loans Issued")
)
# add traces
for t in good_traces:
fig.add_trace(t, row=1, col=1)
for t in bad_traces:
fig.add_trace(t, row=2, col=1)
# layout tweaks
fig.update_layout(
height=800,
width=900,
title_text="Issuance of Loans by Purpose and Income Category",
barmode='stack',
xaxis1=dict(title="Number of Loans Issued"),
xaxis2=dict(title="Number of Loans Issued")
)
fig.show()# Next task a Radar Chart with the bad/good ratio to see if it justifies the amount of loans issued towards housing
high_ratio = final_df.loc[final_df['income_category'] == 'High']
medium_ratio = final_df.loc[final_df['income_category'] == 'Medium']
low_ratio = final_df.loc[final_df['income_category'] == 'Low']
data = [
go.Scatterpolar(
mode='lines+markers',
r = high_ratio['bad/good ratio (%)'].values.tolist(),
theta = high_ratio['purpose'].unique(),
fill = 'toself',
name = 'High Income',
line = dict(
color = "#63AF63"
),
marker = dict(
color = "#B3FFB3",
symbol = "square",
size = 8
),
subplot = "polar",
),
go.Scatterpolar(
mode='lines+markers',
r = medium_ratio['bad/good ratio (%)'].values.tolist(),
theta = medium_ratio['purpose'].unique(),
fill = 'toself',
name = 'Medium Income',
line = dict(
color = "#C31414"
),
marker = dict(
color = "#FF5050",
symbol = "square",
size = 8
),
subplot = "polar2"
),
go.Scatterpolar(
mode='lines+markers',
r = low_ratio['bad/good ratio (%)'].values.tolist(),
theta = low_ratio['purpose'].unique(),
fill = 'toself',
name = 'Low Income',
line = dict(
color = "#C9FFC7"
),
marker = dict(
color = "#8CB28B",
symbol = "square",
size = 8
),
subplot = "polar3"
),
]
layout = go.Layout(
title="Bad/Good Ratio <br> (By Purpose)",
showlegend = False,
paper_bgcolor = "rgb(255, 206, 153)",
polar = dict(
domain = dict(
x = [0,0.3],
y = [0,1]
),
radialaxis = dict(
tickfont = dict(
size = 6
)
),
angularaxis = dict(
tickfont = dict(
size = 6
),
rotation = 90,
direction = "counterclockwise"
)
),
polar2 = dict(
domain = dict(
x = [0.35,0.65],
y = [0,1]
),
radialaxis = dict(
tickfont = dict(
size = 6
)
),
angularaxis = dict(
tickfont = dict(
size = 6
),
rotation = 85,
direction = "clockwise"
),
),
polar3 = dict(
domain = dict(
x = [0.7, 1],
y = [0,1]
),
radialaxis = dict(
tickfont = dict(
size = 6
)
),
angularaxis = dict(
tickfont = dict(
size = 6
),
rotation = 90,
direction = "clockwise"
),
))
fig = go.Figure(data=data, layout=layout)
iplot(fig, filename = "radar/multiple")# Copy Dataframe
complete_df = df.copy()
# Handling Missing Numeric Values
# Transform Missing Values for numeric dataframe
# Nevertheless check what these variables mean tomorrow in the morning.
for col in ('dti_joint', 'annual_inc_joint', 'il_util', 'mths_since_rcnt_il', 'open_acc_6m', 'open_il_6m', 'open_il_12m',
'open_il_24m', 'inq_last_12m', 'open_rv_12m', 'open_rv_24m', 'max_bal_bc', 'all_util', 'inq_fi', 'total_cu_tl',
'mths_since_last_record', 'mths_since_last_major_derog', 'mths_since_last_delinq', 'total_bal_il', 'tot_coll_amt',
'tot_cur_bal', 'total_rev_hi_lim', 'revol_util', 'collections_12_mths_ex_med', 'open_acc', 'inq_last_6mths',
'verification_status_joint', 'acc_now_delinq'):
complete_df[col] = complete_df[col].fillna(0)
# # Get the mode of next payment date and last payment date and the last date credit amount was pulled
complete_df["next_pymnt_d"] = complete_df.groupby("region")["next_pymnt_d"].transform(lambda x: x.fillna(x.mode))
complete_df["last_pymnt_d"] = complete_df.groupby("region")["last_pymnt_d"].transform(lambda x: x.fillna(x.mode))
complete_df["last_credit_pull_d"] = complete_df.groupby("region")["last_credit_pull_d"].transform(lambda x: x.fillna(x.mode))
complete_df["earliest_cr_line"] = complete_df.groupby("region")["earliest_cr_line"].transform(lambda x: x.fillna(x.mode))
# # Get the mode on the number of accounts in which the client is delinquent
complete_df["pub_rec"] = complete_df.groupby("region")["pub_rec"].transform(lambda x: x.fillna(x.median()))
# # Get the mean of the annual income depending in the region the client is located.
complete_df["annual_income"] = complete_df.groupby("region")["annual_income"].transform(lambda x: x.fillna(x.mean()))
# Get the mode of the total number of credit lines the borrower has
complete_df["total_acc"] = complete_df.groupby("region")["total_acc"].transform(lambda x: x.fillna(x.median()))
# Mode of credit delinquencies in the past two years.
complete_df["delinq_2yrs"] = complete_df.groupby("region")["delinq_2yrs"].transform(lambda x: x.fillna(x.mean()))# Drop these variables before scaling but don't drop these when we perform feature engineering on missing values.
# Columns to delete or fix: earliest_cr_line, last_pymnt_d, next_pymnt_d, last_credit_pull_d, verification_status_joint
# ---->>>> Fix the problems shown during scaling with the columns above.
cols_to_drop = [
'issue_d', 'income_category', 'region', 'year', 'emp_length',
'loan_condition','earliest_cr_line','last_pymnt_d','next_pymnt_d',
'last_credit_pull_d','verification_status_joint','emp_length_int',
'total_rec_prncp','funded_amount','investor_funds','sub_grade',
'complete_date','loan_status','interest_payments','initial_list_status',
'out_prncp','out_prncp_inv','total_pymnt','total_pymnt_inv',
'total_rec_int','total_rec_late_fee','recoveries',
'collection_recovery_fee','last_pymnt_amnt','collections_12_mths_ex_med',
'mths_since_last_major_derog','policy_code','application_type',
'annual_inc_joint','dti_joint','acc_now_delinq','tot_coll_amt',
'tot_cur_bal','open_acc_6m','open_il_6m','open_il_12m','open_il_24m',
'mths_since_rcnt_il','total_bal_il','il_util','open_rv_12m',
'open_rv_24m','max_bal_bc','all_util','total_rev_hi_lim',
'inq_fi','total_cu_tl','inq_last_12m'
]
complete_df.drop(cols_to_drop, axis=1, inplace=True, errors='ignore')complete_df.columnsIndex(['loan_amount', 'term', 'interest_rate', 'installment', 'grade',
'home_ownership', 'annual_income', 'verification_status', 'pymnt_plan',
'purpose', 'addr_state', 'dti', 'delinq_2yrs', 'inq_last_6mths',
'mths_since_last_delinq', 'mths_since_last_record', 'open_acc',
'pub_rec', 'revol_bal', 'revol_util', 'total_acc', 'issue_d_clean',
'issue_period', 'loan_condition_int'],
dtype='object')
complete_df.isnull().sum().max() # Maximum number of nulls.np.int64(0)
# Let's make a copy of the dataframe to avoid confusion.
from imblearn.over_sampling import SMOTE
from sklearn.pipeline import make_pipeline
from imblearn.pipeline import make_pipeline as imbalanced_make_pipeline
from imblearn.over_sampling import SMOTE
from imblearn.under_sampling import NearMiss
from imblearn.metrics import classification_report_imbalanced
from sklearn.metrics import precision_score, recall_score, f1_score, roc_auc_score, accuracy_score, classification_report
from collections import Counter
from sklearn.model_selection import KFold, StratifiedKFold, StratifiedShuffleSplit
from sklearn.linear_model import LogisticRegression
len(complete_df['loan_condition_int'])
# Loan Ratios (Imbalanced classes)
complete_df['loan_condition_int'].value_counts()/len(complete_df['loan_condition_int']) * 100loan_condition_int
0 92.40133
1 7.59867
Name: count, dtype: float64
The purpose of the code below is to have the same ratio across our training and test sets.
from sklearn.model_selection import StratifiedShuffleSplit
stratified = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=42)
for train_set, test_set in stratified.split(complete_df, complete_df["loan_condition_int"]):
stratified_train = complete_df.loc[train_set]
stratified_test = complete_df.loc[test_set]
print('Train set ratio \n', stratified_train["loan_condition_int"].value_counts()/len(df))
print('Test set ratio \n', stratified_test["loan_condition_int"].value_counts()/len(df))Train set ratio
loan_condition_int
0 0.739211
1 0.060789
Name: count, dtype: float64
Test set ratio
loan_condition_int
0 0.184803
1 0.015198
Name: count, dtype: float64
train_df = stratified_train
test_df = stratified_test
# Let's Shuffle the data
train_df = train_df.sample(frac=1).reset_index(drop=True)
test_df = test_df.sample(frac=1).reset_index(drop=True)
# Train set (Normal training dataset)
X_train = train_df.drop('loan_condition_int', axis=1)
y_train = train_df['loan_condition_int']
# Test Dataset
X_test = test_df.drop('loan_condition_int', axis=1)
y_test = test_df['loan_condition_int']from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.utils import check_array
from sklearn.preprocessing import LabelEncoder
from scipy import sparse
class CategoricalEncoder(BaseEstimator, TransformerMixin):
"""Encode categorical features as a numeric array.
The input to this transformer should be a matrix of integers or strings,
denoting the values taken on by categorical (discrete) features.
The features can be encoded using a one-hot aka one-of-K scheme
(``encoding='onehot'``, the default) or converted to ordinal integers
(``encoding='ordinal'``).
This encoding is needed for feeding categorical data to many scikit-learn
estimators, notably linear models and SVMs with the standard kernels.
Read more in the :ref:`User Guide <preprocessing_categorical_features>`.
Parameters
----------
encoding : str, 'onehot', 'onehot-dense' or 'ordinal'
The type of encoding to use (default is 'onehot'):
- 'onehot': encode the features using a one-hot aka one-of-K scheme
(or also called 'dummy' encoding). This creates a binary column for
each category and returns a sparse matrix.
- 'onehot-dense': the same as 'onehot' but returns a dense array
instead of a sparse matrix.
- 'ordinal': encode the features as ordinal integers. This results in
a single column of integers (0 to n_categories - 1) per feature.
categories : 'auto' or a list of lists/arrays of values.
Categories (unique values) per feature:
- 'auto' : Determine categories automatically from the training data.
- list : ``categories[i]`` holds the categories expected in the ith
column. The passed categories are sorted before encoding the data
(used categories can be found in the ``categories_`` attribute).
dtype : number type, default np.float64
Desired dtype of output.
handle_unknown : 'error' (default) or 'ignore'
Whether to raise an error or ignore if a unknown categorical feature is
present during transform (default is to raise). When this is parameter
is set to 'ignore' and an unknown category is encountered during
transform, the resulting one-hot encoded columns for this feature
will be all zeros.
Ignoring unknown categories is not supported for
``encoding='ordinal'``.
Attributes
----------
categories_ : list of arrays
The categories of each feature determined during fitting. When
categories were specified manually, this holds the sorted categories
(in order corresponding with output of `transform`).
Examples
--------
Given a dataset with three features and two samples, we let the encoder
find the maximum value per feature and transform the data to a binary
one-hot encoding.
>>> from sklearn.preprocessing import CategoricalEncoder
>>> enc = CategoricalEncoder(handle_unknown='ignore')
>>> enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])
... # doctest: +ELLIPSIS
CategoricalEncoder(categories='auto', dtype=<... 'numpy.float64'>,
encoding='onehot', handle_unknown='ignore')
>>> enc.transform([[0, 1, 1], [1, 0, 4]]).toarray()
array([[ 1., 0., 0., 1., 0., 0., 1., 0., 0.],
[ 0., 1., 1., 0., 0., 0., 0., 0., 0.]])
See also
--------
sklearn.preprocessing.OneHotEncoder : performs a one-hot encoding of
integer ordinal features. The ``OneHotEncoder assumes`` that input
features take on values in the range ``[0, max(feature)]`` instead of
using the unique values.
sklearn.feature_extraction.DictVectorizer : performs a one-hot encoding of
dictionary items (also handles string-valued features).
sklearn.feature_extraction.FeatureHasher : performs an approximate one-hot
encoding of dictionary items or strings.
"""
def __init__(self, encoding='onehot', categories='auto', dtype=np.float64,
handle_unknown='error'):
self.encoding = encoding
self.categories = categories
self.dtype = dtype
self.handle_unknown = handle_unknown
def fit(self, X, y=None):
"""Fit the CategoricalEncoder to X.
Parameters
----------
X : array-like, shape [n_samples, n_feature]
The data to determine the categories of each feature.
Returns
-------
self
"""
if self.encoding not in ['onehot', 'onehot-dense', 'ordinal']:
template = ("encoding should be either 'onehot', 'onehot-dense' "
"or 'ordinal', got %s")
raise ValueError(template % self.handle_unknown)
if self.handle_unknown not in ['error', 'ignore']:
template = ("handle_unknown should be either 'error' or "
"'ignore', got %s")
raise ValueError(template % self.handle_unknown)
if self.encoding == 'ordinal' and self.handle_unknown == 'ignore':
raise ValueError("handle_unknown='ignore' is not supported for"
" encoding='ordinal'")
X = check_array(X, dtype=np.object, accept_sparse='csc', copy=True)
n_samples, n_features = X.shape
self._label_encoders_ = [LabelEncoder() for _ in range(n_features)]
for i in range(n_features):
le = self._label_encoders_[i]
Xi = X[:, i]
if self.categories == 'auto':
le.fit(Xi)
else:
valid_mask = np.in1d(Xi, self.categories[i])
if not np.all(valid_mask):
if self.handle_unknown == 'error':
diff = np.unique(Xi[~valid_mask])
msg = ("Found unknown categories {0} in column {1}"
" during fit".format(diff, i))
raise ValueError(msg)
le.classes_ = np.array(np.sort(self.categories[i]))
self.categories_ = [le.classes_ for le in self._label_encoders_]
return self
def transform(self, X):
"""Transform X using one-hot encoding.
Parameters
----------
X : array-like, shape [n_samples, n_features]
The data to encode.
Returns
-------
X_out : sparse matrix or a 2-d array
Transformed input.
"""
X = check_array(X, accept_sparse='csc', dtype=np.object, copy=True)
n_samples, n_features = X.shape
X_int = np.zeros_like(X, dtype=np.int)
X_mask = np.ones_like(X, dtype=np.bool)
for i in range(n_features):
valid_mask = np.in1d(X[:, i], self.categories_[i])
if not np.all(valid_mask):
if self.handle_unknown == 'error':
diff = np.unique(X[~valid_mask, i])
msg = ("Found unknown categories {0} in column {1}"
" during transform".format(diff, i))
raise ValueError(msg)
else:
# Set the problematic rows to an acceptable value and
# continue `The rows are marked `X_mask` and will be
# removed later.
X_mask[:, i] = valid_mask
X[:, i][~valid_mask] = self.categories_[i][0]
X_int[:, i] = self._label_encoders_[i].transform(X[:, i])
if self.encoding == 'ordinal':
return X_int.astype(self.dtype, copy=False)
mask = X_mask.ravel()
n_values = [cats.shape[0] for cats in self.categories_]
n_values = np.array([0] + n_values)
indices = np.cumsum(n_values)
column_indices = (X_int + indices[:-1]).ravel()[mask]
row_indices = np.repeat(np.arange(n_samples, dtype=np.int32),
n_features)[mask]
data = np.ones(n_samples * n_features)[mask]
out = sparse.csc_matrix((data, (row_indices, column_indices)),
shape=(n_samples, indices[-1]),
dtype=self.dtype).tocsr()
if self.encoding == 'onehot-dense':
return out.toarray()
else:
return outfrom sklearn.base import BaseEstimator, TransformerMixin
# A class to select numerical or categorical columns
# since Scikit-Learn doesn't handle DataFrames yet
class DataFrameSelector(BaseEstimator, TransformerMixin):
def __init__(self, attribute_names):
self.attribute_names = attribute_names
def fit(self, X, y=None):
return self
def transform(self, X):
return X[self.attribute_names]from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
# pick out just true numeric dtypes
numeric_cols = X_train.select_dtypes(include=[np.number]).columns.tolist()
categorical_cols = X_train.select_dtypes(exclude=[np.number]).columns.tolist()
preprocessor = ColumnTransformer([
("num", StandardScaler(), numeric_cols),
("cat", OneHotEncoder(handle_unknown="ignore",
sparse_output=False),
categorical_cols),
])
X_train_transformed = preprocessor.fit_transform(X_train)
X_test_transformed = preprocessor.transform(X_test)# Convert the PeriodIndex into a POSIX timestamp (nanoseconds since epoch)
X_train['year_month_ord'] = (
X_train['issue_period'] # your PeriodDtype column
.dt
.to_timestamp() # → datetime64[ns]
.astype('int64') # → integer nanoseconds
)
X_test['year_month_ord'] = (
X_test['issue_period']
.dt
.to_timestamp()
.astype('int64')
)
# Now re-select true numeric columns (you’ll see year_month_ord in here)
numeric_cols = X_train.select_dtypes(include=[np.number]).columns.tolist()
categorical_cols = X_train.select_dtypes(exclude=[np.number]).columns.tolist()
print("Numerics:", numeric_cols)
print("Categoricals:", categorical_cols)Numerics: ['loan_amount', 'interest_rate', 'installment', 'annual_income', 'dti', 'delinq_2yrs', 'inq_last_6mths', 'mths_since_last_delinq', 'mths_since_last_record', 'open_acc', 'pub_rec', 'revol_bal', 'revol_util', 'total_acc', 'year_month_ord']
Categoricals: ['term', 'grade', 'home_ownership', 'verification_status', 'pymnt_plan', 'purpose', 'addr_state', 'issue_d_clean', 'issue_period']
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
# 1) Make sure your train/test have no Period dtypes
# (either drop issue_period or convert it to an int timestamp or ordinal first)
# 2) Recompute the column lists
numeric_cols = X_train.select_dtypes(include=[np.number]).columns.tolist()
categorical_cols = X_train.select_dtypes(exclude=[np.number]).columns.tolist()
# 3) Build the ColumnTransformer
preprocessor = ColumnTransformer(
transformers=[
("num", StandardScaler(), numeric_cols),
("cat", OneHotEncoder(handle_unknown="ignore", sparse_output=False), categorical_cols),
],
remainder="drop" # any other columns are dropped
)
# 4) Fit/transform in one go
X_train = preprocessor.fit_transform(X_train)
X_test = preprocessor.transform(X_test)from sklearn.linear_model import LogisticRegression
log_reg = LogisticRegression()
# log_reg_sm = LogisticRegression()
log_reg.fit(X_train, y_train)/Users/rishigovind/Library/Python/3.9/lib/python/site-packages/sklearn/linear_model/_linear_loss.py:200: RuntimeWarning:
divide by zero encountered in matmul
/Users/rishigovind/Library/Python/3.9/lib/python/site-packages/sklearn/linear_model/_linear_loss.py:200: RuntimeWarning:
overflow encountered in matmul
/Users/rishigovind/Library/Python/3.9/lib/python/site-packages/sklearn/linear_model/_linear_loss.py:200: RuntimeWarning:
invalid value encountered in matmul
/Users/rishigovind/Library/Python/3.9/lib/python/site-packages/sklearn/linear_model/_linear_loss.py:330: RuntimeWarning:
divide by zero encountered in matmul
/Users/rishigovind/Library/Python/3.9/lib/python/site-packages/sklearn/linear_model/_linear_loss.py:330: RuntimeWarning:
overflow encountered in matmul
/Users/rishigovind/Library/Python/3.9/lib/python/site-packages/sklearn/linear_model/_linear_loss.py:330: RuntimeWarning:
invalid value encountered in matmul
LogisticRegression()In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
LogisticRegression()
from sklearn.metrics import accuracy_score
normal_ypred = log_reg.predict(X_test)
print(accuracy_score(y_test, normal_ypred))0.9239840879893619
/Users/rishigovind/Library/Python/3.9/lib/python/site-packages/sklearn/utils/extmath.py:203: RuntimeWarning:
divide by zero encountered in matmul
/Users/rishigovind/Library/Python/3.9/lib/python/site-packages/sklearn/utils/extmath.py:203: RuntimeWarning:
overflow encountered in matmul
/Users/rishigovind/Library/Python/3.9/lib/python/site-packages/sklearn/utils/extmath.py:203: RuntimeWarning:
invalid value encountered in matmul
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
# 1) Cast to smaller dtypes
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
y_train = y_train.astype('int32')
y_test = y_test.astype('int32')
# 2) Build tf.data pipelines
batch_size = 32 # try lowering if you still OOM
train_ds = (
tf.data.Dataset
.from_tensor_slices((X_train, y_train))
.shuffle(buffer_size=10_000, seed=42, reshuffle_each_iteration=True)
.batch(batch_size)
.prefetch(tf.data.AUTOTUNE)
)
val_ds = (
tf.data.Dataset
.from_tensor_slices((X_test, y_test))
.batch(batch_size)
.prefetch(tf.data.AUTOTUNE)
)
# 3) Define your model with tf.keras
tf.keras.utils.set_random_seed(42)
n_inputs = X_train.shape[1]
model = keras.Sequential([
layers.Input(shape=(n_inputs,), name="input"),
layers.Dense(66, activation="relu", name="hidden1"),
layers.Dense(66, activation="relu", name="hidden2"),
layers.Dense(2, name="outputs") # logits for 2 classes
], name="loan_risk_dnn")
model.compile(
optimizer=keras.optimizers.Adam(learning_rate=0.01),
loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=["accuracy"]
)
# 4) Train on the Dataset
history = model.fit(
train_ds,
epochs=5,
validation_data=val_ds
)Epoch 1/5 1/22185 ━━━━━━━━━━━━━━━━━━━━ 2:25:18 393ms/step - accuracy: 0.2188 - loss: 0.7565 132/22185 ━━━━━━━━━━━━━━━━━━━━ 8s 383us/step - accuracy: 0.8972 - loss: 0.3055 281/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 359us/step - accuracy: 0.9103 - loss: 0.2844 432/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 350us/step - accuracy: 0.9145 - loss: 0.2748 580/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 347us/step - accuracy: 0.9167 - loss: 0.2690 725/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 347us/step - accuracy: 0.9181 - loss: 0.2650 873/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 346us/step - accuracy: 0.9191 - loss: 0.2621 1020/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 345us/step - accuracy: 0.9198 - loss: 0.2599 1169/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 344us/step - accuracy: 0.9204 - loss: 0.2578 1319/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 343us/step - accuracy: 0.9209 - loss: 0.2562 1467/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 342us/step - accuracy: 0.9213 - loss: 0.2548 1617/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 342us/step - accuracy: 0.9216 - loss: 0.2537 1767/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9218 - loss: 0.2528 1916/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9220 - loss: 0.2520 2065/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 340us/step - accuracy: 0.9221 - loss: 0.2514 2216/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 340us/step - accuracy: 0.9222 - loss: 0.2508 2367/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 339us/step - accuracy: 0.9223 - loss: 0.2502 2515/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 339us/step - accuracy: 0.9224 - loss: 0.2497 2649/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9224 - loss: 0.2494 2794/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9225 - loss: 0.2490 2943/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9225 - loss: 0.2487 3092/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9225 - loss: 0.2484 3241/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9226 - loss: 0.2481 3389/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9226 - loss: 0.2478 3536/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9227 - loss: 0.2475 3684/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9227 - loss: 0.2473 3833/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 340us/step - accuracy: 0.9227 - loss: 0.2470 3981/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 340us/step - accuracy: 0.9228 - loss: 0.2467 4130/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 340us/step - accuracy: 0.9228 - loss: 0.2465 4279/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 340us/step - accuracy: 0.9229 - loss: 0.2463 4427/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 340us/step - accuracy: 0.9229 - loss: 0.2461 4576/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 340us/step - accuracy: 0.9229 - loss: 0.2459 4724/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 340us/step - accuracy: 0.9230 - loss: 0.2457 4872/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 340us/step - accuracy: 0.9230 - loss: 0.2455 5019/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 340us/step - accuracy: 0.9230 - loss: 0.2453 5169/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 340us/step - accuracy: 0.9230 - loss: 0.2452 5317/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 340us/step - accuracy: 0.9230 - loss: 0.2450 5465/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 340us/step - accuracy: 0.9231 - loss: 0.2449 5614/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 340us/step - accuracy: 0.9231 - loss: 0.2448 5764/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 339us/step - accuracy: 0.9231 - loss: 0.2446 5914/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 339us/step - accuracy: 0.9231 - loss: 0.2445 6061/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 339us/step - accuracy: 0.9231 - loss: 0.2444 6208/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 339us/step - accuracy: 0.9231 - loss: 0.2443 6356/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 339us/step - accuracy: 0.9232 - loss: 0.2441 6505/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 339us/step - accuracy: 0.9232 - loss: 0.2440 6651/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 339us/step - accuracy: 0.9232 - loss: 0.2439 6797/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 340us/step - accuracy: 0.9232 - loss: 0.2438 6943/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 340us/step - accuracy: 0.9232 - loss: 0.2437 7092/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 340us/step - accuracy: 0.9232 - loss: 0.2436 7241/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 340us/step - accuracy: 0.9232 - loss: 0.2435 7390/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 339us/step - accuracy: 0.9233 - loss: 0.2434 7538/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 339us/step - accuracy: 0.9233 - loss: 0.2433 7687/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 339us/step - accuracy: 0.9233 - loss: 0.2432 7836/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 339us/step - accuracy: 0.9233 - loss: 0.2432 7984/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 339us/step - accuracy: 0.9233 - loss: 0.2431 8133/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 339us/step - accuracy: 0.9233 - loss: 0.2430 8282/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 339us/step - accuracy: 0.9233 - loss: 0.2429 8428/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 339us/step - accuracy: 0.9233 - loss: 0.2429 8575/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 339us/step - accuracy: 0.9233 - loss: 0.2428 8724/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 339us/step - accuracy: 0.9233 - loss: 0.2427 8874/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 339us/step - accuracy: 0.9233 - loss: 0.2427 9022/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 339us/step - accuracy: 0.9233 - loss: 0.2426 9171/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 339us/step - accuracy: 0.9233 - loss: 0.2426 9320/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 339us/step - accuracy: 0.9233 - loss: 0.2425 9467/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 339us/step - accuracy: 0.9233 - loss: 0.2424 9613/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 339us/step - accuracy: 0.9233 - loss: 0.2424 9762/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 339us/step - accuracy: 0.9233 - loss: 0.2423 9910/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 339us/step - accuracy: 0.9234 - loss: 0.2423 10060/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 339us/step - accuracy: 0.9234 - loss: 0.2422 10208/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 339us/step - accuracy: 0.9234 - loss: 0.2422 10357/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 339us/step - accuracy: 0.9234 - loss: 0.2421 10504/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 339us/step - accuracy: 0.9234 - loss: 0.2421 10650/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 339us/step - accuracy: 0.9234 - loss: 0.2420 10797/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 339us/step - accuracy: 0.9234 - loss: 0.2420 10945/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 339us/step - accuracy: 0.9234 - loss: 0.2420 11091/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 339us/step - accuracy: 0.9234 - loss: 0.2419 11235/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 339us/step - accuracy: 0.9234 - loss: 0.2419 11351/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 340us/step - accuracy: 0.9234 - loss: 0.2419 11491/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 341us/step - accuracy: 0.9234 - loss: 0.2418 11624/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 341us/step - accuracy: 0.9234 - loss: 0.2418 11763/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 341us/step - accuracy: 0.9234 - loss: 0.2418 11900/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9234 - loss: 0.2417 12040/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9234 - loss: 0.2417 12184/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9234 - loss: 0.2417 12333/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9234 - loss: 0.2416 12482/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9234 - loss: 0.2416 12629/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9234 - loss: 0.2416 12776/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9234 - loss: 0.2416 12923/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9234 - loss: 0.2415 13071/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9234 - loss: 0.2415 13219/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9234 - loss: 0.2415 13366/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9234 - loss: 0.2414 13513/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9234 - loss: 0.2414 13659/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9234 - loss: 0.2414 13805/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9234 - loss: 0.2413 13954/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9234 - loss: 0.2413 14100/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9234 - loss: 0.2413 14247/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9234 - loss: 0.2413 14395/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9234 - loss: 0.2412 14542/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9234 - loss: 0.2412 14690/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9234 - loss: 0.2412 14838/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 341us/step - accuracy: 0.9234 - loss: 0.2411 14986/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 341us/step - accuracy: 0.9234 - loss: 0.2411 15134/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 341us/step - accuracy: 0.9234 - loss: 0.2411 15282/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 341us/step - accuracy: 0.9234 - loss: 0.2411 15428/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 341us/step - accuracy: 0.9234 - loss: 0.2410 15576/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 341us/step - accuracy: 0.9234 - loss: 0.2410 15723/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 341us/step - accuracy: 0.9234 - loss: 0.2410 15872/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 341us/step - accuracy: 0.9234 - loss: 0.2410 16021/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 341us/step - accuracy: 0.9234 - loss: 0.2410 16170/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 341us/step - accuracy: 0.9234 - loss: 0.2409 16316/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 341us/step - accuracy: 0.9234 - loss: 0.2409 16463/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 341us/step - accuracy: 0.9234 - loss: 0.2409 16609/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 341us/step - accuracy: 0.9234 - loss: 0.2409 16755/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 341us/step - accuracy: 0.9234 - loss: 0.2409 16901/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 341us/step - accuracy: 0.9235 - loss: 0.2408 17047/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 341us/step - accuracy: 0.9235 - loss: 0.2408 17194/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 341us/step - accuracy: 0.9235 - loss: 0.2408 17338/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 341us/step - accuracy: 0.9235 - loss: 0.2408 17485/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 341us/step - accuracy: 0.9235 - loss: 0.2408 17634/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 341us/step - accuracy: 0.9235 - loss: 0.2407 17780/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 341us/step - accuracy: 0.9235 - loss: 0.2407 17928/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 341us/step - accuracy: 0.9235 - loss: 0.2407 18070/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9235 - loss: 0.2407 18215/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9235 - loss: 0.2407 18363/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9235 - loss: 0.2406 18512/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9235 - loss: 0.2406 18661/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 341us/step - accuracy: 0.9235 - loss: 0.2406 18807/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 341us/step - accuracy: 0.9235 - loss: 0.2406 18951/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9235 - loss: 0.2406 19099/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9235 - loss: 0.2405 19245/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9235 - loss: 0.2405 19393/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9235 - loss: 0.2405 19542/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 341us/step - accuracy: 0.9235 - loss: 0.2405 19690/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 341us/step - accuracy: 0.9235 - loss: 0.2405 19838/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 341us/step - accuracy: 0.9235 - loss: 0.2404 19984/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 341us/step - accuracy: 0.9235 - loss: 0.2404 20131/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 341us/step - accuracy: 0.9235 - loss: 0.2404 20275/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9235 - loss: 0.2404 20422/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9235 - loss: 0.2404 20570/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 341us/step - accuracy: 0.9235 - loss: 0.2403 20713/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9235 - loss: 0.2403 20860/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9235 - loss: 0.2403 21005/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9235 - loss: 0.2403 21151/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9235 - loss: 0.2403 21298/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9235 - loss: 0.2403 21444/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9236 - loss: 0.2403 21591/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9236 - loss: 0.2402 21739/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9236 - loss: 0.2402 21886/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9236 - loss: 0.2402 22034/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9236 - loss: 0.2402 22180/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9236 - loss: 0.2402 22185/22185 ━━━━━━━━━━━━━━━━━━━━ 9s 409us/step - accuracy: 0.9236 - loss: 0.2402 - val_accuracy: 0.9240 - val_loss: 0.2350 Epoch 2/5 1/22185 ━━━━━━━━━━━━━━━━━━━━ 2:21 6ms/step - accuracy: 0.8750 - loss: 0.3134 147/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 343us/step - accuracy: 0.9255 - loss: 0.2381 292/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 344us/step - accuracy: 0.9257 - loss: 0.2366 439/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 343us/step - accuracy: 0.9260 - loss: 0.2352 585/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 343us/step - accuracy: 0.9259 - loss: 0.2345 733/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 343us/step - accuracy: 0.9261 - loss: 0.2339 880/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 342us/step - accuracy: 0.9261 - loss: 0.2336 1028/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 342us/step - accuracy: 0.9261 - loss: 0.2334 1175/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 342us/step - accuracy: 0.9261 - loss: 0.2334 1322/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 342us/step - accuracy: 0.9260 - loss: 0.2336 1469/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 342us/step - accuracy: 0.9259 - loss: 0.2336 1616/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 342us/step - accuracy: 0.9259 - loss: 0.2336 1763/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 342us/step - accuracy: 0.9258 - loss: 0.2337 1910/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 342us/step - accuracy: 0.9257 - loss: 0.2338 2057/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 342us/step - accuracy: 0.9256 - loss: 0.2339 2205/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 342us/step - accuracy: 0.9255 - loss: 0.2340 2353/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 342us/step - accuracy: 0.9254 - loss: 0.2342 2500/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 342us/step - accuracy: 0.9253 - loss: 0.2344 2647/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 342us/step - accuracy: 0.9252 - loss: 0.2345 2795/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9252 - loss: 0.2346 2941/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 342us/step - accuracy: 0.9251 - loss: 0.2347 3089/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9250 - loss: 0.2348 3236/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9250 - loss: 0.2349 3384/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9249 - loss: 0.2350 3530/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9249 - loss: 0.2351 3676/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9248 - loss: 0.2351 3822/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 342us/step - accuracy: 0.9248 - loss: 0.2351 3969/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 342us/step - accuracy: 0.9248 - loss: 0.2352 4115/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 342us/step - accuracy: 0.9248 - loss: 0.2352 4262/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 342us/step - accuracy: 0.9248 - loss: 0.2352 4408/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 342us/step - accuracy: 0.9248 - loss: 0.2353 4554/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 342us/step - accuracy: 0.9247 - loss: 0.2353 4700/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 342us/step - accuracy: 0.9247 - loss: 0.2353 4848/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 342us/step - accuracy: 0.9247 - loss: 0.2354 4996/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 342us/step - accuracy: 0.9247 - loss: 0.2354 5145/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 341us/step - accuracy: 0.9247 - loss: 0.2354 5292/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 342us/step - accuracy: 0.9246 - loss: 0.2355 5437/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 342us/step - accuracy: 0.9246 - loss: 0.2355 5583/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 342us/step - accuracy: 0.9246 - loss: 0.2355 5730/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 342us/step - accuracy: 0.9246 - loss: 0.2356 5877/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 342us/step - accuracy: 0.9246 - loss: 0.2356 6025/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 342us/step - accuracy: 0.9246 - loss: 0.2356 6171/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 342us/step - accuracy: 0.9245 - loss: 0.2356 6317/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 342us/step - accuracy: 0.9245 - loss: 0.2356 6463/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 342us/step - accuracy: 0.9245 - loss: 0.2357 6610/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 342us/step - accuracy: 0.9245 - loss: 0.2357 6757/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 342us/step - accuracy: 0.9245 - loss: 0.2357 6904/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 342us/step - accuracy: 0.9245 - loss: 0.2357 7050/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 342us/step - accuracy: 0.9245 - loss: 0.2357 7196/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 342us/step - accuracy: 0.9245 - loss: 0.2358 7342/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 342us/step - accuracy: 0.9245 - loss: 0.2358 7488/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 342us/step - accuracy: 0.9244 - loss: 0.2358 7635/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 342us/step - accuracy: 0.9244 - loss: 0.2358 7783/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 342us/step - accuracy: 0.9244 - loss: 0.2358 7929/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 342us/step - accuracy: 0.9244 - loss: 0.2358 8076/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 342us/step - accuracy: 0.9244 - loss: 0.2359 8220/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 342us/step - accuracy: 0.9244 - loss: 0.2359 8367/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 342us/step - accuracy: 0.9244 - loss: 0.2359 8514/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 342us/step - accuracy: 0.9244 - loss: 0.2359 8661/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 342us/step - accuracy: 0.9244 - loss: 0.2359 8808/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 342us/step - accuracy: 0.9244 - loss: 0.2359 8955/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 342us/step - accuracy: 0.9244 - loss: 0.2359 9103/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 342us/step - accuracy: 0.9244 - loss: 0.2360 9249/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 342us/step - accuracy: 0.9244 - loss: 0.2360 9395/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 342us/step - accuracy: 0.9243 - loss: 0.2360 9542/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 342us/step - accuracy: 0.9243 - loss: 0.2360 9690/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 342us/step - accuracy: 0.9243 - loss: 0.2360 9836/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 342us/step - accuracy: 0.9243 - loss: 0.2361 9981/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 342us/step - accuracy: 0.9243 - loss: 0.2361 10128/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 342us/step - accuracy: 0.9243 - loss: 0.2361 10274/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 342us/step - accuracy: 0.9243 - loss: 0.2361 10421/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 342us/step - accuracy: 0.9243 - loss: 0.2362 10567/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9243 - loss: 0.2362 10714/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9243 - loss: 0.2362 10861/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9243 - loss: 0.2362 11009/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9242 - loss: 0.2362 11157/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9242 - loss: 0.2363 11304/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9242 - loss: 0.2363 11450/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9242 - loss: 0.2363 11595/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9242 - loss: 0.2363 11741/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9242 - loss: 0.2363 11888/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9242 - loss: 0.2363 12035/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9242 - loss: 0.2364 12182/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9242 - loss: 0.2364 12329/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9242 - loss: 0.2364 12477/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9242 - loss: 0.2364 12624/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9242 - loss: 0.2364 12770/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9242 - loss: 0.2364 12917/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9242 - loss: 0.2364 13064/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9242 - loss: 0.2364 13210/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9241 - loss: 0.2365 13357/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9241 - loss: 0.2365 13502/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9241 - loss: 0.2365 13649/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9241 - loss: 0.2365 13796/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9241 - loss: 0.2365 13943/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9241 - loss: 0.2365 14090/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9241 - loss: 0.2365 14236/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9241 - loss: 0.2365 14382/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9241 - loss: 0.2365 14529/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9241 - loss: 0.2365 14676/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9241 - loss: 0.2365 14824/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9241 - loss: 0.2365 14971/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9241 - loss: 0.2366 15118/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9241 - loss: 0.2366 15263/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9241 - loss: 0.2366 15411/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9241 - loss: 0.2366 15557/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9241 - loss: 0.2366 15704/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9241 - loss: 0.2366 15852/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9241 - loss: 0.2366 15999/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9241 - loss: 0.2366 16145/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9241 - loss: 0.2366 16292/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 342us/step - accuracy: 0.9241 - loss: 0.2366 16438/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9241 - loss: 0.2366 16585/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9241 - loss: 0.2366 16731/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9241 - loss: 0.2366 16877/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9241 - loss: 0.2366 17022/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9241 - loss: 0.2366 17169/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9241 - loss: 0.2367 17315/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9241 - loss: 0.2367 17462/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9241 - loss: 0.2367 17608/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9241 - loss: 0.2367 17755/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9241 - loss: 0.2367 17902/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9241 - loss: 0.2367 18048/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9241 - loss: 0.2367 18194/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9241 - loss: 0.2367 18341/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9241 - loss: 0.2367 18487/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9241 - loss: 0.2367 18634/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9241 - loss: 0.2367 18779/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9241 - loss: 0.2367 18926/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9241 - loss: 0.2367 19072/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9241 - loss: 0.2367 19219/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 342us/step - accuracy: 0.9241 - loss: 0.2367 19366/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9241 - loss: 0.2367 19512/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9241 - loss: 0.2367 19660/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9241 - loss: 0.2367 19807/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9241 - loss: 0.2367 19950/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9241 - loss: 0.2367 20095/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9241 - loss: 0.2367 20242/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9241 - loss: 0.2367 20390/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9241 - loss: 0.2367 20536/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9241 - loss: 0.2367 20683/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9241 - loss: 0.2367 20830/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9241 - loss: 0.2367 20977/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9241 - loss: 0.2367 21124/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9241 - loss: 0.2367 21271/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9241 - loss: 0.2367 21417/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9241 - loss: 0.2367 21564/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9241 - loss: 0.2367 21711/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9241 - loss: 0.2367 21858/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9241 - loss: 0.2367 22005/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9241 - loss: 0.2367 22152/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 342us/step - accuracy: 0.9241 - loss: 0.2367 22185/22185 ━━━━━━━━━━━━━━━━━━━━ 9s 406us/step - accuracy: 0.9241 - loss: 0.2367 - val_accuracy: 0.9240 - val_loss: 0.2374 Epoch 3/5 1/22185 ━━━━━━━━━━━━━━━━━━━━ 2:22 6ms/step - accuracy: 0.9062 - loss: 0.2768 147/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 344us/step - accuracy: 0.9171 - loss: 0.2543 293/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 343us/step - accuracy: 0.9204 - loss: 0.2466 440/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 343us/step - accuracy: 0.9216 - loss: 0.2440 586/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 343us/step - accuracy: 0.9223 - loss: 0.2422 733/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 343us/step - accuracy: 0.9231 - loss: 0.2404 878/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 343us/step - accuracy: 0.9236 - loss: 0.2395 1025/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 343us/step - accuracy: 0.9238 - loss: 0.2391 1169/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 343us/step - accuracy: 0.9240 - loss: 0.2388 1313/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 344us/step - accuracy: 0.9241 - loss: 0.2386 1458/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 344us/step - accuracy: 0.9241 - loss: 0.2385 1606/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 344us/step - accuracy: 0.9241 - loss: 0.2385 1751/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 344us/step - accuracy: 0.9241 - loss: 0.2383 1897/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9242 - loss: 0.2382 2045/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9242 - loss: 0.2382 2191/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9241 - loss: 0.2381 2337/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9241 - loss: 0.2381 2483/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9241 - loss: 0.2380 2630/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 343us/step - accuracy: 0.9240 - loss: 0.2380 2778/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 343us/step - accuracy: 0.9240 - loss: 0.2379 2923/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 343us/step - accuracy: 0.9240 - loss: 0.2379 3067/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9240 - loss: 0.2378 3214/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9240 - loss: 0.2377 3361/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 343us/step - accuracy: 0.9240 - loss: 0.2377 3508/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 343us/step - accuracy: 0.9240 - loss: 0.2376 3652/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9240 - loss: 0.2375 3799/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 343us/step - accuracy: 0.9240 - loss: 0.2374 3945/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 343us/step - accuracy: 0.9240 - loss: 0.2374 4090/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9240 - loss: 0.2373 4237/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9240 - loss: 0.2372 4380/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9241 - loss: 0.2372 4526/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9241 - loss: 0.2371 4671/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9241 - loss: 0.2371 4815/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 344us/step - accuracy: 0.9241 - loss: 0.2370 4962/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 344us/step - accuracy: 0.9241 - loss: 0.2370 5109/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 344us/step - accuracy: 0.9241 - loss: 0.2370 5256/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 344us/step - accuracy: 0.9241 - loss: 0.2369 5403/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 344us/step - accuracy: 0.9241 - loss: 0.2369 5546/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 344us/step - accuracy: 0.9241 - loss: 0.2369 5693/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 344us/step - accuracy: 0.9241 - loss: 0.2368 5838/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 344us/step - accuracy: 0.9241 - loss: 0.2368 5986/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 344us/step - accuracy: 0.9241 - loss: 0.2368 6136/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9241 - loss: 0.2368 6285/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9241 - loss: 0.2367 6431/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9241 - loss: 0.2367 6579/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9241 - loss: 0.2367 6722/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9241 - loss: 0.2367 6868/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9241 - loss: 0.2367 7014/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9241 - loss: 0.2366 7159/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9241 - loss: 0.2366 7305/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9241 - loss: 0.2366 7452/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9241 - loss: 0.2366 7598/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9241 - loss: 0.2366 7742/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9241 - loss: 0.2365 7888/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9241 - loss: 0.2365 8036/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9241 - loss: 0.2365 8180/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9241 - loss: 0.2365 8326/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9241 - loss: 0.2365 8473/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9240 - loss: 0.2365 8620/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9240 - loss: 0.2365 8767/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9240 - loss: 0.2365 8915/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9240 - loss: 0.2365 9060/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9240 - loss: 0.2365 9207/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9240 - loss: 0.2365 9353/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9240 - loss: 0.2365 9497/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9240 - loss: 0.2366 9644/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9240 - loss: 0.2366 9790/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9240 - loss: 0.2366 9935/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9240 - loss: 0.2366 10080/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9240 - loss: 0.2366 10227/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9240 - loss: 0.2366 10373/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9240 - loss: 0.2366 10518/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9240 - loss: 0.2366 10662/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9240 - loss: 0.2366 10808/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9240 - loss: 0.2366 10955/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9240 - loss: 0.2366 11102/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9240 - loss: 0.2366 11248/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9240 - loss: 0.2366 11396/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9240 - loss: 0.2367 11540/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9240 - loss: 0.2367 11686/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9240 - loss: 0.2367 11834/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9240 - loss: 0.2367 11981/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9240 - loss: 0.2367 12126/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9240 - loss: 0.2367 12273/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9239 - loss: 0.2367 12417/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9239 - loss: 0.2367 12560/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9239 - loss: 0.2367 12706/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9239 - loss: 0.2367 12852/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9239 - loss: 0.2368 12996/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 344us/step - accuracy: 0.9239 - loss: 0.2368 13141/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 344us/step - accuracy: 0.9239 - loss: 0.2368 13286/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 344us/step - accuracy: 0.9239 - loss: 0.2368 13431/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 344us/step - accuracy: 0.9239 - loss: 0.2368 13577/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9239 - loss: 0.2368 13720/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9239 - loss: 0.2368 13867/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9239 - loss: 0.2368 14014/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9239 - loss: 0.2368 14159/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9239 - loss: 0.2368 14306/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9239 - loss: 0.2368 14453/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9239 - loss: 0.2368 14598/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9239 - loss: 0.2368 14743/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9239 - loss: 0.2368 14890/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9239 - loss: 0.2368 15037/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9239 - loss: 0.2368 15182/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9239 - loss: 0.2368 15329/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9239 - loss: 0.2368 15476/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9239 - loss: 0.2368 15623/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9239 - loss: 0.2368 15768/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9239 - loss: 0.2368 15915/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9239 - loss: 0.2369 16057/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9239 - loss: 0.2369 16202/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9239 - loss: 0.2369 16349/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9239 - loss: 0.2369 16493/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9239 - loss: 0.2369 16636/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9239 - loss: 0.2369 16780/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9239 - loss: 0.2369 16922/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9239 - loss: 0.2369 17064/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9239 - loss: 0.2369 17208/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9239 - loss: 0.2369 17350/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9239 - loss: 0.2369 17492/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9239 - loss: 0.2369 17635/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9239 - loss: 0.2369 17778/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9239 - loss: 0.2369 17922/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9239 - loss: 0.2369 18064/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9239 - loss: 0.2369 18204/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9239 - loss: 0.2369 18344/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 345us/step - accuracy: 0.9239 - loss: 0.2369 18487/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 345us/step - accuracy: 0.9239 - loss: 0.2369 18629/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 345us/step - accuracy: 0.9239 - loss: 0.2369 18772/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 345us/step - accuracy: 0.9239 - loss: 0.2369 18917/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 345us/step - accuracy: 0.9239 - loss: 0.2369 19064/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 345us/step - accuracy: 0.9239 - loss: 0.2369 19208/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 345us/step - accuracy: 0.9239 - loss: 0.2369 19349/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 345us/step - accuracy: 0.9239 - loss: 0.2369 19495/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 345us/step - accuracy: 0.9239 - loss: 0.2369 19641/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 345us/step - accuracy: 0.9239 - loss: 0.2369 19787/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 345us/step - accuracy: 0.9239 - loss: 0.2369 19931/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 345us/step - accuracy: 0.9239 - loss: 0.2369 20077/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 345us/step - accuracy: 0.9239 - loss: 0.2369 20221/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 345us/step - accuracy: 0.9239 - loss: 0.2369 20362/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 345us/step - accuracy: 0.9239 - loss: 0.2369 20505/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 345us/step - accuracy: 0.9239 - loss: 0.2369 20650/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 345us/step - accuracy: 0.9239 - loss: 0.2369 20793/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 345us/step - accuracy: 0.9239 - loss: 0.2369 20936/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 345us/step - accuracy: 0.9239 - loss: 0.2369 21080/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 345us/step - accuracy: 0.9239 - loss: 0.2369 21225/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 345us/step - accuracy: 0.9239 - loss: 0.2369 21371/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 345us/step - accuracy: 0.9239 - loss: 0.2369 21517/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 345us/step - accuracy: 0.9239 - loss: 0.2370 21658/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 345us/step - accuracy: 0.9239 - loss: 0.2370 21803/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 345us/step - accuracy: 0.9239 - loss: 0.2370 21948/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 345us/step - accuracy: 0.9239 - loss: 0.2370 22089/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 345us/step - accuracy: 0.9239 - loss: 0.2370 22185/22185 ━━━━━━━━━━━━━━━━━━━━ 9s 409us/step - accuracy: 0.9239 - loss: 0.2370 - val_accuracy: 0.9240 - val_loss: 0.2385 Epoch 4/5 1/22185 ━━━━━━━━━━━━━━━━━━━━ 2:25 7ms/step - accuracy: 0.9688 - loss: 0.1070 145/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 348us/step - accuracy: 0.9262 - loss: 0.2377 289/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 348us/step - accuracy: 0.9253 - loss: 0.2395 436/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 345us/step - accuracy: 0.9251 - loss: 0.2392 582/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 345us/step - accuracy: 0.9250 - loss: 0.2389 728/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 345us/step - accuracy: 0.9251 - loss: 0.2382 874/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 345us/step - accuracy: 0.9251 - loss: 0.2378 1021/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 344us/step - accuracy: 0.9251 - loss: 0.2379 1168/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 344us/step - accuracy: 0.9251 - loss: 0.2378 1314/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 344us/step - accuracy: 0.9251 - loss: 0.2378 1461/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 344us/step - accuracy: 0.9250 - loss: 0.2377 1607/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 344us/step - accuracy: 0.9250 - loss: 0.2376 1753/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 344us/step - accuracy: 0.9249 - loss: 0.2376 1898/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9249 - loss: 0.2377 2044/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9248 - loss: 0.2378 2190/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9248 - loss: 0.2379 2336/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9247 - loss: 0.2380 2483/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9247 - loss: 0.2380 2628/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9246 - loss: 0.2380 2774/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9246 - loss: 0.2381 2920/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9245 - loss: 0.2381 3066/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9245 - loss: 0.2381 3212/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9245 - loss: 0.2380 3358/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9244 - loss: 0.2380 3505/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9244 - loss: 0.2380 3652/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 344us/step - accuracy: 0.9244 - loss: 0.2380 3799/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 343us/step - accuracy: 0.9244 - loss: 0.2380 3946/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 343us/step - accuracy: 0.9244 - loss: 0.2379 4092/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 343us/step - accuracy: 0.9244 - loss: 0.2379 4239/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 343us/step - accuracy: 0.9244 - loss: 0.2379 4385/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 343us/step - accuracy: 0.9244 - loss: 0.2378 4531/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 343us/step - accuracy: 0.9244 - loss: 0.2378 4677/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 343us/step - accuracy: 0.9244 - loss: 0.2377 4824/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9244 - loss: 0.2377 4970/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9244 - loss: 0.2377 5117/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9244 - loss: 0.2377 5264/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9243 - loss: 0.2376 5410/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9243 - loss: 0.2376 5557/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9243 - loss: 0.2376 5703/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9243 - loss: 0.2376 5850/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9243 - loss: 0.2376 5998/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9243 - loss: 0.2376 6144/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9243 - loss: 0.2376 6291/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9243 - loss: 0.2376 6438/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9243 - loss: 0.2376 6586/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9243 - loss: 0.2375 6731/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9243 - loss: 0.2375 6878/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9243 - loss: 0.2375 7024/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9243 - loss: 0.2375 7171/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9242 - loss: 0.2375 7319/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9242 - loss: 0.2374 7464/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9242 - loss: 0.2374 7611/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9242 - loss: 0.2374 7757/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9242 - loss: 0.2374 7903/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9242 - loss: 0.2374 8049/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9242 - loss: 0.2374 8196/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9242 - loss: 0.2374 8343/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9242 - loss: 0.2374 8489/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9242 - loss: 0.2374 8637/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9242 - loss: 0.2373 8785/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9242 - loss: 0.2373 8931/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9242 - loss: 0.2373 9077/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9242 - loss: 0.2373 9223/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9241 - loss: 0.2373 9370/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9241 - loss: 0.2373 9517/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9241 - loss: 0.2373 9664/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9241 - loss: 0.2373 9812/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9241 - loss: 0.2373 9960/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9241 - loss: 0.2373 10106/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9241 - loss: 0.2373 10252/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9241 - loss: 0.2373 10398/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 343us/step - accuracy: 0.9241 - loss: 0.2373 10545/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9241 - loss: 0.2373 10693/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9241 - loss: 0.2373 10841/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9241 - loss: 0.2373 10988/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9241 - loss: 0.2373 11136/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9241 - loss: 0.2373 11281/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9241 - loss: 0.2373 11426/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9241 - loss: 0.2373 11573/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9241 - loss: 0.2373 11719/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9240 - loss: 0.2373 11866/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9240 - loss: 0.2373 12012/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9240 - loss: 0.2373 12158/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9240 - loss: 0.2373 12305/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9240 - loss: 0.2373 12452/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9240 - loss: 0.2373 12598/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 342us/step - accuracy: 0.9240 - loss: 0.2373 12744/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9240 - loss: 0.2373 12889/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9240 - loss: 0.2373 13035/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9240 - loss: 0.2373 13180/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9240 - loss: 0.2373 13325/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 343us/step - accuracy: 0.9240 - loss: 0.2373 13471/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 343us/step - accuracy: 0.9240 - loss: 0.2373 13607/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 343us/step - accuracy: 0.9240 - loss: 0.2373 13720/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9240 - loss: 0.2373 13853/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9240 - loss: 0.2373 13996/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9240 - loss: 0.2373 14139/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9240 - loss: 0.2373 14284/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9240 - loss: 0.2373 14429/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9240 - loss: 0.2373 14575/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9240 - loss: 0.2373 14720/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9240 - loss: 0.2373 14864/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9240 - loss: 0.2373 15009/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9240 - loss: 0.2373 15156/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9240 - loss: 0.2373 15303/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9240 - loss: 0.2373 15450/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9240 - loss: 0.2373 15596/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9240 - loss: 0.2373 15742/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9240 - loss: 0.2373 15888/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9240 - loss: 0.2373 16035/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9240 - loss: 0.2373 16182/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9240 - loss: 0.2373 16330/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9240 - loss: 0.2373 16476/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2373 16621/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2373 16769/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2373 16915/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2373 17060/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2373 17207/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2373 17355/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2373 17502/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2373 17649/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2373 17797/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2373 17945/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2373 18093/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2373 18241/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2372 18385/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2372 18530/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2372 18676/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2372 18821/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2372 18967/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2372 19114/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2372 19261/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2372 19409/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2372 19557/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2372 19705/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2372 19852/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2372 20000/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2372 20147/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2372 20295/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2372 20442/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2372 20589/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2372 20735/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2372 20880/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2372 21026/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2372 21173/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2372 21319/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2372 21465/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2372 21612/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2372 21758/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2372 21904/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2372 22052/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2372 22185/22185 ━━━━━━━━━━━━━━━━━━━━ 9s 410us/step - accuracy: 0.9240 - loss: 0.2372 - val_accuracy: 0.9239 - val_loss: 0.2416 Epoch 5/5 1/22185 ━━━━━━━━━━━━━━━━━━━━ 2:34 7ms/step - accuracy: 0.9062 - loss: 0.2438 145/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 349us/step - accuracy: 0.9278 - loss: 0.2241 291/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 346us/step - accuracy: 0.9270 - loss: 0.2275 437/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 345us/step - accuracy: 0.9266 - loss: 0.2292 584/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 344us/step - accuracy: 0.9264 - loss: 0.2298 732/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 343us/step - accuracy: 0.9263 - loss: 0.2303 879/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 343us/step - accuracy: 0.9261 - loss: 0.2309 1027/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 342us/step - accuracy: 0.9260 - loss: 0.2317 1175/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 342us/step - accuracy: 0.9258 - loss: 0.2322 1321/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 342us/step - accuracy: 0.9257 - loss: 0.2327 1470/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 341us/step - accuracy: 0.9256 - loss: 0.2330 1618/22185 ━━━━━━━━━━━━━━━━━━━━ 7s 341us/step - accuracy: 0.9255 - loss: 0.2333 1765/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9254 - loss: 0.2336 1913/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9253 - loss: 0.2339 2059/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9251 - loss: 0.2342 2206/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9250 - loss: 0.2344 2354/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9249 - loss: 0.2347 2500/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9248 - loss: 0.2348 2646/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9248 - loss: 0.2350 2793/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9247 - loss: 0.2350 2939/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9247 - loss: 0.2351 3086/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9246 - loss: 0.2352 3233/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9246 - loss: 0.2353 3381/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9245 - loss: 0.2353 3528/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9245 - loss: 0.2354 3675/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9245 - loss: 0.2354 3820/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9245 - loss: 0.2354 3967/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9245 - loss: 0.2354 4114/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9245 - loss: 0.2354 4262/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9245 - loss: 0.2354 4410/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 341us/step - accuracy: 0.9245 - loss: 0.2354 4543/22185 ━━━━━━━━━━━━━━━━━━━━ 6s 342us/step - accuracy: 0.9245 - loss: 0.2354 4690/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 342us/step - accuracy: 0.9245 - loss: 0.2355 4837/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 342us/step - accuracy: 0.9245 - loss: 0.2355 4979/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9245 - loss: 0.2355 5126/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9245 - loss: 0.2355 5272/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9245 - loss: 0.2356 5414/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9244 - loss: 0.2356 5561/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9244 - loss: 0.2356 5708/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9244 - loss: 0.2357 5855/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 343us/step - accuracy: 0.9244 - loss: 0.2357 5941/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 346us/step - accuracy: 0.9244 - loss: 0.2357 6084/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 346us/step - accuracy: 0.9244 - loss: 0.2357 6230/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 346us/step - accuracy: 0.9244 - loss: 0.2358 6377/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 346us/step - accuracy: 0.9244 - loss: 0.2358 6523/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 346us/step - accuracy: 0.9243 - loss: 0.2358 6670/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 346us/step - accuracy: 0.9243 - loss: 0.2358 6814/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 346us/step - accuracy: 0.9243 - loss: 0.2358 6960/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 346us/step - accuracy: 0.9243 - loss: 0.2359 7106/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 346us/step - accuracy: 0.9243 - loss: 0.2359 7254/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 346us/step - accuracy: 0.9243 - loss: 0.2359 7401/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 346us/step - accuracy: 0.9243 - loss: 0.2359 7547/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 346us/step - accuracy: 0.9243 - loss: 0.2359 7693/22185 ━━━━━━━━━━━━━━━━━━━━ 5s 346us/step - accuracy: 0.9243 - loss: 0.2359 7840/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 346us/step - accuracy: 0.9243 - loss: 0.2359 7988/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 346us/step - accuracy: 0.9243 - loss: 0.2359 8135/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 345us/step - accuracy: 0.9243 - loss: 0.2359 8282/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 345us/step - accuracy: 0.9243 - loss: 0.2360 8430/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 345us/step - accuracy: 0.9243 - loss: 0.2360 8576/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 345us/step - accuracy: 0.9243 - loss: 0.2360 8722/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 345us/step - accuracy: 0.9243 - loss: 0.2360 8868/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 345us/step - accuracy: 0.9243 - loss: 0.2360 9015/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 345us/step - accuracy: 0.9243 - loss: 0.2361 9162/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 345us/step - accuracy: 0.9242 - loss: 0.2361 9310/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 345us/step - accuracy: 0.9242 - loss: 0.2361 9458/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 345us/step - accuracy: 0.9242 - loss: 0.2361 9605/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 345us/step - accuracy: 0.9242 - loss: 0.2361 9753/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 345us/step - accuracy: 0.9242 - loss: 0.2361 9900/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 345us/step - accuracy: 0.9242 - loss: 0.2361 10047/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 345us/step - accuracy: 0.9242 - loss: 0.2361 10193/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 345us/step - accuracy: 0.9242 - loss: 0.2362 10340/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 345us/step - accuracy: 0.9242 - loss: 0.2362 10488/22185 ━━━━━━━━━━━━━━━━━━━━ 4s 345us/step - accuracy: 0.9242 - loss: 0.2362 10634/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 345us/step - accuracy: 0.9242 - loss: 0.2362 10780/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 345us/step - accuracy: 0.9242 - loss: 0.2362 10926/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 345us/step - accuracy: 0.9242 - loss: 0.2362 11073/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 344us/step - accuracy: 0.9242 - loss: 0.2362 11218/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 344us/step - accuracy: 0.9242 - loss: 0.2362 11364/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 344us/step - accuracy: 0.9242 - loss: 0.2363 11510/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 344us/step - accuracy: 0.9242 - loss: 0.2363 11657/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 344us/step - accuracy: 0.9241 - loss: 0.2363 11804/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 344us/step - accuracy: 0.9241 - loss: 0.2363 11950/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 344us/step - accuracy: 0.9241 - loss: 0.2363 12097/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 344us/step - accuracy: 0.9241 - loss: 0.2363 12243/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 344us/step - accuracy: 0.9241 - loss: 0.2363 12389/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 344us/step - accuracy: 0.9241 - loss: 0.2364 12536/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 344us/step - accuracy: 0.9241 - loss: 0.2364 12684/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 344us/step - accuracy: 0.9241 - loss: 0.2364 12832/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 344us/step - accuracy: 0.9241 - loss: 0.2364 12980/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 344us/step - accuracy: 0.9241 - loss: 0.2364 13127/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 344us/step - accuracy: 0.9241 - loss: 0.2364 13275/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 344us/step - accuracy: 0.9241 - loss: 0.2364 13424/22185 ━━━━━━━━━━━━━━━━━━━━ 3s 344us/step - accuracy: 0.9241 - loss: 0.2364 13571/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9241 - loss: 0.2364 13718/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9241 - loss: 0.2364 13865/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9241 - loss: 0.2364 14013/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9241 - loss: 0.2365 14160/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9241 - loss: 0.2365 14307/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9241 - loss: 0.2365 14454/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9241 - loss: 0.2365 14602/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9241 - loss: 0.2365 14749/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9241 - loss: 0.2365 14895/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9241 - loss: 0.2365 15041/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9241 - loss: 0.2365 15187/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9241 - loss: 0.2365 15334/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9241 - loss: 0.2365 15482/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9241 - loss: 0.2365 15628/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9241 - loss: 0.2365 15774/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9241 - loss: 0.2365 15922/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9241 - loss: 0.2365 16063/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9240 - loss: 0.2365 16208/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9240 - loss: 0.2365 16353/22185 ━━━━━━━━━━━━━━━━━━━━ 2s 344us/step - accuracy: 0.9240 - loss: 0.2365 16495/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2365 16640/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2365 16787/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2365 16935/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2365 17082/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2365 17229/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2365 17376/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2366 17523/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2366 17669/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2366 17813/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2366 17959/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2366 18106/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2366 18253/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2366 18400/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2366 18546/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2366 18691/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2366 18836/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2366 18983/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2366 19129/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2366 19275/22185 ━━━━━━━━━━━━━━━━━━━━ 1s 344us/step - accuracy: 0.9240 - loss: 0.2366 19422/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2367 19569/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2367 19715/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2367 19860/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2367 20005/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2367 20152/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2367 20298/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2367 20445/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2367 20593/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2367 20739/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2367 20885/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2367 21031/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2367 21177/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2368 21323/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2368 21469/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2368 21616/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2368 21760/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2368 21906/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2368 22053/22185 ━━━━━━━━━━━━━━━━━━━━ 0s 344us/step - accuracy: 0.9240 - loss: 0.2368 22185/22185 ━━━━━━━━━━━━━━━━━━━━ 9s 408us/step - accuracy: 0.9240 - loss: 0.2368 - val_accuracy: 0.9240 - val_loss: 0.2374
Architecture of the Neural Network
from IPython.display import clear_output, Image, display, HTML
def strip_consts(graph_def, max_const_size=32):
"""Strip large constant values from graph_def."""
strip_def = tf.GraphDef()
for n0 in graph_def.node:
n = strip_def.node.add()
n.MergeFrom(n0)
if n.op == 'Const':
tensor = n.attr['value'].tensor
size = len(tensor.tensor_content)
if size > max_const_size:
tensor.tensor_content = "<stripped %d bytes>"%size
return strip_def
def show_graph(graph_def, max_const_size=32):
"""Visualize TensorFlow graph."""
if hasattr(graph_def, 'as_graph_def'):
graph_def = graph_def.as_graph_def()
strip_def = strip_consts(graph_def, max_const_size=max_const_size)
code = """
<script>
function load() {{
document.getElementById("{id}").pbtxt = {data};
}}
</script>
<link rel="import" href="https://tensorboard.appspot.com/tf-graph-basic.build.html" onload=load()>
<div style="height:600px">
<tf-graph-basic id="{id}"></tf-graph-basic>
</div>
""".format(data=repr(str(strip_def)), id='graph'+str(np.random.rand()))
iframe = """
<iframe seamless style="width:1200px;height:620px;border:0" srcdoc="{}"></iframe>
""".format(code.replace('"', '"'))
display(HTML(iframe))