4.1数据清洗

4.1.1缺失值处理

1.缺失值处理方法:删除记录、数据插补、不处理

2.常用的插补方法:

  • 均值/中位数/众数插补:用该属性取值的平均数/中位数/众数进行插补
  • 使用固定值:将缺失值的属性用一个常量替换。
  • 最近临插补:在记录中找到与缺失值最接近的样本的该属性值插补
  • 回归方法:对带有缺失值的变量,根据已有数据和其有关的其他变量(因变量)的数据建立拟合模型来预测缺失值的属性值
  • 插值法:利用已知点建立合适的插值函数f(x),未知值由对应点xi求出的f(xi)近似代替。

3.拉格朗日插值法

对于平面上已知的n个点(无两点在一条直线上)可以找到一个n-1次多项式y = a0 + a1 x+ a2x2+......+an-1xn-1,使此多项式曲线过这n个点。

 

预处理GMRES算法 matlab_预处理GMRES算法 matlab

 

预处理GMRES算法 matlab_数据_02

4.牛顿插值法

预处理GMRES算法 matlab_预处理GMRES算法 matlab_03

5.python的Scipy库中,只提供了拉格朗日插值法的函数(因为实现比较容易),需要牛顿插值法,需要自行编写。

6.from scipy.interplotate import lagrange的使用:

直接调用lagrange(x, y)这个函数即可,返回一个对象。

参数x, y对应各个点的x值和y值。

例如:(1, 2)(3,5)(5,9)这三个点,作为函数输入应该这么写:

x = [1, 3, 5]

y = [2, 5, 9]

a = lagrange(x, y)

直接输出该对象,就能看到插值的函数。

利用该对象,能看到很多特性。具体参见:https://docs.scipy.org/doc/numpy-1.12.0/reference/generated/numpy.poly1d.html

  • a.order得到阶
  • a[]得到拉格朗日函数的常数值
  • a()得到对应函数值
  • 此外可以对其进行加减乘除运算

代码实现:


from scipy.interpolate import lagrange
x = [1, 2, 3, 4, 7]
y = [5, 7, 10, 3, 9]
a = lagrange(x, y)
print(a)
print(a(1), a(2), a(3))
print(a[0], a[2], a[3])



输出结果:

预处理GMRES算法 matlab_数据_04

解释:

<class 'numpy.lib.polynomial.poly1d'> 4

这一行是输出a的类型,以及最高次幂。

预处理GMRES算法 matlab_预处理GMRES算法 matlab_05

第二行和第三行就是插值的结果,显示出函数。

第二行的数字是对应下面x的幂,如果对应不齐,则是排版问题。

5.0 7.0 10.0

第四行是代入的x值,得到的结果y。

28.1333333333 30.6527777778 -7.30555555556

最后一行是提取出的系数。也就是说用f[a]这形式,来提取拉格朗日函数的常数值。

7. 用拉格朗日插值对缺失值进行插补的python程序

预处理GMRES算法 matlab_人工智能_06

代码清单4-1 用拉格朗日法进行查补



# 拉格朗日插值代码
import pandas as pd
from scipy.interpolate import lagrange      # 导入拉格朗日插值函数

inputfile = './catering_sale.xls'           # 销量数据路径
outputfile = './sales.xls'                  # 输出数据路径

data = pd.read_excel(inputfile)             # 读入数据
data[u'销量'][(data[u'销量'] < 400) | (data[u'销量'] > 5000)] = 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)             # 输出结果,写入文件



进行插值之前会对数据进行异常值检测,2015/2/21和2015/2/14数据异常,把此数据定义为空缺值,进行补数。

4.1.2异常值处理

异常值处理方法:

  • 删除异常值记录
  • 视为缺失值
  • 平均值修正:用前后两个观测值的平均值修正该异常值
  • 不处理

4.2数据集成

数据集成时,来自多个数据源的实体的表达形式是不一样的,有可能不匹配,要考虑实体识别问题和属性冗余问题。

4.2.1实体识别

实体识别常见形式:

  • 同名异意:数据源A中的属性ID和数据源B中的属性ID分别描述的是菜品编号和订单编号
  • 异名同义:数据源A中的sales_dt和数据源B中的sales_date都是描述销售日期的,即A,sales_dt = B.sales_date
  • 单位不统一:国际单位和中国传统的计量单位

4.2.2冗余属性识别:

常见形式:

  • 同一属性多次出现
  • 同一属性命名不一致导致重复

4.3数据变换

4.3.1简单函数变换

1.简单函数变换将不具有正态分布的数据变换成具有正态分布的数据。

2.时间序列分析中,有时简单的对数变换或者差分运算可以将非平稳序列转换成平稳序列。
4.3.2规范化(归一化)

1.最小—最大规范化

也称离差标准化,对原始数据的线性变换,将数值值映射到[0, 1]之间。

转换公式:  

x*  = (x - min)/(max - min)

