基于MATLAB应用SMOTE算法进行过采样
简介
在学习模式分类的过程中,我们往往会发现我们需要分析的数据存在样本不均衡的问题,严重时甚至相差十几倍 ,在这种情况下模式分类算法很容易忽视少数类的准确率。本文介绍的是解决样本不均衡问题常用的一种方法——通过SMOTE算法对少数类进行过采样进而解决样本不均衡的问题。本文MATLAB代码来源: SMOTE算法怎样增加新数据——MATLAB中文论坛.下载的CSNN.rar包
正文
Smote过采样函数——SmoteOverSampling
SmoteOverSampling代码:
// SmoteOverSampling
function [sample,sampleLabel]=SmoteOverSampling(data,Label,ClassType,C,AttVector,k,type)
%check parameters
NumClass=size(ClassType,2);
if(size(C)~=NumClass)
error('class number and cost matrix do not consistent.')
end
if(size(data,2)~=size(Label))
error('instance numbers in data and Label do not consistent.')
end
if(size(data,1)~=length(AttVector))
error('attribute numbers in data and AttVector do not consistent.')
end
%prepare for distance function
attribute=VDM(data,Label,ClassType,AttVector);
%compute class distribution
ClassD=zeros(1,NumClass);
for i=1:NumClass
id=find(Label==ClassType(i));
ClassData{
i}=data(:,id);
ClassD(i)=length(id);
end
%compute new class distribution
cn=C./ClassD;
[tmp,baseClassID]=min(cn);
newClassD=floor(C/C(baseClassID)*ClassD(baseClassID));
%over sampling using SMOTE
sample=data;
sampleLabel=Label;
clear data Label;
i=1;
while(i<NumClass | i==NumClass )
if(newClassD(i)>ClassD(i))
diff=newClassD(i)-ClassD(i);
s=SMOTE(ClassData{
1},diff,k,type,attribute,AttVector);
sample=[sample s];
sampleLabel=[sampleLabel repmat(ClassType(i),1,diff)];
end
if(length(ClassData)>1)
ClassData=ClassData(2:end);% delete after used
end
i=i+1;
end
函数功能:
通过复制高成本的训练样本直到不同类的样本与成本C成正比;复制的方法是SMOTE。
函数参数解释:
sample: Smote过度抽样后的新训练集——行索引属性和列索引实例
sampleLabel:新训练集中实例的类标签——行向量
data:原始训练集——行索引属性和列索引实例
Label:原始训练集中实例的类标签——行向量
ClassType:类(即标签)类型——行向量
C:代价向量,C[i]是在不考虑实例被错误分配到的具体类的情况下,错误分类第i个类实例的代价——行向量
AttVector:属性向量,1表示对应属性为名义属性,0表示对应属性为数值属性——行向量1*n,n为原始数据的属性维数
k:算法中使用了k-NN。默认值为5——使用默认值就好
type: 可选’nominal’ 或 ‘numeric’——‘nominal’ :在计算距离时使用VDM处理名义属性; ‘numeric’:名义属性计算方法与数值属性相同,即使用欧式距离处理名义属性
注意:
- 设置C值应遵循大样本类小代价,小样本类大代价
- C与ClassType在位置上是一一对应的关系;注意理解下面的例子
example_1写法表示:类标签为0的样本被错分配的代价(C_0):类标签为1的样本被错分配的代价(C_1)=1:2
而example_2写法表示:类标签为0的样本被错分配的代价(C_1):类标签为1的样本被错分配的代价(C_0)=1:2
// example_1
ClassType = [0,1];
C = [1,2];
// example_1
ClassType