【人工智能概论】 数据清洗
一. 数据清洗
- 在数据清洗的过程中,主要处理的是缺失值、异常值和重复值。
- 在数据获取相对精准的情况下,对于多变量时间序列异常检测与预测这一课题,异常值本身就是模型需要的,如果人工抹除了还搞个锤锤,重复值实际上也不会有太大的影响,因此关键在于对缺失值进行处理。
二. 常见的缺失值处理方法
- 数据的缺失分为两种,一种是某条记录的整体缺失;另一种是数据中某项缺失。
- 不同的数据表达方式对缺失值的表达是不相同的,数据库中是Null,Python中是None,Pandas和Numpy中是NaN。
- 丢失的数据记录通常是无法找回的,对于缺失数据,通常有以下几种处理思路:
- 丢弃缺失值
- 直接删掉有缺失的整行或整列数据,操作最为简单。
- 但这样会造成记录数量或特征数量的减少,这是不值得推荐的。
- 补全缺失值
- 通过一定的方法将缺失的数据补上,从而形成更完整的数据记录,对于后续的数据处理、分析和建模至关重要。
- 统计法:对于数值型的数据,使用均值、加权均值、中位数等方法补全;对于分类型数据,使用众数补足
- 模型法:基于已有的其他字段,将缺失字段作为目标变量进行预测,从而得到最为可能的补全值。
- 真值转换
- 某些情况下,缺失值的规律无从探索,因而无法补全;或缺失值也是一种带有信息的数据,不应该对缺失值任意的进行填补。
- 这时,就需要使用真值转换进行缺失值的填充。
- 该方法的本质思路是:
作为开发人员,我们认同缺失值的存在,并且把缺失值也作为数据分布规律的一部分,将特征的实际值与缺失值都作为输入参与后续数据处理,但因为缺失值无法参与模型的计算,因此要对缺失值进行真值转换。
- 以用户性别为例,这是一个很重要的特征,缺失的性别信息是很难补齐的,可以通过真值转换进行调整。
- 转换前:
特征:性别,值域:(男,女,未知) - 转换后:
特征1: 性别为男,值域: (0,1)
特征2: 性别为女,值域: (0,1)
特征3: 性别未知,值域: (0,1)
- 很显然通过将一个特征扩展到三个,很好的把数据缺失融入进来。
- 特征值为连续的如何进行真值转换?
- 不处理
三. 课题背景下的缺失值处理思路
- 对于异常检测来说,缺失值何尝不是造成异常的一种原因,或者说具有异常值的数据何尝不是某种意义上的异常,它可能对应着某个传感器功能的缺失,如果贸然进行填补,可能会造成模型性能的下降。
- 因此应该把数据缺失这一信息进行保留。
- 假想:连续数值的缺失是不是可以弄个特别大数,一眼假那种来作为标记以方便运算,如-9999。
四. 代码实现
- 思路: 看看各数据的统计情况,检验是否存在缺失值,对缺失值进行处理(-9999)。
import os
import pandas as pd
dataset_folder = './processed_datasets_csv/SMD'
def load_and_look_data(file_dir,read_info = False):
df = pd.read_csv(file_dir,header=0,index_col=0)
if read_info:
pd.set_option('display.max_columns',None)
print(df.describe().T)
null_num = df.isnull().sum().sum()
if null_num == 0:
print(file_dir,"中没有缺失值!")
elif null_num >0 :
print(file_dir,"存在%d个缺失值"%null_num)
return null_num
def load_and_look_dataset():
i = 0
j = 0
for category in ["train","test"]:
file_list = os.listdir(os.path.join(dataset_folder,category))
for filename in file_list:
if filename.endswith('.csv'):
i = i + 1
file_dir = os.path.join(dataset_folder,category,filename)
null_num = load_and_look_data(file_dir)
null_list = []
if null_num:
j = j + 1
null_list.append(file_list)
print('共计%d个文件'%i)
print('有%d个含有缺失项' %j)
return null_list
if __name__ =="__main__":
null_list = load_and_look_dataset()
for file in null_list:
df = pd.read_csv(file,header=0,index_col=0)
df.fillna(-9999,inplace=True)
df.to_csv(file, index=False)