机器学习(二) -- 数据预处理(2)

本文介绍了机器学习中的数据预处理步骤,包括检测和处理缺失数据(通过isnull()和info()函数)、异常数据(散点图、箱线图和3σ法则)、以及重复数据(记录和特征重复的检测与删除)。使用了numpy、pandas库进行操作。
摘要由CSDN通过智能技术生成

系列文章目录及链接

上篇:机器学习(二) -- 数据预处理(1)
下篇:机器学习(二) -- 数据预处理(3)


前言

tips:标题前有“***”的内容为补充内容,是给好奇心重的宝宝看的,可自行跳过。文章内容被“文章内容”删除线标记的,也可以自行跳过。“!!!”一般需要特别注意或者容易出错的地方。

本系列文章是作者边学习边总结的,内容有不对的地方还请多多指正,同时本系列文章会不断完善,每篇文章不定时会有修改。

本章开始会用到numpy,pandas以及matplotlib,这些就不在这讲了哈。


四、【数据清洗】

数据异常大致分为三种情况,缺失数据、异常数据(噪声数据)、重复数据。

通过填写缺失的值、光滑噪声数据、识别或删除离群点并解决不一致性来“清理”数据。主要是达到如下目标:格式标准化,异常数据清除,错误纠正,重复数据的清除。

1、缺失数据的检测与处理

1.1、检测与统计

1.1.1、利用isnull()函数

(只是想查看每列的缺失值情况,info()更方便)

测试数据:

# 检测
print('data中元素是否为空:\n', data.isnull())
# print('data中元素是否为非空:\n', data.notnull())

# 统计
print('data中每个特征对应的非空值数为:\n', data.count())
# print('data中每个特征对应的非空值数为:\n', data.notnull().sum())
print('data中每个特征对应的缺失率为:\n', 1-data.count()/len(data))

# print('data中总非空值数为:\n', data.count().sum())
# # print('data中为空值的总个数:\n',data.isnull().sum().sum())
# print('data中总缺失率为:\n', 1-data.count().sum()/(len(data)*len(data.columns)))

结果:isnill()和notnull()对每个值进行判断,并给出结果(备注掉的有些结果是一样的,就是写法不同,可以参考一下,发散一下思维。)

1.1.2、利用info()函数
# 缺失值的统计
# 利用info()方法查看DataFrame的缺失值
print(data.info())

info()就比较直接了,

第一行,告诉我们“data”是一个DataFrame对象

第二行,告诉我们样本范围有4个,从0到3

第三行以及表格,告诉我们有4列(每列一个特征),每个特征的非缺失值情况,如feature2有3个非缺失值

(其他的···请字面理解,也不重要)

1.2、处理

1.2.1、删除缺失值(慎用)
# 删除缺失值
data1=data.dropna()
print(data1)

dropna()函数:删除具有缺失值的行。

        how:确定缺失值个数,默认how='any’表明,只要某行有缺失值就将该行丢弃;

                  how='all’表明某行全部为缺失值才将其丢弃。

.dropna(axis = 0,how = 'any', thresh = None, subset = None, inplace = False)
1.2.2、填充缺失值

一般用该列平均值填充(当然还有其他很多方法,用0、最大值、中位数、拉格朗日插值等等填充)

# 填充缺失值
data2=data.fillna(1)
# data2=data.replace(np.nan,1)
print(data2)

data2=data.fillna(data.mean())
print(data2)

fillna():缺失值替换。

        value:用于填充缺失值的标量值或字典对象

        method:插值方式,ffill向前填充(向下,front fill),bfill向后填充(向上,back fill)

.fillna(value=None,method=None,axsi=None,inplace=False,limit=None)
# 填充缺失值
# 向后填充
data3=data.fillna(method='bfill')
print(data3)

data3.iloc[2,2]=None
print(data3)

# 向前填充
data4=data3.fillna(method='ffill')
print(data4)

2、异常数据的检测与处理

2.1、检测

2.1.1、散点图方法
# 测试数据制作
data=pd.DataFrame(np.arange(12),columns=['x'])
data['y']=data['x']*1.2+1.2
data.iloc[1,1]=134
data.iloc[6,1]=143
print(data)

一目了然,有没有。

# 绘图法
plt.scatter(data['x'],data['y'],c='k',marker='.')
# plt.scatter(data.iloc[:,0],data.iloc[:,1],c='k',marker='.')

2.1.2、箱线图分析

原理与概念:

5个四分位点:数值大小从小到大排序,分别在开头(最小),25%位置的数(下四分位),中位数,75%位置的值(上四分位),结尾(最大值)的值,分别为Q0,Q1,Q2,Q3,Q4

四分位距(IQR):Q3-Q1得到的数

然后将最大、最小值设置为min=Q1-1.5IQR,max=Q3+1.5IQR,不在[min,max]的值被认为是异常值。

