数据分析而言,数据是显而易见的核心。但是并不是所有的数据都是有用的。存在不完整的、含噪声的和不一致的数据是现实世界大型的数据库或数据仓库的共同特点。一些比较成熟的算法对其处理的数据集合一般有一定的要求,如数据完整性好、数据的冗余性小、属性之间的相关性小。然而,实际系统中的数据一般无法直接满足数据挖掘算法的要求,因此必须对数据进行预处理,以提高数据质量,使之符合数据挖掘算法的规范和要求。数据预处理技术是数据分析以及数据挖掘过程中非常重要的一环。 数据预处理是指在对数据进行数据挖掘的主要处理以前,先对原始数据进行必要的清洗、集成、转换、离散、归约、特征选择和提取等一系列处理工作,达到挖掘算法进行知识获取要求的最低规范和标准。
数据清洗实际上也是数据质量分析,检查原始数据中是否存在脏数据(不符合要求,或者不能直接进行分析的数据),并且处理脏数据。
常见情况如下:
#导入库
import seaborn as sns
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import scipy.stats as st
import warnings
import missingno as msn
from scipy.stats import skew
%matplotlib inline
plt.style.use('seaborn-darkgrid')
sns.set(style = 'darkgrid')
import warnings
warnings.filterwarnings('ignore')
plt.rcParams['font.sans-serif'] = ['STSong']
本文使用mathorcup杯B题数据附件1语音用户数据集。语音用户数据集包括5433个样本,每个样本包括51个特征变量和四种评分情况。
链接:https://pan.baidu.com/s/1cELfAf9rjBxCypyHv2i7Uw?pwd=gbit
提取码:gbit
#源数据导入
file1 = pd.read_excel('./附件1语音业务用户满意度数据.xlsx')
file1_n = file1.copy()
#查看数据集大小
file1_n.shape
缺失值处理
缺失值处理一般有三个处理步骤(判断数据是否为NaN、过滤缺失值、补全缺失值)。
本文首先查看各个数据条空值比例,并使用missingno库可视化缺失值和绘制缺失比例柱状图。
#缺失值可视化
msno.bar(file1_n)
## 查看空值比例
data_na = (file1_n.isnull().sum()/len(file1_n))*100
data_na = data_na.drop(data_na[data_na == 0].index).sort_values(ascending=False)
## 绘制空值比例的条形图
plt.figure(figsize=(15,10))
sns.barplot(x=data_na.index, y=data_na)
plt.xlabel('特征', fontsize=15)
plt.ylabel('缺失比例', fontsize=15)
plt.xticks(rotation=90) # 倾斜90度
图1 缺失比例柱状图
由图1 缺失比例柱状图得出:发现“用户描述”,“用户描述.1”,“重定向次数”,“重定向驻留时长”数据缺失比例在96%以上,属于高度缺失数据,那我们对于这些高度缺失数据通常得处理方式是删除,如果数据没有要求得话,那么我们将直接删除。
#用户描述过于分散无判断意义,故删除
file1_n = file1.copy()
file1_n.drop("用户描述", axis = 1, inplace = True)
file1_n.drop("用户描述.1", axis = 1, inplace = True)
#删除重定向次数、重定向时长
file1_n.drop("重定向次数", axis = 1, inplace = True)
file1_n.drop("重定向驻留时长", axis = 1, inplace = True)
#删除id
file1_n.drop("用户id", axis = 1, inplace = True)
删除完数据我们要继续查看缺失数据条,本文得数据就有说明要求“是否关怀用户”和“是否去过营业厅”空白部分为0,故使用fillna()方法进行填充。
#是否关怀用户,空白的为“否
file1_n["是否关怀用户"] = file1_n["是否关怀用户"].fillna('否')
#是否去过营业厅,空白的为“否
file1_n["是否去过营业厅"] = file1_n["是否去过营业厅"].fillna('否')
填充完成后,我们要养成好习惯继续查看缺失数据条。就会发现剩下一些缺失部分较少的低度缺失数据,通常我们处理这些数据要根据不同数据类型进行不同方式处理。一般数据存在数值数据类型和类别数据类型。数值类型的特征,他们有测量或计数的意义。主要可分为两类:连续特征和离散特征。常用的对数值特征提取和处理方法有:
类别特征的取值没有数学意义,不能直接进行计算,需要通过各种编码方法将其变为数值特征。
常用的类别特征提取方法有:
本文示例对于类别型变量的缺失值用众数进行填充、对于数值型变量的缺失值用平均数进行填充
fill_col = ['是否4G网络客户(本地剔除物联网)', '终端品牌类型',
'是否5G网络客户', '是否实名登记用户', '客户星级标识','当月欠费金额',
'前第3个月欠费金额', '终端品牌', '外省流量占比']
# 对于分类型变量的缺失值用众数进行填充、对于数值型变量的缺失值用平均数进行填充
for s in fill_col:
if s in file1_n.columns:
if file1_n[s].dtype==object:
fill_none = file1_n[s].value_counts().index[0]
else:
fill_none = np.mean(file1_n[s])
file1_n[s] = file1_n[s].fillna(fill_none)
使数据分布更接近正态分布。
numeric_feats = file1_n.dtypes[file1_n.dtypes != "object"].index
# 检查所有数值特征的偏斜
skewed_feats = file1_n[numeric_feats].apply(lambda x: skew(x.dropna())).sort_values(ascending=False)
print("\n转换后特征偏度: \n")
skewness = pd.DataFrame({'Skew' :skewed_feats})
skewness.head(10)
#boxcox转换
from scipy.special import boxcox1p
skewed_features = skewness.index
lam = 0.15
for feat in skewed_features:
#all_data[feat] += 1
file1_n[feat] = boxcox1p(file1_n[feat], lam)