我们在处理真实世界机器学习数据集时遇到的主要挑战之一是数据的比例不平衡。欺诈检测是这类数据的最好例子。在本文中,我们将使用kaggle中的信用卡欺诈检测数据集(www.kaggle.com/mlg-ulb/creditcardfraud)。
在全部数据中,欺诈事件不到1%。这种具有相当少的来自特定类的实例的数据称为不平衡数据。
采样技术
过采样
对少数类(数据集中实例较少的类)的数据进行复制,以增加少数类的比例。这种技术的一个主要问题是过度拟合。
from imblearn.over_sampling import RandomOverSampler
oversample = RandomOverSampler(sampling_strategy='minority')
X_over, y_over = oversample.fit_resample(X_train, y_train)
欠采样
对来自多数类(机器学习数据集中实例较多的类)的数据进行采样,以减少多数类的比例。这种技术的一个主要问题是信息的丢失。
from imblearn.over_sampling import RandomUnderSampler
undersample = RandomUnderSampler(sampling_strategy='majority')
X_over, y_over = oversample.fit_resample(X_train, y_train)
合成少数类过采样技术(SMOTE)
我们将使用过采样技术生成样本,但不是盲目复制。SMOTE遵循以下步骤来生成数据。
- 对于少数类中的每个样本x,选择k个最近邻构成Q{y0,y1,…yk}(k的默认值为5)。
- 对少数类样本进行线性插值,得到新的样本x’。
from imblearn.over_sampling import SMOTE
sm = SMOTE(random_state = 2)
X_train_res, y_train_res = sm.fit_sample(X_train, y_train)
结合使用SMOTE和欠采样可获得更好的结果。
集成学习技巧
集成学习技术在不平衡数据上表现良好。集成技术结合了多个分类器的结果,以提高单个分类器的性能。
随机森林
随机森林是一种减少决策树分类器方差的集成学习技术。随机森林从建立在采样数据上的多个决策树中获得最佳解。
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(n_estimators=100,
bootstrap = True,
max_features = 'sqrt')
model.fit(X_train,y_train)
y_pred2= model.predict(X_test)
我们检测到72个欺诈(总共98个欺诈)。因此,检测到欺诈的概率为0.734。
XGBoost
随机森林并行构建树。在boosting技术中,通过校正先前训练的树的误差来训练树。
import xgboost as xgb
alg = xgb.XGBClassifier(learning_rate=0.1, n_estimators=140, max_depth=5,min_child_weight=3, gamma=0.2, subsample=0.6, colsample_bytree=1.0,objective='binary:logistic', nthread=4, scale_pos_weight=1, seed=27)
alg.fit(X_train, y_train, eval_metric='auc')
y_pred = alg.predict(X_test)
y_score = alg.predict_proba(X_test)[:,1]
我们检测到74起欺诈/ 98起欺诈。因此,检测到欺诈的概率为0.755。
Light GBM
Light GBM可以提高XGBoost的性能。Light GBM内存高效且与大型数据集兼容。
import lightgbm as lgbm
lgbm_clf = lgbm.LGBMClassifier(boosting_type='gbdt',
class_weight=None,
colsample_bytree=0.5112837457460335,importance_type='split',
learning_rate=0.02, max_depth=7, metric='None',
min_child_samples=195, min_child_weight=0.01,
min_split_gain=0.0,
n_estimators=3000, n_jobs=4, num_leaves=44, objective=None,
random_state=42, reg_alpha=2, reg_lambda=10, silent=True,
subsample=0.8137506311449016, subsample_for_bin=200000,
subsample_freq=0)
lgbm_clf.fit(X_train, y_train)
y_pred1 = lgbm_clf.predict(X_test)
y_score1 = lgbm_clf.predict_proba(X_test)[:,1]
我们检测到76起欺诈/ 98起欺诈。因此,检测到欺诈的概率为0.775。
深度学习技术
自编码器
自编码器尝试重建给定的输入。自编码器用于降维和深度异常检测。这些深度学习技术也可以应用于图像和视频。
我们将仅以正常交易来训练我们的自编码器。每当遇到欺诈检测时,自编码器都无法重建它。
autoencoder = tf.keras.models.Sequential([
tf.keras.layers.Dense(input_dim, activation='relu', input_shape=(input_dim, )),
tf.keras.layers.GaussianNoise(),
tf.keras.layers.Dense(latent_dim, activation='relu'),
tf.keras.layers.Dense(input_dim, activation='relu')
])
autoencoder.compile(optimizer='adam',
loss='mse',
metrics=['acc'])
autoencoder.summary()
现在,我们将训练自编码器,并观察正常交易和欺诈交易的重构情况。
X_test_transformed = pipeline.transform(X_test)
reconstructions = autoencoder.predict(X_test_transformed)
mse = np.mean(np.power(X_test - reconstructions, 2), axis=1)
欺诈交易的重构误差率很高。现在,我们需要设置将欺诈与正常交易区分开的阈值。
为了获得较高的精度值,我们可以采用较高的阈值,但是为了获得良好的召回率,我们需要降低它。
DevNet
Deviation Networks (DevNet)定义了高斯先验和基于Z分数的偏差损失,以使端到端神经异常评分学习器能够直接优化异常评分。
该网络中使用的损失函数为:
Lφ(x;Θ)=(1- y)| dev(x)| + y max(0,a-dev(x))
dev(x)=φ(x;Θ)?μR/σR
其中a是Z分数置信区间。
根据中心极限定理,我们可以得出结论:高斯分布拟合从网络获得的异常分数数据。我们将在实验中设置μ= 0和σ= 1,这有助于DevNet在不同机器学习数据集上实现稳定的检测性能。
对于所有正常交易(y = 0):
Lφ(x;Θ)=(1-0)| dev(x)| = | dev(x)|
对于所有欺诈交易(y = 1):
Lφ(x;Θ)= 1(max(0,a-dev(x)))= max(0,a-dev(x))
因此,偏差损失相当于将所有异常对象的异常评分与正常对象的异常评分进行统计显著性偏差。
网络的代码是:
def dev_network(input_shape):
x_input = Input(shape=input_shape) intermediate = Dense(1000
,activation='relu',
kernel_regularizer=regularizers.l2(0.01), name =
'hl1')(x_input)
intermediate = Dense(250, activation='relu',
kernel_regularizer=regularizers.l2(0.01), name =
'hl2')(intermediate)
intermediate = Dense(20, activation='relu',
kernel_regularizer=regularizers.l2(0.01), name =
'hl3')(intermediate)
intermediate = Dense(1, activation='linear', name = 'score')
(intermediate)
return Model(x_input, intermediate)
偏差损失的Pytyhon代码为:
def deviation_loss(y_true, y_pred):
confidence_margin = 5.
ref = K.variable(np.random.normal(loc = 0., scale= 1.0, size =
5000) , dtype='float32')
dev = (y_pred - K.mean(ref)) / K.std(ref)
inlier_loss = K.abs(dev)
outlier_loss = K.abs(K.maximum(confidence_margin - dev, 0.))
return K.mean((1 - y_true) * inlier_loss +
y_true * outlier_loss)
model = dev_network_d(input_shape)
model.compile(loss=deviation_loss, optimizer=rms)
指标
对于不平衡的机器学习数据,准确性不是一个好的度量标准。相反,我们可以考虑使用Recall和F1-score。
我们也可以从ROC曲线转换到Precision-Recall曲线。
ROC曲线介于真阳性率(召回率)与假阳性率之间。
精度对不平衡数据的变化更为敏感,因为负样本的数量相当高。
FPR = FP /(FP + TN)
Precision= TP /(TP + FP)
最后
- 为了从图像或视频相关数据中检测异常,首选深度学习。
- 与集成方法相比,深度学习中需要调整的参数更多。因此,理解模型对于深度学习的调整起着关键作用。