盒子
盒子
文章目录
  1. 数据背景

R语言,数据类别不平衡的一种处理方法

数据背景

是从stackoverflow招聘页提取的数据,所有条目的特征都是哑变量,预测目标是所在岗位是否是Data Scientist.数据下载

这个数据集的特点就是类别标签极不平衡,(DS和nonDS大概是1:4)而处理类别标签不平衡的一般方法是:upsampling或者downsampling,还有就是本文使用的代价敏感训练。

这里使用是时一个比较好用的包-caret, 首先构造一个代价矩阵作为在randomforest里面的parms,这个代价矩阵costMatrix里面包含了两类标签的大致比例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
trainData<-read.csv("train_data.csv",header= T)
trainY <- trainData$class
trainX <- subset(trainData, select = -c(JobID,Employer,class)) #去掉无用列
library(caret)
indx <- createFolds(trainY, returnTrain = TRUE)
ctrl <- trainControl(method = "cv", index = indx, classProbs = TRUE)
costMatrix <- matrix(c(0, 4, 1, 0), ncol = 2)
rownames(costMatrix) <- levels(as.factor(trainData$class))
colnames(costMatrix) <- levels(as.factor(trainData$class))
library(caret)
cartCosts <- train(x = trainX,
y = trainY,
method = "rf",
trControl = ctrl,
metric = "Kappa",
tuneLength = 10,
parms = list(loss = costMatrix))

下面针对这样一个不平衡标签写了一个精度描述函数

1
2
3
4
5
6
7
8
9
10
DS_Accuracy_Rate = function( model, test.data, test.solutions ) {
predictions = predict( model, test.data)
DS_sum = length(predictions)-sum(as.numeric(test.solutions)-1)
NON_DS_sum = sum(as.numeric(test.solutions)-1)
NON_DS_correct_predictions = sum(ifelse(predictions == test.solutions&test.solutions == 'nonDS',1,0 ))
DS_correct_predictions = sum(ifelse(predictions == test.solutions&test.solutions == 'DS',1,0 ))
accuracy = (NON_DS_correct_predictions+4*DS_correct_predictions )/(NON_DS_sum + 4*DS_sum)
}
DS_accuracy = DS_Accuracy_Rate(cartCosts, trainX,trainY)
DS_accuracy

突然回想起了前几个月京东面试时候,面试官问我评价分类结果的指标有哪些,当时因为没有好好研究这方面,就磕磕碰碰答了精度,ROC什么的?想象也是相当潦草啊,当时。。

最后结果为:

1
0.991769547325103

还是想说数据集好,跑出来的结果就是顺心!虽然现实世界中没有这么顺心的数据了