<jupyter_start><jupyter_text>EDA<jupyter_code>data.head()
sns.countplot(x = data['stroke'])
sns.pairplot(data)
sns.heatmap(data.corr())
data.describe()
data.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 5110 entries, 0 to 5109
Data columns (total 11 columns):
 #   Column             Non-Null Count  Dtype  
---  ------             --------------  -----  
 0   gender             5110 non-null   object 
 1   age                5110 non-null   float64
 2   hypertension       5110 non-null   int64  
 3   heart_disease      5110 non-null   int64  
 4   ever_married       5110 non-null   object 
 5   work_type          5110 non-null   object 
 6   Residence_type     5110 non-null   object 
 7   avg_glucose_level  5110 non-null   float64
 8   bmi                4909 non-null   float64
 9   smoking_status     5110 non-null   object 
 10  stroke             5110 non-null   int64  
dtypes: float64(3), int64(3), object(5)
memory usage: 439.3+ KB<jupyter_text>BMI data is missing.  Feature Engeeniering<jupyter_code>X = data.drop("stroke", axis="columns")
y = data["stroke"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.2, stratify=y, random_state=123)
def evaluate_model(model: BaseEstimator, X_test = X_test, y_test = y_test, transform = None):
    if transform is None:
        print("Accuracy: "  + str(accuracy_score(y_test, model.predict(X_test))))
        print("F1 score: "  + str(f1_score(y_test, model.predict(X_test))))
        print("Recall score: "  + str(recall_score(y_test, model.predict(X_test))))
    else:
        print("Accuracy: "  + str(accuracy_score(y_test, model.predict(transform.transform(X_test)))))
        print("F1 score: "  + str(f1_score(y_test, model.predict(transform.transform(X_test)))))
        print("Recall score: "  + str(recall_score(y_test, model.predict(transform.transform(X_test)))))


column_transform = ColumnTransformer([
        ('imputer', SimpleImputer(strategy = "most_frequent", add_indicator=True), ['bmi']),
        ('OHEncoder', OneHotEncoder(handle_unknown='ignore'), ['gender', 'ever_married', 'work_type', 'Residence_type', 'smoking_status'])
    ],
    remainder='passthrough')
column_transform.fit(X_train)
poly_f = PolynomialFeatures()

poly_f.fit(
    column_transform.transform(X_train))<jupyter_output><empty_output><jupyter_text>First models  Linear Regression<jupyter_code>lin_reg = make_pipeline(
    column_transform,
    poly_f,
    LogisticRegression(max_iter=10000, random_state=123))
lin_reg.fit(X_train, y_train)


evaluate_model(lin_reg)<jupyter_output>Accuracy: 0.9510763209393346
F1 score: 0.038461538461538464
Recall score: 0.02<jupyter_text>Linear Regression with weights<jupyter_code>lin_reg = make_pipeline(
    column_transform,
    poly_f,
    LogisticRegression(max_iter=10000, random_state=123, class_weight='balanced'))
lin_reg.fit(X_train, y_train)


evaluate_model(lin_reg)<jupyter_output>Accuracy: 0.7622309197651663
F1 score: 0.23343848580441642
Recall score: 0.74<jupyter_text>Random Forest<jupyter_code>rf_pipe = make_pipeline(
    column_transform,
    poly_f,
    RandomForestClassifier(random_state=123))

rf_pipe.fit(X_train, y_train)


evaluate_model(rf_pipe)<jupyter_output>Accuracy: 0.9510763209393346
F1 score: 0.038461538461538464
Recall score: 0.02<jupyter_text>Under samplinghttps://www.analyticsvidhya.com/blog/2020/07/10-techniques-to-deal-with-class-imbalance-in-machine-learning/<jupyter_code>rus = RandomUnderSampler(random_state=42, replacement=True)# fit predictor and target variable
X_rus, y_rus = rus.fit_resample(X_train, y_train)
lin_reg_rus = make_pipeline(
    column_transform,
    LogisticRegression(max_iter=1000, random_state=123))
lin_reg_rus.fit(X_rus, y_rus)


evaluate_model(lin_reg_rus)
rf_pipe_rus = make_pipeline(
    column_transform,
    RandomForestClassifier(random_state=123))

rf_pipe_rus.fit(X_rus, y_rus)


