<jupyter_start><jupyter_text>資料預處理<jupyter_code>import numpy as np
import pandas as pd
import os

filepath = '/Users/mac/Desktop/Kaggle_datasets/Creditcardfraud/'
filename01 = 'creditcard.csv'

df_full = pd.read_csv(os.path.join(filepath, filename01))
df_full.head()
df_full.info()
df_full.Class.value_counts() ##可以看到positive比例超級低約莫0.2%，直接跑DL會有偵測不到positive全部猜negative的危險
df_full.sort_values(by='Class', ascending=False, inplace=True)
df_full.drop('Time', axis=1,  inplace = True)
df_full.head() ##記住，第index值492以後都是false，方便我們分層抽樣<jupyter_output><empty_output><jupyter_text>Stratified sampling: 盡量讓0和1平衡<jupyter_code>df_sample = df_full.iloc[:3000,:]
df_sample.Class.value_counts()
feature = np.array(df_sample.values[:,0:29])
label = np.array(df_sample.values[:,-1])<jupyter_output><empty_output><jupyter_text>Shuffle<jupyter_code>from sklearn.utils import shuffle

shuffle_df = shuffle(df_sample, random_state=42)

df_train = shuffle_df[0:2400]
df_test = shuffle_df[2400:]
train_feature = np.array(df_train.values[:,0:29])
train_label = np.array(df_train.values[:,-1])
test_feature = np.array(df_test.values[:,0:29])
test_label = np.array(df_test.values[:,-1])
train_feature[0]
train_feature.shape
train_label
train_label.shape
test_feature.shape
test_label.shape<jupyter_output><empty_output><jupyter_text>MinMaxScaler，整個data數據的Scaler要統一！！<jupyter_code>from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()

scaler.fit(train_feature)
train_feature_trans = scaler.transform(train_feature)
test_feature_trans = scaler.transform(test_feature)
train_feature_trans<jupyter_output><empty_output><jupyter_text>跑模型<jupyter_code>######################### 建立模型
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout

import matplotlib.pyplot as plt 
def show_train_history(train_history,train,validation):
    plt.plot(train_history.history[train])
    plt.plot(train_history.history[validation])
    plt.title('Train History')
    plt.ylabel(train)
    plt.xlabel('Epoch')
    plt.legend(['train', 'validation'], loc='best')
    plt.show()

model = Sequential() #一層一層到底，按順序

#輸入層（隱藏層1）
model.add(Dense(units=200, 
                input_dim=29, 
                kernel_initializer='uniform', 
                activation='relu'))
model.add(Dropout(0.5))

#隱藏層2，不用寫input_dim，因為就是前一層的units
model.add(Dense(units=200,  
                kernel_initializer='uniform', 
                activation='relu'))
model.add(Dropout(0.5))

#輸出層
model.add(Dense(units=1, #輸出一個數字 
                kernel_initializer='uniform',
                activation='sigmoid'))

print(model.summary()) #可以清楚看到model還有參數數量

model.compile(loss='binary_crossentropy',   #二元用binary
              optimizer='adam', metrics=['accuracy'])

train_history = model.fit(x=train_feature_trans, y=train_label,  #上面多分割一步在keras是內建的
                          validation_split=0.8, epochs=200, 
                          batch_size=500, verbose=2) #verbose=2表示顯示訓練過程

######################### 訓練過程視覺化
show_train_history(train_history,'acc','val_acc')
show_train_history(train_history,'loss','val_loss')


######################### 實際測驗得分
scores = model.evaluate(test_feature_trans, test_label)
print('\n')
print('accuracy=',scores[1])

######################### 紀錄模型預測情形（答案卷）
prediction = model.predict_classes(test_feature_trans)

#儲存訓練結果
#model.save_weights("Keras_CreditCardFraud_MLP.h5")
#print('model saved to disk')<jupyter_output>_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_16 (Dense)             (None, 200)               6000      
_________________________________________________________________
dropout_11 (Dropout)         (None, 200)               0         
_________________________________________________________________
dense_17 (Dense)             (None, 200)               40200     
_________________________________________________________________
dropout_12 (Dropout)         (None, 200)               0         
_________________________________________________________________
dense_18 (Dense)             (None, 1)                 201       
=================================================================
Total params: 46,401
Trainable params: 46,401
Non-trainable params: 0
_________________________________________________________________
None
T[...]<jupyter_text>Train/Test Score<jupyter_code>df_ans = pd.DataFrame({'Real Class' :test_label})
df_ans['Prediction'] = prediction
df_ans[ df_ans['Real Class'] != df_ans['Prediction'] ]
df_ans['Prediction'].value_counts() #分層之後，0和1參半，是好現象
df_ans['Real Class'].value_counts()
prediction_train = model.predict_classes(train_feature_trans)
df_train_ans = pd.DataFrame({'Real Class' :train_label})
df_train_ans['Prediction'] = prediction_train
df_train_ans[ df_train_ans['Real Class'] != df_train_ans['Prediction'] ]
df_train_ans['Prediction'].value_counts()
df_train_ans['Real Class'].value_counts()<jupyter_output><empty_output><jupyter_text>Confusion Matrix<jupyter_code>import seaborn as sns
%matplotlib inline