# 利用箱型图的四分位距(IQR)对异常值进行检测
Percentile = np.percentile(data['y'], [0, 25, 50, 75, 100])  # 计算百分位数
IQR = Percentile[3] - Percentile[1]  # 计算箱型图四分位距
UpLimit = Percentile[3]+IQR*1.5  # 计算临界值上界
DownLimit = Percentile[1]-IQR*1.5  # 计算临界值下界

# 判断异常值,大于上界或小于下界的值即为异常值
abnormal = [i for i in data['y'] if i >UpLimit or i < DownLimit] 
print('IQR检测出的y中异常值为:\n', abnormal)
print('IQR检测出的异常值比例为:\n', len(abnormal)/len(data['y']))

2.1.3、3σ法则

这玩意就和数学的正态分布有关了,

简单来讲,超出的【μ±3σ】的值就为异常值。(μ是均值,σ是标准差)

data.iloc[1,1]=2.4
# 利用3sigma原则对异常值进行检测
y_mean = data['y'].mean()  # 计算均值
y_std = data['y'].std()  # 计算标准差

UpLimit = y_mean+y_std*3  # 计算临界值上界
DownLimit =  y_mean-y_std*3  # 计算临界值下界

y_cha = data['y'] - y_mean  # 计算元素与平均值之差

# 返回异常值所在位置
ind = [i for i in range(len(y_cha)) if np.abs(y_cha[i])>y_std*3]

abnormal = [data['y'][i] for i in ind]  # 返回异常值
print('3sigma原则检测出的y中异常值为:\n', abnormal)
print('3sigma原则检测出的异常值比例为:\n', len(abnormal)/len(data['y']))

之所以我要修改上面,有一个异常值的数据,是因为我这里数据量太少,异常值又大占比也偏高,出现了设置成3σ不判定为异常值的情况。所以,使他只有一个异常值,来检测异常效果。(实际操作中异常值比例应该没有这么大,我这2/12了都,直接两个大异常值,把标准差拉到了50+,笑不活了QwQ)

这也可以用计算临界值的方法,大同小异哈。

2.2、处理

2.2.1、不处理

身为一条咸鱼,是躺床上起床上厕所都觉得累的!咱就啥都不干!!!

2.2.2、删除

这是pandas里面的操作方法哈

# 删除异常值
# print(data)
data1=data[~(np.abs(y_cha)>y_std*3)]# 删的是有异常值的一行哈
print(data1)

2.2.3、修改

一般修改为阈值或中值。(当然,也可以是其他的视情况而定,比如可以按照缺失值处理,插入各种值。这里复制一个data2是防止吧data里面的数据修改了,后面还要用呢,节约是中华民族的传统美德)

# 修改异常值
data2=data.iloc[:,:]

for i in ind:
    if data2.iloc[i,1]>UpLimit:
        data2.iloc[i,1]=UpLimit
    if data2.iloc[i,1]<DownLimit:
        data2.iloc[i,1]=DownLimit
        
print("临界值上界:",UpLimit,"临界值下界:",DownLimit)
print(data2)

2.2.4、转换

当当当当,看异常值得差异是不是小了很多。但这种使用情况极少,慎用。

# 异常值的对数转换
log_y=np.log(data['y'])
print(log_y)

3、重复数据的检测与处理

重复数据有两种情况,一种是记录重复(整行重复),一种是特征重复(某个值重复)

3.1、记录重复

一个或多个特征列的几条记录完全一致,对于记录重复数据。一般采用直接删除方式

3.1.1、检测
# 制作数据
data=pd.DataFrame([[1,'gxy',88,70,'B'],
                   [2,'zqx',59,90,'B'],
                   [3,'ysy',91,95,'A'],
                   [2,'zqx',59,90,'B'],
                   [4,'xyyz',44,64,'C']],
                  columns=['num','name','English','Python','level'])
print(data)

# 检测
result=data.duplicated()
print(result)

3.1.2、处理
# 处理
data1=data.drop_duplicates()
print(data1)

3.2、特征重复

一个或多个特征名不同,但是数据完全一样。

3.2.1、检测
# 制作数据
data=pd.DataFrame([[1,'gxy',88,70,1,'B'],
                   [2,'zqx',59,90,2,'B'],
                   [3,'ysy',91,95,3,'A'],
                   [4,'xyyz',44,64,4,'C']],
                  columns=['num','name','English','Python','idCard','level'])
print(data)

#检测
result=data.corr(method='pearson',min_periods=1)
print(result)

 corr函数检测相似度,相似度为1,表示两列数据一模一样

3.2.2、处理
# 处理
data1=data[:]

del data1['idCard']
print(data1)


# 2
data1=data.iloc[:,[0,1,2,3,5]]
print(data1)


旧梦可以重温,且看:机器学习(二) -- 数据预处理(1)
欲知后事如何,且看:机器学习(二) -- 数据预处理(3)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值