不平衡数据分类实证-R语言

数据分布不平衡及多种解决方法介绍


点击下面就可以蓝色字体就行

不平衡理论原理及多种解决方法介绍

SMOTE算法
SMOTE全称是Synthetic Minority Oversampling Technique即合成少数类过采样技术,它是基于随机过采样算法的一种改进方案,由于随机过采样采取简单复制样本的策略来增加少数类样本,这样容易产生模型过拟合的问题,即使得模型学习到的信息过于特别(Specific)而不够泛化(General),SMOTE算法的基本思想是对少数类样本进行分析并根据少数类样本人工合成新样本添加到数据集中,具体如图下2所示,算法流程如下。

1 对于少数类中每一个样本 x ,以欧氏距离为标准计算它到少数类样本集 Smin 中所有样本的距离,得到其k近邻。
2 根据样本不平衡比例设置一个采样比例以确定采样倍率 N ,对于每一个少数类样本 x ,从其k近邻中随机选择若干个样本,假设选择的近邻为 x^
3 对于每一个随机选出的近邻 x^ ,分别与原样本按照如下的公式构建新的样本。
这里写图片描述


SMOTE算法摒弃了随机过采样复制样本的做法,可以防止随机过采样易过拟合的问题,实践证明此方法可以提高分类器的性能。但是由于对每个少数类样本都生成新样本,因此容易发生生成样本重叠(Overlapping)的问题,为了解决SMOTE算法的这一缺点提出一些改进算法,其中的一种是Borderline-SMOTE算法,如图3所示。
在Borderline-SMOTE中,若少数类样本的每个样本 xi 求k近邻,记作 Siknn ,且 Siknn 属于整个样本集合 S 而不再是少数类样本,若满足

这里写图片描述


原文链接:http://www.jianshu.com/p/3e8b9f2764c8


看了原理,让我们来实践下,看看是否有效果?
本文采用SMOTE预处理不平衡数据,尽量让 正样本和负样本比例为1:1,然后选用svm模型分类,代码如下:

install.packages('DMwR')
install.packages('pROC')
install.packages('el071')

library('pROC')
library('DMwR')
library("e1071")

dt = read.csv("C://Users//yelang//Desktop//matlabyewu//r业务//svm//ww.csv") #读入数据
df =dt
sum(is.na(df))


df[complete.cases(df[,9]),] #去除婚否的缺失值df[complete.cases(df['MaritalStatus']),] 
df[complete.cases(df['VehiclePrice']),]

df['Age']
attach(df)
Age[Age == 0] =  median(as.numeric(as.matrix(df['Age'])))  #所有缺失值换成38
VehiclePrice[VehiclePrice == 0] =0.5
df = data.frame(df,Age,VehiclePrice)

colnames(df) #所有列明
df=na.omit(df) #删除其他缺失值
sum(is.na(df)) #查看缺失值





table(df$FraudFound)

df<-df[,c(-8,-10,-14)]# 删掉这几列

set.seed(100) # for reproducing results
rowIndices <- 1 : nrow(df) # prepare row indices
sampleSize <- 0.8 * length(rowIndices) # training sample size
trainingRows <- sample (rowIndices, sampleSize) # random sampling
trainingData <- df[trainingRows, ] # training data
testData <- df[-trainingRows, ] # test data

prop.table(table(trainingData$FraudFound)) 
prop.table(table(testData$FraudFound)) 

trainingData$FraudFound<-as.factor(trainingData$FraudFound) 
trainingData<-SMOTE(FraudFound~.,trainingData,perc.over=400,perc.under=100) 
trainingData$FraudFound<-as.numeric(trainingData$FraudFound) 
# 我们再次用prop.table()函数检查结果的平衡性,确定我们已经让阴性、阳性数据达到相同。 
prop.table(table(trainingData$FraudFound)) 
##  
##   1   2  
## 


#tuned1 <- tune.svm(FraudFound ~ ., data = trainingData,  type="nu-classification" , gamma = 10^(-1:-4), cost = 10^(1:5)) # tune
#summary (tuned1) # to select best gamma and cost
svmfit <- svm (FraudFound ~ ., data = trainingData, type="nu-classification" , kernel = "radial", cost = 1000, gamma=0.0001, scale = FALSE) # radial svm, scaling turned OFF
print(svmfit)#打印svm模型概要
colnames(trainingData) #输出列明


compareTable <- cbind(testData[,12]+1, predict(svmfit, testData[,-12]))  # comparison table

View(compareTable)#观察预测结果
jg = as.numeric(predict(svmfit, testData[,-12])) #测试预测结果
testtarget = testData[,12]+1 #目标变量加1,为了和输出更好匹配
jglen =  length(jg)
count = length(which((testtarget==2)))
cheat = sum(abs((jg[1:count ]-testtarget[1:count ])))/as.numeric(length(jg[1:count ]))#欺诈模型错误率
cheataccuracy = 1-cheat# 欺诈模型正确率


count1 = length(which((testtarget==1)))#计算原始变量里面1的个数



cheatnot = sum(abs(na.omit(jg[count+1:jglen ]-testtarget[count+1:jglen ])))/count1
cheatnotaccuracy  = 1-cheatnot  # 非欺诈正确率

zaccuracy= 1- (sum(abs((jg-testtarget)))/as.numeric(length(jg)) ) #总的正确率

write.csv(testData ,file="C://Users//yelang//Desktop//matlabyewu//r业务//svm//testdata.csv")#写出数据,测试数据预测结果和测试数据本身目标值一起输出
write.csv(compareTable,file="C://Users//yelang//Desktop//matlabyewu//r业务//svm//jg.csv")#写出数据,测试数据预测结果和测试数据本身目标值一起输出

猜你喜欢

转载自blog.csdn.net/u014356002/article/details/53402573