cols = ['Real_Class_1','Real_Class_0']  #Gold standard
rows = ['Prediction_1','Prediction_0'] #diagnostic tool (our prediction)

B1P1 = len(df_ans[(df_ans['Prediction'] == df_ans['Real Class']) & (df_ans['Real Class'] == 1)])
B1P0 = len(df_ans[(df_ans['Prediction'] != df_ans['Real Class']) & (df_ans['Real Class'] == 1)])
B0P1 = len(df_ans[(df_ans['Prediction'] != df_ans['Real Class']) & (df_ans['Real Class'] == 0)])
B0P0 = len(df_ans[(df_ans['Prediction'] == df_ans['Real Class']) & (df_ans['Real Class'] == 0)])

conf = np.array([[B1P1,B0P1],[B1P0,B0P0]])
df_cm = pd.DataFrame(conf, columns = [i for i in cols], index = [i for i in rows])

f, ax= plt.subplots(figsize = (5, 5))
sns.heatmap(df_cm, annot=True, ax=ax, fmt='d') 
ax.xaxis.set_ticks_position('top') #Making x label be on top is common in textbooks.

print('total test case number: ', np.sum(conf))
def model_efficacy(conf):
    total_num = np.sum(conf)
    sen = conf[0][0]/(conf[0][0]+conf[1][0])
    spe = conf[1][1]/(conf[1][0]+conf[1][1])
    false_positive_rate = conf[0][1]/(conf[0][1]+conf[1][1])
    false_negative_rate = conf[1][0]/(conf[0][0]+conf[1][0])
    
    print('total_num: ',total_num)
    print('G1P1: ',conf[0][0]) #G = gold standard; P = prediction
    print('G0P1: ',conf[0][1])
    print('G1P0: ',conf[1][0])
    print('G0P0: ',conf[1][1])
    print('##########################')
    print('sensitivity: ',sen)
    print('specificity: ',spe)
    print('false_positive_rate: ',false_positive_rate)
    print('false_negative_rate: ',false_negative_rate)
    
    return total_num, sen, spe, false_positive_rate, false_negative_rate

model_efficacy(conf)<jupyter_output>total_num:  600
G1P1:  74
G0P1:  5
G1P0:  7
G0P0:  514
##########################
sensitivity:  0.913580246914
specificity:  0.986564299424
false_positive_rate:  0.00963391136802
false_negative_rate:  0.0864197530864<jupyter_text>分層抽樣才有可能達到好的預測效果?  以下實驗拿這個分層做出來的模型去預測大部分為0的數據，預設是false positive rate高<jupyter_code>df_sample2 = df_full.iloc[:,:] #由於都是label=0，就不shuffle了

feature2 = np.array(df_sample2.values[:,0:29])
label2 = np.array(df_sample2.values[:,-1])

feature2_trans = scaler.transform(feature2)

######################### 實際測驗得分
scores = model.evaluate(feature2_trans, label2)
print('\n')
print('accuracy=',scores[1])

######################### 紀錄模型預測情形（答案卷）
prediction2 = model.predict_classes(feature2_trans)
unique, counts = np.unique(prediction2, return_counts=True)
unique, counts ##結果相當不錯！！
prediction2_list = prediction2.reshape(-1).astype(int)
label2_list = label2.astype(int)
print(classification_report(label2_list, prediction2_list))
print(confusion_matrix(label2_list, prediction2_list))
conf = confusion_matrix(label2_list, prediction2_list)
f, ax= plt.subplots(figsize = (5, 5))
sns.heatmap(conf, annot=True, ax=ax, fmt='d') 
ax.xaxis.set_ticks_position('top') #Making x label be on top is common in textbooks.
def model_efficacy(conf):
    total_num = np.sum(conf)
    sen = conf[0][0]/(conf[0][0]+conf[1][0])
    spe = conf[1][1]/(conf[1][0]+conf[1][1])
    false_positive_rate = conf[0][1]/(conf[0][1]+conf[1][1])
    false_negative_rate = conf[1][0]/(conf[0][0]+conf[1][0])
    
    print('total_num: ',total_num)
    print('G1P1: ',conf[0][0]) #G = gold standard; P = prediction
    print('G0P1: ',conf[0][1])
    print('G1P0: ',conf[1][0])
    print('G0P0: ',conf[1][1])
    print('##########################')
    print('sensitivity: ',sen)
    print('specificity: ',spe)
    print('false_positive_rate: ',false_positive_rate)
    print('false_negative_rate: ',false_negative_rate)
    
    return total_num, sen, spe, false_positive_rate, false_negative_rate

model_efficacy(conf)<jupyter_output>total_num:  284807
G1P1:  281048
G0P1:  3267
G1P0:  60
G0P0:  432
##########################
sensitivity:  0.999786558903
specificity:  0.878048780488
false_positive_rate:  0.883211678832
false_negative_rate:  0.000213441097372
{'fraction_non_alphanumeric': 0.17816979051819185, 'fraction_numerical': 0.045424476295479604, 'mean_word_length': 5.851208459214502, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 30, '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': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '175114', 'license': 'MIT', 'n_tokens_mistral': 3608, 'n_tokens_neox': 3434, 'n_words': 487, 'path': 'Skl_Keras_CreditCardFraud_(Stratified).ipynb', 'repo_name': 'Pytoddler/Kaggle-competition', 'size': '9070'}