这次我所介绍的噪声添加方法是针对带标签的数据集,通过置换标签类别的方式实现。
比如,标签中有0、1两个类别,所加噪声占整个数据集的比例为20%,那么我们会将20%的0标签换成1,将20%的1标签置换成0。
多个类别也是一样的,如果3个类别,分别为0、1、2,噪声比例还是20%,如果0标签所占的比例为50%,1标签所占整个数据集的比例为30%,2标签所占整个数据集的比例为20%,整个数据集有100个样本点。那么我们对0标签加噪的样本点个数为100*50%*20%=10个,这10个噪声点里边有个噪声会变成1,有
个样本点会变成2。
其他的也是一样的操作,具体python代码如下:
import pandas as pd
import collections
import copy
import warnings
from sklearn.utils import shuffle
warnings.filterwarnings("ignore")
def recreat_data(name,url,url1,pre):
"""
:param name: 加噪之后的数据集文件名
:param url: 原数据集地址
:param url1: 保存加噪之后的数据集地址
:param pre: 噪声百分比
:return:
"""
df=pd.read_csv(url,header=None)
data=df.values
numSamples,numAttribute=data.shape
samNums=(int)(numSamples*pre)#需要置换标签总的样本数量
k_list=list(collections.Counter(data[:,0]).keys())#读取样本点类别
v_list=list(collections.Counter(data[:,0]).values())#样本点类别对应的样本数目
print(k_list)
dff={}
for i in range(len(k_list)):#类别循环
tag=k_list[i]#标签类别
dff[i]=df[df[0]==int(tag)].reset_index()#提取该类别的样本点
samNumsi=int(samNums*(v_list[i]/numSamples))#该类别中需要置换的样本数目
temp_k=copy.deepcopy(k_list)
temp_v=copy.deepcopy(v_list)
temp_k.pop(i)#将该类别出栈,只保留剩余的类别
temp_v.pop(i)#将该类别出栈,只保留剩余的类别的样本点数目
print("tempk",temp_k)
print("temp_v",temp_v)
k=0
samNumsij=0
for j in range(len(temp_k)):
samNumsij+=int(samNumsi*(temp_v[j]/(sum(temp_v))))#剩余类别需要置换的样本点数目
print("sam",samNumsij)
for l in range(k,samNumsij):
dff[i].loc[l, 0] = int(temp_k[j])
k+=1
new=dff[0]
for i in range(len(k_list)-1):
new=pd.concat([new,dff[i+1]])
new = shuffle(new).reset_index().drop(['index', 'level_0'], axis=1)#打乱顺序
new.to_csv(url1, index=False, header=None)
#实例
url="D:\py\\UCI\wine.csv"
url1="D:\py\\UCI噪声\wine_0.2.csv"
pre=0.2
recreat_data("wine",url,pre)