这种方法缺点:1.数值集中某个数值很大,则规范化后各值会接近于0,并且相差不大。2.将来遇到超过目前属性[min, max]取值范围时,会引起系统出错,需重新确定min,max。

2.零—均值规范化

也称标准差标准化,经过处理的数据的均值为0,标准差为1。

转换公式:

x*  = (x - x均值)/δ

δ为原始数据的标准差。

3.小数定标规范化

通过移动属性值的小数位数,将属性值映射到[-1, 1]之间,移动的小数位数取决于属性值绝对值的最大值。转换公式:

      x* = x / 10k

4.代码清单4-2 数据规范化代码

(1)pd.read_excel('文件名', sheetname = k, header = 0, encoding = utf-8)

  • read_csv与to_csv是一对输入输出的工具,read_csv直接返回pandas.DataFrame,⽽to_csv只要执行命令即可写文件
  • read_table:功能类似
  • read_fwf:操作fixed width file
  • read_excel与to_excel方便的与excel交互
  • header 表⽰数据中是否存在列名,不存在可以写none
  • names 表示要用给定的列名来作为最终的列名
  • encoding 表⽰数据集的字符编码

注意:当你的xls文件行数很多超过65536时,就会遇到错误,解决办法是将写入的格式变为xlsx。

唯一重要的参数:sheetname=k,标志着一个excel的第k个sheet页将会被取出。

常用的参数:

  • 读取处理:
    skiprows:跳过一定的行

   nrows:仅读取一定的行

   skipfooter:尾部有固定的行数永不读取

   skip_blank_lines:空行跳过

  • 内容处理:

   sep/delimiter:分隔符很重要,常见的逗号,空格,Tab(‘\t’)

   na_values:指定应该被当作na_values的数值

   thousands:统一千位分隔符

  • 收尾处理:

   squeeze:仅读到一列时,不再保存为pandas.DataFrame而是pandas.Series     



# 数据规范化
import pandas as pd 
import numpy as np

# 参数初始化
datafile = './normalization_data.xls'
# 读取数据
data = pd.read_excel(datafile, header = None)


# 最小-最大规范化
data1 = (data - data.min())/(data.max() - data.min())
# 零-均值规范化
data2 = (data - data.mean())/data.std()
# 小数定标规范化;  data.abs().max()表示绝对值的最大值; np.ceil()向正无穷取整
data3 = data/10**np.ceil(np.log10(data.abs().max()))

print(data)
print(data1)
print(data2)
print(data3)



 

 运算结果:

预处理GMRES算法 matlab_数据_07

4.3.3连续属性离散化

1.某些分类算法(如:ID3算法,Apriori算法),要求数据是分类属性形式,常常需要将连续属性变成分类属性,即连续属性离散化

2.离散化过程:1.确定分类数;2.如何将连续属性值映射到这些分类值

3.常见离散化方法:

  • 等宽法:属性的值域分成相同宽度的区间(缺点:对离群点比较敏感,倾向于不均匀的把属性分布到各个区间,损坏建立的决策模型)
  • 等频法:相同的数量的记录放进每个区间(缺点:将相同的数据值分到不同的区间)
  • 基于聚类分析的方法:
  1. 首先用聚类算法(K-Means)进行聚类
  2.  然后将聚类的簇合并到一个簇的连续属性值,并作同一标记

4.代码清单4-3  数据离散化

(1).pandas.DataFrame.copy

链接:http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.copy.html#pandas.DataFrame.copy

DataFrame.copy(deep=True):Make a copy of this objects data.(deep:Make a deep copy, including a copy of the data and the indices. With deep=False neither the indices or the data are copied.)

import pandas as pd

datafile = './discretization_data.xls'
data = pd.read_excel(datafile)
data = data[u'肝气郁结证型系数'].copy()


k = 4
# 等宽离散化,各个类比依次名为0,1,2,3
d1 = pd.cut(data, k , labels = range(k))


# 等频离散化
w = [1.0*i/k for i in range(k+1)]
# 使用describe()自动计算分位数
w = data.describe(percentiles = w)[4: 4+k+1]
w[0] = w[0]*(1-1e-10)
d2 = pd.cut(data, w, labels = range(k))


from sklearn.cluster import KMeans
# 建立模型,n_jobs是并行数,一般等于CPU数表较好
kmodel = KMeans(n_clusters = k, n_jobs = 4)
# 训练模型
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()



 

 运行结果:

预处理GMRES算法 matlab_人工智能_08

4.3.4属性构造

1.为更好的数据挖掘,需要利用已有的属性集构造出新的属性。

2.比如:线损率  = [(供入电量 - 供出电量)/供入电量] * 100%

线损率超过3%~15%,认为用户存在窃漏电行为。

3.代码清单4-4  线损率属性构造



# 线损率属性构造

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)



4.3.5小波变换

1.小波变换具有多分辨率特点,在时域和频域都有表征信号局部特征的能力,通过伸缩和平移等运算对信号进行多尺度聚焦分析,提供了一种非平稳信号的时频分析手段,可以由粗到细观察信号。

