randomForest:信用卡欺诈建议

randomForest: Credit card fraud advice

数据来源:https://www.kaggle.com/mlg-ulb/creditcardfraud

我有一个包含大约 280,000 行和 31 列的数据集。该数据集包含信用卡交易记录,并标记了欺诈交易。 99.8% 的数据是合法交易,0.2% 的数据是欺诈性的。由于数据非常不平衡,我使用加权随机森林对非欺诈案例与欺诈案例进行分类。

目前,我认为我的模型非常适合数据,以至于过度拟合。但是,我不确定它是否过度拟合,因为数据在 99.8% 的真实交易中自然是不平衡的。这就是我的结果:

#training
> actual <- as.factor(c(0,0,1,1))

> predicted <- as.factor(c(0,1,0,1))

> count <- c(191204,40,98,228)

> df1 <- data.frame(actual,predicted,count)

#testing
> actual <- as.factor(c(0,0,1,1))

> predicted <- as.factor(c(0,1,0,1))

> count <- c(56852,9,26,75)

> df2 <- data.frame(actual,predicted,count)

问题一:如何让模型更通用,减少过拟合?我是否从模型中删除变量?如果是这样,我该如何识别和删除这些 'weak' 指标?

问题2:如何从整体上改进这个模型?我想增加真阳性的数量并减少误报和漏报的数量。

我尝试将 ntree 设置为 100、200 和 500。据我了解,这似乎对我的结果没有太大影响。

> set.seed(123)

> data_set_size <- floor(nrow(df)*0.80)

> index <- sample(1:nrow(df), size = data_set_size)

> training <- df[index,]

> testing <- df[-index,]

> rf <- randomForest(Class ~ ., data = training, ntree = 4, importance = TRUE, classwt = c(0.3,0.7))

> results <- data.frame(testing$Class, predict(rf, testing[,1:30], type = "class"))

对于问题 1 how do I identify and remove these 'weak' indicators?,您应该关注特征选择:有监督或无监督。其中有监督的特征选择方法包括相关性、缺失值处理等方法,而无监督的特征提取方法有主成分分析、因子分析。这里的想法是降低数据维度,以便保留占最大方差的特征,同时丢弃具有低方差的特征。

对于 Question 2: How can I improve this model overall? 关注 5-fold10-fold cross-validation 方案。要确定最佳树数以提高准确性,请参阅这些类似的问题,1, 2, 3, 4 and 5

下面给出了问题 2 的最小工作示例:

from sklearn import datasets
from sklearn.model_selection import cross_validate
from sklearn.svm import LinearSVC
from sklearn.ensemble import  RandomForestClassifier
import pandas as pd

diabetes = datasets.load_diabetes()
X, y = diabetes.data, diabetes.target

clf=RandomForestClassifier(n_estimators =10, random_state = 42, class_weight="balanced")
output = cross_validate(clf, X, y, cv=2, scoring = 'accuracy', return_estimator =True)
for idx,estimator in enumerate(output['estimator']):
    print("Features sorted by their score for estimator {}:".format(idx))
    feature_importances = pd.DataFrame(estimator.feature_importances_,
                                       index = diabetes.feature_names,
                                        columns=['importance']).sort_values('importance', ascending=False)
    print(feature_importances)

输出

Features sorted by their score for estimator 0:
     importance
s6     0.137735
age    0.130152
s5     0.114561
s2     0.113683
s3     0.112952
bmi    0.111057
bp     0.108682
s1     0.090763
s4     0.056805
sex    0.023609
Features sorted by their score for estimator 1:
     importance
age    0.129671
bmi    0.125706
s2     0.125304
s1     0.113903
bp     0.111979
s6     0.110505
s5     0.106099
s3     0.098392
s4     0.054542
sex    0.023900