数据挖掘实战(2):数据预处理

 
内容分为一个部分:《Python数据分析与挖掘实战》第四章 的内容;
 
课件 PDF 和 源码 移步到Githubhttps://github.com/Stormzudi/Python-Data-Mining
邮箱:[email protected]


第一部分:

第4章 数据预处理

4.1 数据清洗

 
这部分的内容在 数据挖掘实战 (1):数据探索 的第二部分 中也有详细的介绍。
 

数据清洗主要是删除原始数据集中的无关数数据集成据、重复数据,平滑噪声数据,筛选掉与挖掘主题无关的数据,处理缺失值、异常值等。
                   

4.1.1 缺失值处理

处理缺失值的方法可分成3类:删除记录、 数据插补、不处理。
其中着重强调数据插补的知识,普遍的插值方法有如下几种。
(1)拉格朗日插值法

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File  : 4-1_lagrange_newton_interp.py
# @Author: Stormzudi
# @Date  : 2020/7/22 16:01

# 拉格朗日插值代码
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'销量'] > 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)  # 输出结果,写入文件

(2)牛顿插值法
实现牛顿插值法:https://blog.csdn.net/wwxy1995/article/details/84440110

4.1.2 异常值处理

移步到:数据挖掘实战 (1):数据探索 的第二部分
 
 

4.2 数据集成

数据挖掘需要的数据往往分布在不同的数据源中,数据集成 就是将多个数据源合并存放在一个一致的数据存储(如数据仓库)中的过程。

4.2.1 实体识别

实体识别:指从不同数据源识别出显示世界的实体,它的任务是统一不同源数据的矛盾之处,常见形式如下。
(1)同名异义
(2)异名同义
(3)单位不统一

4.2.2 冗余属性识别

数据集成往往导致数据冗余,例如,
(1)同一属性多次出现;
(2)同一属性命名不一致导致重复。
往往需要删除这些冗余数据。

有些冗余属性可以用相关分析检测。给定两个数值型的属性A和B,根据其属性值,用相关系数度量一个属性在多大程度上蕴含另一个属性,如果发现相关系数过高,表明过于冗余,要删除这一属性。

相关分析检测可以使用专门的统计学软件R、SPSS进行分析。

 
 

4.3 数据变换

4.3.1 简单函数变换

简单函数变换 在数据预处理中很重要,简单理解就是将原本的不具有某种规律的数据变换成具有一定规律的数据。例如:通过log(x)函数将原本的数据值变小,使其整体变化程度不会很大。

有时对数变换或者差分运算可以将非平稳序列的数据转化成平稳序列。

常见的简单函数变换有: x 2 x^2 x2 x \sqrt x x l o g ( x ) log(x) log(x)
 
 

4.3.2 规范化

数据规范化对于基于距离的挖掘算法尤其重要。包括:
(1)最小-最大规范化
                           x ∗ = x − min ⁡ max ⁡ − min ⁡ {x^*} = \frac{ {x - \min }}{ {\max - \min }} x=maxminxmin
(2)零-均值规范化
                            x ∗ = x − x − σ {x^*} = \frac{ {x - \mathop x\limits^ - }}{\sigma } x=σxx
(3)小数定标规范化
                            x ∗ = x 10 k {x^*} = \frac{x}{ { { {10}^k}}} x=10kx

# -*- coding: utf-8 -*-
# 数据规范化
import pandas as pd
import numpy as np

datafile = '../data/normalization_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()))  # 小数定标规范化

移步到:数据挖掘实战 (1):数据探索 的第二部分

4.3.3 连续属性离散化

离散值:数据特征的值只能在几种类别中选择,例如:性别(男、女)
连续值:数据值的取值是在某一范围内的任意值,例如:价格

有些数据挖掘算法,特别是某些分类算法(如ID3算法、Apriori 算法等),要求数据是分类属性形式。这样,常常需要将连续属性变换成分类属性,即连续属性离散化。

常用的数据离散化的方法:等宽法、等频法、(一维)聚类

#-*- 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()
4.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) #保存结果
4.3.5 小波变换

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

能够刻画某个问题的特征量往往是隐含在一个信号中的某个或者某些分量中,小波变换可以把非平稳信号分解为表达不同层次、不同频带信息的数据序列,即小波系数。选取适当的小波系数,即完成了信号的特征提取。

#-*- 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 数据规约

数据规约的目的是产生更小但保持原数据完整性的新数据集。其中数据规约分成两个部分:属性规约数值规约
 

4.4.1属性规约

属性规约 通过属性合并来创建新属性维数,或者直接通过删除不相关的属性(维)来减少数据维数,从而提高数据挖掘的效率、降低计算成本。属性规约的目标是寻找出最小的属性子集并确保新数据子集的概率分布尽可能地接近原来数据集的概率分布。

最让我们熟悉的是PCA,主成分分析,就是典型的属性规约,通过降维可以减少数据集的复杂度,在新数据集保留了原始数据集的90%以上的信息,不会失去原始数据的真实性。

#-*- 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.4.2数值规约

数值规约指通过选择替代的、较小的数据来减少数据量,包括有参数方法和无参数方法
两类。有参数方法是使用一个模型来评估数据,只需存放参数,而不需要存放实际数据,例如回归(线性回归和多元回归)和对数线性模型(近似离散属性集中的多维概率分布)。无参数方法就需要存放实际数据,例如直方图、聚类、抽样(采样)。
 
 

4.5 Python 主要数据预处理函数

数据预处理函数:
                
 
 

4.6 小结

本章介绍了数据预处理的4个主要任务:数据清洗、数据集成、数据变换、数据规约

数据清洗 主要介绍了对缺失值和异常值的处理,延续了第3章的缺失值和异常值分析的内容,本章所介绍的处理缺失值的方法分为3类:删除记录、数据插补和不处理,处理异常值的方法有删除含有异常值的记录、不处理、平均值修正和视为缺失值;

数据集成 是合并多个数据源中的数据,并存放到一个数据存储的过程,对该部分的介绍从实体识别问题和冗余属性两个方面进行;

数据变换 介绍了如何从不同的应用角度对已有属性进行函数变换;

数据规约 从属性(纵向)规约和数值(横向)规约两个方面介绍了如何对数据进行规约,使挖掘的性能和效率得到很大的提高。通过对原始数据进行相应的处理,将为后续挖掘建模提供良好的数据基础。

 
 

猜你喜欢

转载自blog.csdn.net/qq_41709378/article/details/107443313