数据预处理
数据预处理主要内容包括:数据清洗、数据集成、数据交换、数据规约
1.数据清洗
1.1缺失值处理
缺失值处理方法:删除记录、数据插补、不处理
常见插补方法:
插补方法 | 方法描述 |
均值/中位数/众数插补 | 根据属性值类型,用属性值的平均数/中位数/众数进行插补 |
使用固定值 | 将缺失的属性值用一个常量替换 |
最近临插补 | 在记录中找到与缺失样本最接近的样本的属性值插补 |
回归方法 | 对带有缺失值的变量,根据已有数据和与其有关的其他变量数据建立拟合模型来预测缺失的属性值 |
插值法 | 插值法是利用已知点建立合适的插值函数f(x),未知值由对应点xi求出的函数值f(xi)近似代替 |
插值法:拉格朗日插值法、牛顿插值法、Hermite插值法、分段插值法、样条插值法
#拉格朗日插值代码 import pandas as pd #导入数据分析库Pandas from scipy.interpolate import lagrange #导入拉格朗日插值函数 inputfile=‘../data/catering_sale.xls’ #销量数据导入路径 outputfile='../tmp/sales.xls' #数据输出路径 data=pd.read_excel(inputfile) #读入数据 data=[u'销量'][(data[u'销量']<400)|(data[u'销量']>500)]=None #过滤异常值,将其变为控制 #自定义列向量插值函数 #s为列向量,n为被插值的位置,k为取前后的数据个数,默认为5 def ployinterp_column(s,n,k=5): y=s[list(range(n-k,n))+list(range(n+1,n+1+k))] #取数 y=y[y.notnull()] #剔除空值 return lagrange(y.index,list(y))(n) #插值并返回插值结果 #逐个元素判断是否需要插值 for i in data.columns: for j in range(len(data)): if (data[i].isnull())[j]: #如果为空即插值 data[i][j]=ployinterp_column(data[i],j) data.to_excel(outputfile) #输出结果,写入文件
1.2 异常值处理
异常值是否剔除,需视情况而定,因为异常值可能蕴藏着有用的信息。
异常值处理方法:
异常值处理方法 | 方法描述 |
删除含有异常值的记录 | 直接将含有异常值的记录删除 |
视为缺失值 | 将异常值视为缺失值,利用缺失值处理方法进行处理 |
平均值修正 | 可用前后两个观测值的平均值修正该异常值 |
不处理 | 直接在具有异常值的数据集上进行挖掘建模 |
2.数据集成
数据挖掘需要的数据通常分布在不同的数据源,数据集成是将多个数据源合并存放在一个一致的数据存储中的过程。
2.1 实体识别
实体识别,指从不同数据源识别出现实世界的实体,用途:统一不同源数据的矛盾之处。
常见形式:
同名异义:数据源A的属性ID和数据源B的属性ID分别描述的是:菜品编号、订单编号,即描述不同的实体。
异名同义:数据源A的sales_dt和数据源B的sales_date都是描述销售日期,即A.sales_dt=B.sales_date。
单位不统一:描述同一实体分别用国际单位和传统计量单位。
2.2 冗余属性识别
数据集成常导致数据冗余:a.同一属性多次出现;b.同一属性命名不一致导致重复
3.数据交换
数据变换主要是对数据进行规范化处理,将数据转换成适当的形式。
3.1 简单函数变换
3.2 规范化
不同评价指标往往具有不同的量纲,数值间差别可能很大,不进行数据处理可能会影响数据分析结果。
为消除指标间的量纲、取值范围差异的影响,需进行标准化处理,将数据按照比例缩放,使之落入一个特定的区间,便于进行综合分析。
(1)最小-最大规范化(离差标准化)
它是对原始数据的线性变换,将数值映射到[0,1]间。
x*=(x-min)/(max-min)
该方法的缺点是:若数值集中且某个数值很大,则规范化后各值会接近于0,且相差不大。
若将来遇到超过目前属性[min,max]取值范围时,会引起系统出错,则需重新确定max、min。
(2)零-均值规范化(标准差标准化)
处理完成的数据均值为0,标准差为1。x'为原始数据均值,δ为原始数据的标准差。
x*=(x-x')/δ
(3)小数定标规范化
通过移动属性值的小数位数,将属性值映射到[-1,1]之间,移动的小数位数取决于属性值绝对值的最大值。
x*=x/10k
#-*- coding: utf-8 -*- #数据规范化 import pandas as pd datafile='../data/normal_data.xls' data=pd.read_excel(datafile,header=None) (data-data.min())/(data.max()-data.min()) #最小-最大化规范 (data-data.mean())/data.std() #零-均值规范化 data/10**np.ceil(np.log10(data.abs().max())) #小数定标规范化
3.3 连续属性离散化
某些数据挖掘算法,常需要将连续属性变换成分类属性,即连续属性离散化。
离散化过程:在数据的取值范围内设定若干个离散的划分点,将取值范围划分为一些离散化的区间,用不同的符号或整数值代表落在每个子区间中的数值。
常用离散化方法
(1)等宽法
将属性的值域分成具有相同宽度的区间。
(2)等频法
将相同数量的记录放进每个区间。
(3)基于聚类分析的方法
一维聚类步骤,a:将连续属性的值用聚类算法进行聚类,b:再将聚类得到的簇进行处理,合并到一个簇的连续属性值并做同一标记。
离散化方法:需要用户指定簇的个数,从而决定产生的区间数。
#-*- coding: utf-8 -*- #数据规范化 import pandas as pd datafile = '../data/discretization_data.xls' #参数初始化 data = pd.read_excel(datafile) #读取数据 data = data[u'肝气郁结证型系数'].copy() k = 4 d1 = pd.cut(data, k, labels = range(k)) #等宽离散化,各个类比依次命名为0,1,2,3 #等频率离散化 w = [1.0*i/k for i in range(k+1)] w = data.describe(percentiles = w)[4:4+k+1] #使用describe函数自动计算分位数 w[0] = w[0]*(1-1e-10) d2 = pd.cut(data, w, labels = range(k)) from sklearn.cluster import KMeans #引入KMeans kmodel = KMeans(n_clusters = k, n_jobs = 4) #建立模型,n_jobs是并行数,一般等于CPU数较好 kmodel.fit(data.reshape((len(data), 1))) #训练模型 c = pd.DataFrame(kmodel.cluster_centers_).sort(0) #输出聚类中心,并且排序(默认是随机序的) w = pd.rolling_mean(c, 2).iloc[1:] #相邻两项求中点,作为边界点 w = [0] + list(w[0]) + [data.max()] #把首末边界点加上 d3 = pd.cut(data, w, labels = range(k)) def cluster_plot(d, k): #自定义作图函数来显示聚类结果 import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签 plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号 plt.figure(figsize = (8, 3)) for j in range(0, k): plt.plot(data[d==j], [j for i in d[d==j]], 'o') plt.ylim(-0.5, k-0.5) return plt cluster_plot(d1, k).show() cluster_plot(d2, k).show() cluster_plot(d3, k).show()
3.4 属性构造
利用已有属性构造新的属性,并加入到现有属性集合中去。
#-*- coding: utf-8 -*- #线损率属性构造 import pandas as pd #参数初始化 inputfile= '../data/electricity_data.xls' #供入供出电量数据 outputfile = '../tmp/electricity_data.xls' #属性构造后数据文件 data = pd.read_excel(inputfile) #读入数据 data[u'线损率'] = (data[u'供入电量'] - data[u'供出电量'])/data[u'供入电量'] data.to_excel(outputfile, index = False) #保存结果
3.5 小波变换
主要应用领域:信号处理、图像处理、语音处理、模式识别、量子物理等
特点:
多分辨率,在时域和频域具有表征信号局部特征的能力,可通过伸缩、平移等运算过程对信号进行多尺度聚焦分析,从中提取有用信息。
(1)基于小波变换特征提取方法:
基于小波变换特征提取方法 | 方法描述 |
基于小波变换的多尺度空间能量分布特征提取方法 |
各尺度空间内的平滑信号、细节信号能提供原始信号的时频局域信息。 把不同分解尺度上信号的能量求解出来,即可将这些能量尺度顺序排列,形成特征向量供识别用。 |
基于小波变换的多尺度空间的模极大值特征提取方法 | 利用小波变换信号局域化分析能力,求解小波变换的模极大值特性检测信号的局部奇异性,将小波变换模极大值的尺度参数s、平移参数t、幅值作为目标的特征量 |
基于小波包变换特征提取方法 | 利用小波分解,可将时域随机信号序列映射为尺度域各子空间内的随机系数序列,按小包分解得到最佳子空间内随机系数序列的不确定性程度最低,将最佳子空间的熵值及最佳子空间在完整二叉树中的位置参数作为特征量,可以用于目标识别。 |
基于适应性小波神经网络特征提取方法 | 基于适应性小波神经网络的特征提取方法可把信号通过分析小波拟合表示,进行特征提取 |
(2)小波基函数
一种具有局部支集的函数,平均值为0,小波基函数满足ψ(0)=∫ψ(t)dt=0
(3)小波变换特征提取代码
#-*- coding: utf-8 -*- #利用小波分析进行特征分析 #参数初始化 inputfile= '../data/leleccum.mat' #提取自Matlab的信号文件 from scipy.io import loadmat #mat是MATLAB专用格式,需要用loadmat读取它 mat = loadmat(inputfile) signal = mat['leleccum'][0] import pywt #导入PyWavelets coeffs = pywt.wavedec(signal, 'bior3.7', level = 5)
#返回结果为level+1个数字,第一个数组为逼近系数数组,后面的依次是细节系数数组
4.数据规约
大数据集上进行复杂的数据分析和挖掘需要很长的时间,数据规约产生更小,但保持原数据完整性的新数据集。
数据规约意义:
降低无效、错误数据对建模的影响,提高建模确定性
少量且具有代表性的数据将大幅缩减数据挖掘所需的时间
降低储存数据的成本
4.1 属性规约
通过属性合并来创建新属性维数,或通过删除不想关的属性来减少数据维数;从而提高数据挖掘效率、降低计算成本。
属性规约目标:寻找出最小的属性子集并确保新数据子集的概率分布尽可能接近原来数据集的概率分布。
属性规约方法:
属性规约方法 | 方法描述 |
合并属性 | 将一些旧属性合并为新属性 |
逐步向前选择 | 从一个空属性集开始,每次从原来属性集合中选择一个当前最优的属性添加到当前属性子集中。直至无法选择出最优属性或满足一定阙值约束为止 |
逐步向后删除 | 从一个全属性集开始,每次从当前属性子集中选择一个当前最差的属性并将其从当前属性子集中消去。直至无法选择出最差属性为止或满足一定阙值约束为止 |
决策树归纳 | 利用决策树的归纳方法对初始数据进行分类归纳学习,获得一个初始决策树,所以没有出现在该决策树的属性均可认为是无关属性,因此,将这些属性从初始集合中删除,即可获得一个较优的属性子集。 |
主成分分析 | 用较少变量去解释原始数据中的大部分变量,即将利用许多相关性很高的变量转化成彼此相互独立或不想关的变量。 |
主成分分析降维:
#-*- coding: utf-8 -*- #主成分分析 降维 import pandas as pd #参数初始化 inputfile = '../data/principal_component.xls' outputfile = '../tmp/dimention_reducted.xls' #降维后的数据 data = pd.read_excel(inputfile, header = None) #读入数据 from sklearn.decomposition import PCA pca = PCA() pca.fit(data) pca.components_ #返回模型的各个特征向量 pca.explained_variance_ratio_ #返回各个成分各自的方差百分比
4.2 数值规约
通过选择替代的、较小的数据来减少数据量。
有参数方法:使用一个模型评估数据,只需存放参数,不需存放实际数据(线性回归、多元回归、近似离散属性集中的多维概率分布)
无参数方法:需存放实际数据(直方图、聚类、抽样采样)
(1)直方图:
(2)聚类:
聚类技术将数据元组(数据表中的一行)视为对象。它将对象划分为一个簇,使一个簇中的对象相互“相似”,而与其他簇中的对象“相异”。
数据规约中,用数据的簇替换实际数据。该技术的有效性依赖于簇的定义是否符合数据的分布性质。
(3)抽样:
s个样本无放回简单随机抽样:从D的N个元组中抽取s个样本(s<N),其中D中任意元组被抽取的概率为1/N,即所有元组的抽取是等可能的。
s个样本有放回简单随机抽样:与上方法类似,不同在于每次一个元组从D中抽取后,记录它,再放回原处。
聚类抽样:若D中元组分组放入M个互不相交的簇,则可得到s个簇的简单随机抽样,其中s<M。
分层抽样:若D划分成互不相交的部分,称为层,通过对每一层的简单随机抽样就可以得到D的分层样本
(4)参数回归:线性模型和对数线性模型
5 Python主要数据预处理函数
函数名 | 函数功能 | 所属扩展库 | 用法 |
interpolate | 一维、高维数据插值 | Scipy |
from scipy.interpolate import * f=scipy.interpolate.lagrange(x,y) x、y分别为自变量、因变量 |
unique | 去除数据中的重复元素,得到单值元素列表,它是对象的方法名 | Pandas\Numpy |
np.unique(D),D是一维数据,可以是:list\array\Series D.unique(),D是Pandas的Series对象 |
isnull | 判断每个元素是否为空值 | Pandas |
D.isnull(),D要求是Series对象,返回一个布尔Series |
notnull | 判断每个元素是否为非空值 | Pandas | D.notnull(),D要求是Series对象,返回一个布尔Series |
PCA | 对指标变量矩阵进行主成分分析 | Scikit-Learn |
from sklearn.decomposition import PCA model=PCA(),建模 model.fit(D),训练,D为要进行主成分分析的数据矩阵 model.components_,训练结束后,获取特征向量 model.explained_variance_ratio_,训练结束后,获取各个属性的贡献率 |
random | 生成随机矩阵 | Numpy |
np.random.rand(k,m,n...),生成一个k*m*n的随机矩阵,其元素均匀分布在区间(0,1)上 np.random.randn(k,m,n...),生成一个k*m*n的随机矩阵,其元素服从标准正态分布 |