2.基于小波变换的特征提取方法:多尺度空间能量分布特征提取、多尺度空间的模极大值特征提取、特征提取、适应性小波神经网络的特征提取。

3.小波基函数:一种具有局部之集的函数,平均值为0,满足Ψ(0) = ∫Ψ(t)dt = 0. 常用的小波基有Haar小波基、db系列小波基。

4.小波变换

伸缩和平移变换:

预处理GMRES算法 matlab_python_09

 

5.基于小波变换多尺度空间能量分布特征提取方法

小波分析技术可以把信号在各频率波段中的特征提取出来,基于小波变化的多尺度空间能量分布特征提取方法是对信号进行频带分析,再分别以计算所得的各个频带的能量作为特征向量。

信号f(t)的二进小波分解可表示为:

f(t) = Aj + ΣDj    (4-21)

其中A是近似信号,为低频部分;D是细节信号,为高频部分,此时信号的频带分布如图:

预处理GMRES算法 matlab_python_10

信号的总能量为:

E = EAj + ∑EDj   (4-22)

选择第j层的近似信号和各层的细节信号的能量作为特征,构造特征向量:

F = [EAj, ED, ED2 , .......EDj]  (4-23)

利用小波变换提取出可以代表声波信号的向量数据,即完成从声波信号的特征向量数据的变换。本例利用小波函数对声波信号数据进行分解,得到5个层次的小波系数。

利用这些小波系数求得各个能量值,这些能量值即可作为声波信号的特征数据。

在python中,Scipy本身提供一些信号处理函数,但不够全面,更好的信号处理库是PyWaves(pywt)。

利用PyWavelets完成上述任务,程序代码如下:


# 利用小波分析进行特征分析

# 参数初始化
inputfile = './leleccum.mat'     # 提取自Matlab的信号文件

from scipy.io import loadmat    # mat是Python专用格式,需要loadmat读取它
mat = loadmat(inputfile)
signal = mat['leleccum'][0]

import pywt                     # 导入PyWavelets
coeffs = pywt.wavedec(signal, 'bior3.7', level = 5)
# 返回结果为level + 1个数字,第一个数组为逼近系数数组,后面的依次是细节系数数组


4.4 数据规约

数据规约产生更小但保持原数据完整性的新数据集。在规约后的数据集上进行分析和挖掘更有效。

4.4.1 属性规约

属性规约通过属性合并来创新属性维数,或删除不相关的属性(维)来减少数据维数,从而提高数据挖掘效率。

属性规约的目标是寻找出最小的属性子集并确保新数据子集的概率分布。

属性规约常用方法:

预处理GMRES算法 matlab_python_11

逐步向前选择,逐步向后删除和决策树归纳属于直接删除不相关属性(维)方法。

主成分分析是一种用于连续属性的数据降维方法,它构造了原始数据的一个正交变换,新空间的基底去除原始空间基底下数据的相关性,只需使用少数新变量就能解释原始数据大部分变异。

预处理GMRES算法 matlab_python_12

在python中,主成分分析的函数位于Scikit-Learn下:

sklearn.decomposition.PCA(n_components = None, copy = True, whiten = False)    # decomposition 分解;components 成分;whiten 漂白

参数说明:

(1)n_components

意义:PCA算法中所要保留的主成分个数n,也即保留下来的特征个数n。

类型:int或者string,缺省时默认为None,所有成分被保留。赋值为int,比如n_components = 1,将把原始数据降到一个维度。赋值为string,比如n_components = 'mle',将自动选取特征个数n,使得满足所要求的方差百分比。

(2)copy

类型:bool,True,False,缺省时默认为True。

意义:表示是否在运行算法时,将原始训练数据复制一份。若为True,则运行PCA算法后,原始训练数据的值不会有任何改变,因为是在原始数据的副本上进行运算;若为False,则运行PCA算法后,原始训练数据的值会变,因为是在原始数据上进行降维运算。

(3)whiten

类型:bool,缺省时默认为False。

意义:白化,使得每个特征具有相同的方差。

使用主成分分析降维的程序代码如下:


import pandas as pd

# 参数初始化
inputfile = './principal_component.xls'
outputfile = './dimention_reducted.xls'        # 降维后的数据

data = pd.read_excel(inputfile, header = None)      # 读入数据

from sklearn.decomposition import PCA

pca = PCA()
pca.fit(data)
print(pca.components_)                         # 返回模型的各个特征向量
print(pca.explained_variance_ratio_)           # 返回各个成分各自的方差百分比; variance(方差); ratio(比率)


运行结果:

预处理GMRES算法 matlab_人工智能_13

从结果可以得到特征方程det(R-λE) = 0有7个特征根、对应的7个单位特征向量以及各个成分各自的方差百分比(也称为贡献率)。其中,方差百分比越大,说明向量的权重越大。

当选取前4个主成分时,累计贡献率已达到97.37%,说明选取前3个主成分进行计算已经相当不错了,因此可以重新建立PCA模型,设置n_components = 3,计算出成分结果。