<jupyter_start><jupyter_text>Import Data<jupyter_code>#Import cleaned csv file
data = pd.read_csv("output.csv")
data.columns
#Select only relevant columns
model_data = data[[
    'EMI', 
    'Loan Amount', 
    'Maximum amount sanctioned for any Two wheeler loan',
    'Age at which customer has taken the loan', 
    'Rate of Interest', 
    'Number of times 30 days past due in last 6 months', 
    'Maximum MOB (Month of business with TVS Credit)', 
    'Number of times 60 days past due in last 6 months', 
    'Number of loans', 
    'Maximum amount sanctioned in the Live loans', 
    'Number of times 90 days past due in last 3 months', 
    'Tenure', 
    'Number of times bounced while repaying the loan',
    'Target variable ( 1: Defaulters / 0: Non-Defaulters)'
]]

#Rename Dependent Variable Column to "Class"
model_data = model_data.rename(columns={"Target variable ( 1: Defaulters / 0: Non-Defaulters)": "Class"})
model_data.head()<jupyter_output><empty_output><jupyter_text>Train the Model<jupyter_code># Assign X (data) and y (target)
X = model_data.drop('Class', axis=1)
y = model_data['Class']
print(f"X Shape: {X.shape}")
print(f"y Shape: {y.shape}")
#Train Test Split
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, train_size=0.8, random_state=10)<jupyter_output><empty_output><jupyter_text>Resample Data using Oversampling Technique<jupyter_code># concatenate our training data back together
X = pd.concat([X_train, y_train], axis=1)

# separate minority and majority classes
not_defaulted = X[X.Class==0]
defaulted = X[X.Class==1]

print(not_defaulted.Class.value_counts())
print(defaulted.Class.value_counts())
from sklearn.utils import resample
# upsample minority
defaulted_upsampled = resample(defaulted,
                               replace=True,
                               n_samples=len(not_defaulted),
                               random_state=27)
# combine majority and upsampled minority
upsampled = pd.concat([not_defaulted, defaulted_upsampled])
upsampled.Class.value_counts()
#redefine the X and y training samples
y_train = upsampled.Class
X_train = upsampled.drop('Class', axis=1)
#Define the classifier as a logistic regression model
from sklearn.linear_model import LogisticRegression
classifier = LogisticRegression(C=0.004291934260128779, class_weight=None, dual=False,
                   fit_intercept=True, intercept_scaling=1, l1_ratio=None,
                   max_iter=5000, multi_class='auto', n_jobs=None, penalty='l1',
                   random_state=None, solver='liblinear', tol=0.0001, verbose=0,
                   warm_start=False)
classifier

#fit the training samples in the classifier
classifier.fit(X_train, y_train)
print(f"Training Data Score: {classifier.score(X_train, y_train)}")
print(f"Testing Data Score: {classifier.score(X_test, y_test)}")<jupyter_output>Training Data Score: 0.7754439979822226
Testing Data Score: 0.8417760250220984<jupyter_text>Assessment<jupyter_code>#Compare with test data
predictions = classifier.predict(X_test)

print(sum(predictions), sum(y_test))

total = 0
default_num = 0

for i in range(len(predictions)):
    if(predictions[i] == y_test.array[i]):
        total +=1
        if(predictions[i]==1):
            default_num+=1
print("-------" * 2)            
print(default_num, sum(y_test))
print("-------" * 2)
print(total/len(predictions))<jupyter_output>2450 292
--------------
205 292
--------------
0.8414360508601346<jupyter_text>Grid Search<jupyter_code>#Import Grid Search
from sklearn.model_selection import GridSearchCV

#Define param_grid
param_grid = [    
    {'penalty' : ['l1'],
    'C': np.logspace(-4, 4),
    'solver': ['newton-cg','liblinear'],
    'max_iter': [5000]
    }
]

#define clf
clf = GridSearchCV(classifier, param_grid = param_grid, cv = 3, verbose=True, n_jobs=-1)


best_clf = clf.fit(X_train, y_train)
best_clf.best_estimator_
import joblib
filename = 'logistic_regression_oversample.sav'
joblib.dump(clf, filename)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12136878385032004, 'fraction_numerical': 0.033973412112259974, 'mean_word_length': 4.202304737516005, 'pattern_counts': {'":': 1, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '594326', 'license': 'MIT', 'n_tokens_mistral': 1482, 'n_tokens_neox': 1346, 'n_words': 335, 'path': 'logistic_regression_oversampling.ipynb', 'repo_name': 'Gendo90/TVS-default-risk', 'size': '4062'}