<jupyter_start><jupyter_text>Příprava vstupních dat Import datasetu<jupyter_code>df = pd.read_csv('data.csv', sep=';')<jupyter_output><empty_output><jupyter_text>Preprocessing<jupyter_code># set gender as a category data type
df.Gender = df.Gender.map({0: 'female', 1: 'male'}).astype('category')

# drop ID columns
df = df.drop(['Unit1', 'Unit2', 'Gender'], axis=1)<jupyter_output><empty_output><jupyter_text>Normalizace<jupyter_code>normalization = "mean"
if normalization == "mean":
    series_labels = df.pop('isSepsis')
    df = (df - df.mean()) / df.std()
    df['isSepsis'] = series_labels
elif normalization == "minmax":
    df = (df - df.min()) / (df.max() - df.min())<jupyter_output><empty_output><jupyter_text>Chybějící data<jupyter_code># Drop 10% of rows with the most missing data.
df_row_null_sum = df.isnull().sum(axis=1)
df_row_null_sum.hist(bins=len(df.columns))
plt.show()
print(f"Before: number of rows = {len(df)}, percentage of non-NA cells = {df.count().sum() / df.size * 100}")

df = df[df_row_null_sum < df_row_null_sum.quantile(0.9)]
df.isnull().sum(axis=1).hist(bins=len(df.columns))
plt.show()
print(f"After: number of rows = {len(df)}, percentage of non-NA cells = {df.count().sum() / df.size * 100}")
# Drop columns with more than 50% missing data.
df_col_null_sum = df.isnull().sum(axis=0)
df_col_null_sum.plot(kind='bar')
plt.show()
print(f"Before: number of columns = {len(df.columns)}, percentage of non-NA cells = {df.count().sum() / df.size * 100}")

df = df[df.columns[(df_col_null_sum / len(df)) < 0.5]]
df.isnull().sum(axis=0).plot(kind='bar')
plt.show()
print(f"After: number of columns = {len(df.columns)}, percentage of non-NA cells = {df.count().sum() / df.size * 100}")
# Fill the missing data with mean/median.
print(f"Before: percentage of non-NA cells = {df.count().sum() / df.size * 100}")
df = df.fillna(df.mean())
print(f"After: percentage of non-NA cells = {df.count().sum() / df.size * 100}")<jupyter_output>Before: percentage of non-NA cells = 90.39043178484631
After: percentage of non-NA cells = 100.0<jupyter_text>Nevyváženost dat<jupyter_code>not_sepsis_cnt, sepsis_cnt = df['isSepsis'].value_counts()
df['isSepsis'].value_counts().plot(kind="bar")

# divide by class
not_sepsis = df[df['isSepsis'] == 0]
sepsis = df[df['isSepsis'] == 1]
sampling = "over"
if sampling == "under":
    # random under-sampling
    not_sepsis_sample = not_sepsis.sample(sepsis_cnt)
    df = pd.concat([sepsis, not_sepsis_sample], axis=0, ignore_index=True)
elif sampling == "over":
    # random over-sampling
    sepsis_over = sepsis.sample(not_sepsis_cnt, replace=True)
    df = pd.concat([sepsis_over, not_sepsis], axis=0, ignore_index=True)

df['isSepsis'].value_counts().plot(kind="bar")<jupyter_output><empty_output><jupyter_text>Analýza dat<jupyter_code>df.head()
df.info()
df.describe()
# measure the relationship and the dependency between two variables
plt.matshow(df.corr())
df.drop('isSepsis', 1).hist()
_ = plt.plot()<jupyter_output><empty_output><jupyter_text>Rozdělení dat na tréningová a testovací<jupyter_code>df = df.reindex(np.random.permutation(df.index))

split_fraction = 0.8
train_fv = df.sample(frac=split_fraction)
test_fv = df.drop(train_fv.index)

print(f"velikost trenovacich dat = {len(train_fv)}, rozlozeni = {train_fv['isSepsis'].value_counts().values}")
print(f"velikost testovacich dat = {len(test_fv)}, rozlozeni = {test_fv['isSepsis'].value_counts().values}")

train_labels = train_fv.pop('isSepsis')
test_labels = test_fv.pop('isSepsis')<jupyter_output>velikost trenovacich dat = 50110, rozlozeni = [25078 25032]
velikost testovacich dat = 12528, rozlozeni = [6287 6241]<jupyter_text>Tvorba modelu Definice vrstev NN<jupyter_code>print(f"input_dim = {len(train_fv.columns)}")
model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(20, activation='relu', input_dim=len(train_fv.columns)))
model.add(tf.keras.layers.Dense(30, activation='relu'))
model.add(tf.keras.layers.Dense(20, activation='relu'))
model.add(tf.keras.layers.Dense(1, activation='sigmoid'))<jupyter_output>input_dim = 22<jupyter_text>Volba funkcí a hyperparametrů<jupyter_code>model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])
model.summary()<jupyter_output>Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense (Dense)                (None, 20)                460       
_________________________________________________________________
dense_1 (Dense)              (None, 30)                630       
_________________________________________________________________
dense_2 (Dense)              (None, 20)                620       
_________________________________________________________________
dense_3 (Dense)              (None, 1)                 21        
=================================================================
Total params: 1,731
Trainable params: 1,731
Non-trainable params: 0
_________________________________________________________________<jupyter_text>Tréning<jupyter_code>history = model.fit(train_fv.values, train_labels.values,
                    validation_data=(test_fv.values, test_labels.values),
                    epochs=10, batch_size=32)