evaluate_model(rf_pipe_rus)<jupyter_output>Accuracy: 0.7113502935420744
F1 score: 0.20485175202156336
Recall score: 0.76<jupyter_text>Over sampling<jupyter_code>ros = RandomOverSampler(random_state=42, sampling_strategy=0.5)

X_ros, y_ros = ros.fit_resample(X_train, y_train)
lin_reg_ros = make_pipeline(
    column_transform,
    LogisticRegression(max_iter=1000, random_state=123))
lin_reg_ros.fit(X_ros, y_ros)

evaluate_model(lin_reg_ros)
rf_pipe_ros = make_pipeline(
    column_transform,
    RandomForestClassifier(random_state=123))

rf_pipe_ros.fit(X_ros, y_ros)


evaluate_model(rf_pipe_ros)<jupyter_output>Accuracy: 0.9481409001956947
F1 score: 0.07017543859649124
Recall score: 0.04<jupyter_text>SMOT<jupyter_code>smote = SMOTE()

X_smote, y_smote = smote.fit_resample(column_transform.transform(X_train), y_train)
lin_reg_smote = LogisticRegression(max_iter=1000, random_state=123)
lin_reg_smote.fit(X_smote, y_smote)

evaluate_model(lin_reg_smote, transform=column_transform)
rf_smote = RandomForestClassifier(random_state=123)

rf_smote.fit(X_smote, y_smote)


evaluate_model(rf_smote, transform=column_transform)<jupyter_output>Accuracy: 0.9461839530332681
F1 score: 0.06779661016949154
Recall score: 0.04<jupyter_text>NearMiss<jupyter_code>nm = NearMiss(version=3)
X_nm, y_nm = nm.fit_resample(column_transform.transform(X_train), y_train)
lin_reg_nm = LogisticRegression(max_iter=1000, random_state=123)
lin_reg_nm.fit(X_nm, y_nm)

evaluate_model(lin_reg_nm, transform=column_transform)
rf_nm = RandomForestClassifier(random_state=123)
rf_nm.fit(X_nm, y_nm)

evaluate_model(rf_nm, transform=column_transform)<jupyter_output>Accuracy: 0.6203522504892368
F1 score: 0.11818181818181818
Recall score: 0.52<jupyter_text>SVM<jupyter_code>svc_pipe = make_pipeline(
    column_transform,
    SVC(class_weight='balanced', probability=True, random_state=123))
svc_pipe.fit(X_train, y_train)

evaluate_model(svc_pipe)<jupyter_output>Accuracy: 0.7299412915851272
F1 score: 0.22905027932960895
Recall score: 0.82<jupyter_text>Balanced Random Forest<jupyter_code>brf = make_pipeline(
        column_transform,
        poly_f,
        BalancedRandomForestClassifier()
    )
brf.fit(X_train, y_train)

evaluate_model(brf)<jupyter_output>Accuracy: 0.7211350293542075
F1 score: 0.2359249329758713
Recall score: 0.88<jupyter_text>Hyper-param optimization<jupyter_code>grid = {
    'columntransformer__imputer__strategy': ['mean', 'most_frequent', 'median'],
    'balancedrandomforestclassifier__n_estimators' : [50, 100, 200, 300, 400, 500, 600, 800],
    'balancedrandomforestclassifier__max_depth' : [2, 3, 4, 6, 8, 10]
}

clf = RandomizedSearchCV(brf, grid, scoring='recall', random_state=123, n_iter=20)
search = clf.fit(X_train, y_train)
brf.get_params().keys()
print(search.best_score_)
print(search.best_params_)
estimator = search.best_estimator_
evaluate_model(estimator)
brf = make_pipeline(
        column_transform,
        poly_f,
        BalancedRandomForestClassifier(n_estimators=500, max_depth=4)
    )
brf.fit(X, y)

evaluate_model(brf)
with open('model.bin', "wb") as f:
    pickle.dump(brf, f)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11185332575326891, 'fraction_numerical': 0.08044343376918704, 'mean_word_length': 5.5889513108614235, 'pattern_counts': {'":': 0, '<': 40, '<?xml version=': 0, '>': 40, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, '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': '12', 'dir': 'jupyter-structured-clean-dedup', 'id': '113360', 'license': 'MIT', 'n_tokens_mistral': 3080, 'n_tokens_neox': 2661, 'n_words': 408, 'path': 'modelling/stroke_model.ipynb', 'repo_name': 'SawickiBartosz/stroke-service', 'size': '7036'}