# Plot training & validation loss values
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'])
plt.show()

# Plot training & validation accuracy values
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'])
plt.show()<jupyter_output><empty_output><jupyter_text>Evaluace<jupyter_code>metrics_values = model.evaluate(test_fv.values, test_labels.values, verbose=0)
true_labels = test_labels.values
pred_scores = model.predict(test_fv.values).flatten()
for i in range(len(model.metrics_names)):
    print(f"{model.metrics_names[i]} = {metrics_values[i]}")<jupyter_output>loss = 0.2729678433554992
accuracy = 0.8943167328834534<jupyter_text>Metriky True Positive Rate, False Positive Rate, ROC křivka, AUC<jupyter_code>fprs, tprs, thresholds = metrics.roc_curve(true_labels, pred_scores)
plt.plot(thresholds, tprs)
plt.xlim((0, 1))
plt.ylim((0, 1))
plt.xlabel('Classification Threshold')
plt.ylabel('True Positive Rate')
plt.show()

plt.plot(thresholds, fprs)
plt.xlabel('Classification Threshold')
plt.ylabel('False Positive Rate')
plt.xlim((0, 1))
plt.ylim((0, 1))
plt.show()

# The ROC curve is created by plotting the true positive rate (TPR) against
# the false positive rate (FPR) at various threshold settings.
plt.plot(fprs, tprs)
plt.plot([0, 1], [0, 1], linestyle='--')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.show()
# Compute precision-recall pairs for different probability thresholds.
precisions, recalls, thresholds = metrics.precision_recall_curve(true_labels, pred_scores)
plt.plot(recalls, precisions)
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.show()<jupyter_output><empty_output><jupyter_text>Klasifikace s využitím prahu<jupyter_code>pred_threshold = 0.5
# convert prediction scores > threshold to 1 (positive), scores <= threshold to 0 (negative)
pred_labels = np.where(pred_scores > pred_threshold, 1, 0)<jupyter_output><empty_output><jupyter_text>Metriky True/False Positives/Negatives a matice záměn<jupyter_code># true negatives  [0][0]  |  false positives is [0][1]
# false negatives [1][0]  |  true positives is [1][1]

df_confusion = pd.crosstab(pd.Series(true_labels, name='Actual'),
                           pd.Series(pred_labels, name='Predicted'),
                           margins=False)
# absolute
display(df_confusion)
# percentual
display(df_confusion / df_confusion.sum(axis=1) * 100)

cm = metrics.confusion_matrix(true_labels, pred_labels)
names = ['not sepsis', 'sepsis']
cm_df = pd.DataFrame(cm, index=names, columns=names)
hm = sns.heatmap(cm_df)
hm.set(xlabel='Predicted class', ylabel='Actual class')
plt.show()<jupyter_output><empty_output><jupyter_text>Metriky Accuracy, Precision, Recall, F1 score, AUC<jupyter_code># 90% accuracy may seem good, but classifier model that always predicts "benign" on class-imbalanced
# dataset can achieve the exact same accuracy (90/100 correct predictions).
accuracy = metrics.accuracy_score(true_labels, pred_labels)
# The precision is intuitively the ability of the classifier not to label as positive
# a sample that is negative. A model that produces no false positives has a precision of 1.0.
precision = metrics.precision_score(true_labels, pred_labels)
# The recall is intuitively the ability of the classifier to find all the positive samples.
# A model that produces no false negatives has a recall of 1.0.
recall = metrics.recall_score(true_labels, pred_labels)
# The F1 score can be interpreted as a weighted average of the precision and recall,
# where an F1 score reaches its best value at 1 and worst score at 0.
f1 = metrics.f1_score(true_labels, pred_labels)
# Area Under the ROC Curve.
auc = metrics.roc_auc_score(true_labels, pred_scores)

print(f"accuracy = {accuracy}\nprecision = {precision}\nrecall = {recall}\nF1 score = {f1}\nAUC = {auc}")<jupyter_output>accuracy = 0.894316730523627
precision = 0.8646003262642741
recall = 0.9341451690434225
F1 score = 0.8980283425754776
AUC = 0.955771717667588
{'fraction_non_alphanumeric': 0.14832686457568448, 'fraction_numerical': 0.031679429350676594, 'mean_word_length': 5.625434329395413, 'pattern_counts': {'":': 4, '<': 58, '<?xml version=': 0, '>': 57, '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': '15', 'dir': 'jupyter-structured-clean-dedup', 'id': '328492', 'license': 'MIT', 'n_tokens_mistral': 3578, 'n_tokens_neox': 3244, 'n_words': 689, 'path': 'Sepsis Classification.ipynb', 'repo_name': 'jwrona/sepsis_classification', 'size': '9533'}