数据探索

第 3 章数据探索(重要)

** **

** 数据质量分析 **

是数据预处理的前提,是数据挖掘分析结论有效性和准确性的基础,其主要任务 ** 是检查原始数据中是否存在脏数据, ** 脏数据包括:

缺失值

异常值

不一致的值

重复数据及含有特殊符号(如 # 、¥、 * )的数据

本小节将主要对数据中的缺失值、异常值和一致性进行分析。

** 缺失值统计分析 **

统计 ** 缺失值的变量个数 **

统计每个变量 ** 的未缺失数 **

统计变量的 ** 缺失数及缺失率 **

** 异常值统计分析 - 箱型图代码 **

异常值分析是检验数据是否有录入 ** 错误以及含有不合常理的数据 ** 。

异常值是指样本中的个别值,其数值明显偏离其余的观测值。异常值也称为离群点,异常值的分析也称为离群点的分析。

异常值分析方法主要有:简单统计量分析、 3 原则、箱型图分析。 ****

_
_ ** import ** pandas ** as ** pd
data = pd.read_excel( ** '../data/catering_sale.xls' ** , index_col = **
u'日期' ** ) _ #读取数据,指定“日期”列为索引列

_ ** import ** matplotlib.pyplot ** as ** plt _ #导入图像库
_ plt.rcParams[ ** 'font.sans-serif' ** ] = [ ** 'SimHei' ** ] _

用来正常显示中文标签

_ plt.rcParams[ ** 'axes.unicode_minus' ** ] = ** False ** _ #用来正常显示负号

_ plt.figure() _ #建立图像
_ p = data.boxplot( return_type = ** 'dict' ** ) _

p['fliers'][0].get不会报错

p = data.boxplot() #画箱线图,直接使用pd的DataFrame的方法

_ x = p[ ** 'fliers' ** ][ 0 ].get_xdata() _ # 'flies'即为异常值的标签
_ y = p[ ** 'fliers' ** ][ 0 ]. get_ydata ()
y.sort() _ #从小到大排序,该方法直接改变原对象

用annotate添加注释

其中有些相近的点,注解会出现重叠,难以看清,需要一些技巧来控制。

以下参数都是经过调试的,需要具体问题具体调试。

_ ** for ** i ** in ** range ( len (x)):
** if ** i> 0 :
plt.annotate(y[i], xy = (x[i],y[i]), xytext =(x[i]+ 0.05 - 0.8
/(y[i]-y[i- 1 ]),y[i]))
** else ** :
plt.annotate(y[i], xy = (x[i],y[i]), xytext =(x[i]+ 0.08 ,y[i]))
plt.show() _ #展示箱线图 _

_ _

** 一致性分析 **

数据不一致性是指数据的矛盾性、不相容性。直接对不一致的数据进行挖掘,可能会产生与实际相违背的挖掘结果。

在数据挖掘过程中,不一致数据的产生主要发生在数据集成的过程中,可能是由于被挖掘数据是来自于从不同的数据源、重复存放的数据未能进行一致性地更新造成的,比如两张表中都存储了用户的地址,在用户的地址发生改变时,如果只更新了一张表中的数据,那么这两张表中就有了不一致的数据。

** 数据特征分析 **

一般可通过绘制图表、计算某些特征量等手段进行数据的特征分析。

这里主要介绍的特征方法有:

** 分布分析 - 统计函数 describe **

分布分析能揭示数据的分布特征和分布类型,便于发现某些特大或特小的可疑值。

对于定性分类数据,可用饼图和条形图直观地显示分布情况。

对于定量变量而言,欲了解其分布形式,是对称的、还是非对称的,可做出频率分布表、绘制频率分布直方图、绘制茎叶图进行直观地分析;

定量变量做频率分布分析时选择 “组数”和“组宽”是主要的问题,一般按照以下步骤:

求极差 2 决定组距与组数 3 决定分点 4 列出频率分布表 5 绘制频率分布直方图

1 各组之间必须是相互排斥的

2 各组必须将所有的数据包含在内

3 各组的组宽最好相等 _
_ catering_sale = ** '../data/catering_sale.xls' ** _ #餐饮数据
_ data = pd.read_excel(catering_sale, index_col = ** u'日期' ** ) _

读取数据,指定“日期”列为索引列

_ data = data[(data[ ** u'销量' ** ] > 400 )&(data[ ** u'销量' ** ] < 5000
)] _ #过滤异常数据
_ statistics = data.describe() _ #保存基本统计量

_ statistics.loc[ ** 'range' ** ] = statistics.loc[ ** 'max' **
]-statistics.loc[ ** 'min' ** ] _ #极差
_ statistics.loc[ ** 'var' ** ] = statistics.loc[ ** 'std' **
]/statistics.loc[ ** 'mean' ** ] _ #变异系数
_ statistics.loc[ ** 'dis' ** ] = statistics.loc[ ** '75%' **
]-statistics.loc[ ** '25%' ** ] _ #四分位数间距
_ print (statistics)

** 对比分析 **

对比分析是指把两个相互联系的指标数据进行比较,从数量上展示和说明研究对象规模的大小,水平的高低,速度的快慢,以及各种关系是否协调。特别适用于指标间的横纵向比较、时间序列的比较分析。在对比分析中,选择合适的对比标准是十分关键的步骤,选择得合适,才能做出客观的评价,选择不合适,评价可能得出错误的结论。

** 对比分析主要有以下两种形式: **

第一种 : 绝对数比较

第二种 : 相对数比较

  1. 结构相对数 4) 强度相对数

  2. 比例相对数 5) 计划完成程度相对数

  3. 比较相对数 6) 动态相对数

** 统计量分析 **

用统计指标对定量数据进行统计描述,常从集中趋势和离中趋势两个方面进行分析。

平均水平的指标是对个体集中趋势的度量,使用最广泛的是均值和中位数;反映变异程度的指标则是对个体离开平均水平的度量,使用较广泛的是标准差(方差)、四分位间距。

集中趋势度量主要有:均值、中位数、众数

离中趋势度量主要有:极差、标准差、变异系数

** 周期性分析 **

周期性分析是探索某个变量是否随着时间变化而呈现出某种周期变化趋势。周期性趋势相对较长的有年度周期性趋势、季节性周期趋势,相对较短的一般有月度周期性趋势、周度周期性趋势,甚至更短的天、小时周期性趋势。

如在做某用电单位用电量趋势预测过程中,可以先分析该用电单位日用电量的时序图,来直观地估计其用电量变化趋势。

** 贡献度分析 - 帕累托分析 **

贡献度分析又称帕累托分析,帕累托法则又称 20/80 定律。同样的投入放在不同的地方会产生不同的效益。比如对一个公司来讲, 80% 的利润常常来自于
20% 最畅销的产品;而其他 80% 的产品只产生了 20% 的利润。贡献度分析要求我们抓住问题的重点,找到那最有效的 20%
的热销产品、渠道或者销售人员,在最有效的 20% 上投入更多资源,尽量减少浪费在 80% 低效的地方。

** 菜品盈利数据 帕累托图 **

_

初始化参数

_ dish_profit = ** '../data/catering_dish_profit.xls' ** _ #餐饮菜品盈利数据
_ data = pd.read_excel(dish_profit, index_col = ** u'菜品名' ** )
data = data[ ** u'盈利' ** ].copy() _
_ plt.figure()
data.plot( kind = ** 'bar' ** )
plt.ylabel( ** u'盈利(元)' ** )
p = 1.0 data.cumsum()/data.sum()
p.plot( color = ** 'r' ** , secondary_y = ** True ** , style = **
'-o' ** , linewidth = 2 ) _ #secondary_y数轴说明在右边
_ plt.annotate( format (p[ 6 ], ** '.4%' ** ), xy = ( 6 , p[ 6 ]),
xytext =( 6 * 0.9 , p[ 6 ]
0.9 ), arrowprops = dict (
arrowstyle = ** "->" ** , connectionstyle = ** "arc3,rad=.2" ** )) _

添加注释,即85%处的标记。这里包括了指定箭头样式。

_ plt.ylabel( ** u'盈利(比例)' ** )
plt.show()

_ #小知识cumsum
_ a = np.array([[ 1 , 2 , 3 ], [ 4 , 5 , 6 ]])
np.cumsum(a, axis = 0 ) _ # sum over rows for each of the 3 columns
_ np.cumsum(a, axis = 1 ) _ # sum over rows for each of the 3 行 _

_ 就餐饮企业来讲,可以重点改善盈利最高的 80%的菜品,或者重点发展综合影响最高的80%的部门。这种结果可以通过帕累托分析直观的呈现出来,如下图: _

** 相关性分析代码 corr **

分析连续变量之间线性的相关程度的强弱,并用适当的统计指标表示出来的过程称为相关分析。

相关性分析方法主要有:

直接绘制散点图 2 绘制散点图矩阵 3 计算相关系数(比较常用的如 Pearson 相关系数、 Spearman 秩相关系数和判定系数。)

_
_ catering_sale = ** '../data/catering_sale_all.xls' ** _ #餐饮数据,含有其他属性
_ data = pd.read_excel(catering_sale, index_col = ** u'日期' ** ) _

读取数据,指定“日期”列为索引列

_ data .corr() _ #相关系数矩阵,即给出了任意两款菜式之间的相关系数
_ data .corr()[ ** u'百合酱蒸凤爪' ** ] _ #只显示“百合酱蒸凤爪”与其他菜式的相关系数
_ data [ ** u'百合酱蒸凤爪' ** ].corr( data [ ** u'翡翠蒸香茜饺' ** ]) _

计算“凤爪”与“翡翠蒸香茜饺”的相关系数 _

** 统计特征函数 **

Mean () Geomean ()几何平均数, Var , std , corr , cov 。 Moment 中心距

第4章- ** 数据预处理 **

一、 ** 数据清洗 **

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

**1 删除无关重复值 **
**2 平滑噪声 **
**3 异常值处理 **

(1) 删除有异常值的记录 (2) 视为缺失值 (3) 平均值修正 (4) 不处理
要分析异常值的原因,再决定取舍。

**4 缺失值处理 **

方法可分为三类:删除记录、数据插补和不处理。

常用的数据插补方法:均值 / 中位数 / 众数,固定值,最近邻插补,回归方法,插值

插值方法:有 Hermite 插值、分段插值、样条插值法,而最主要的有拉格朗日插值法和牛顿插值法。

** 拉格朗日插值法 代码 ployinterp_column **

拉格朗日插值法可以找到一个 [ _ 多项式 _

](https://baike.baidu.com/item/多项式)
,其恰好在各个观测的点取到观测到的值。这样的多项式称为 ** 拉格朗日(插值)多项式 ** _
_ ** 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) _ #输出结果,写入文件 _

二、 ** 数据集成 : 实体识别,冗余属性识别 **

将多个数据源放在一个统一的数据仓库中。

要考虑实体识别问题和属性冗余问题,从而把源数据在最低层上加以转换、提炼和集成。

**
  1. 实体识别 **

实体识别的任务是检测和解决同名异义、异名同义、单位不统一的冲突。如:

** 同名异义: ** 数据源 A 中的属性 ID 和数据源 B 中的属性 ID 分别描述的是菜品编号和订单编号,即描述的是不同的实体。

** 异名同义: ** 数据源 A 中的 sales_dt 和数据源 B 中的 sales_date 都是是描述销售日期的,即 A.
sales_dt= B. sales_date 。

** 单位不统一 ** :描述同一个实体分别用的是国际单位和中国传统的计量单位。

**
  1. 冗余属性识别 **

数据集成往往导致数据冗余,如: ** 同一属性多次出现 \ 同一属性命名不一致导致重复 **

不同源数据的 ** 仔细整合能减少甚至避免数据冗余与不一致 ** ,以提高数据挖掘的速度和质量。对于冗余属性要先分析检测到后再将其删除。

有些冗余属性可以用相关分析检测到。给定两个数值型的属性 A 和 B ,根据其属性值,可以用相关系数度量一个属性在多大程度上蕴含另一个属性。

一、 ** 数据变换 :简单函数变换 , 规范化,离散化 **

主要是对数据进行规范化的操作,将数据转换成 “适当的”格式,以适用于挖掘任务及算法的需要。

**1. 简单函数变换 **

简单函数变换就是对原始数据进行某些数学函数变换,常用的函数变换包括平方、开方、对数、差分运算等

用来将不具有正太分布的数据变换成具有正太性的数据。
时间序列分析中,对数变换或者差分运算可以将非平稳序列转换为平稳序列

**
  1. 规范化 **

数据标准化(归一化)处理是数据挖掘的一项基础工作,不同评价指标往往具有不同的量纲和量纲单位,数值间的差别可能很大
消除指标间量纲影响

** 最小 - 最大规范化: ** 也称为离差标准化是对原始数据的线性变换,使结果值映射到 [0,1] 之间

** 零 - 均值规范化 : ** 也叫标准差标准化,经过处理的数据的平均数为 0 标准差为 1

** 小数定标规范化 : ** 通过移动属性值的小数位数,将属性值映射到 [-1 , 1] 之间,移动的小数位数取决于属性值绝对值的最大值。

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.mean( axis = 0 )
按照列

_
_ data/ 10 **np.ceil(np.log10(data.abs().max())) _ #小数定标规范化 _

_ _

1. ** 连续属性离散化 **

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

离散化性涉及 ** 两个子任务 ** : 1 需要多少个分类变量 2 确定如何将连续属性值映射到这些分类值。

常用的离散化方法
(1)等宽法
(2)等频法
(3)基于聚类分析的方法

_ #数据规范化:离散化cut,KMeans
_ datafile = ** '../data/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 )]
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_values( by =[ 0 ]) _

.sort()#输出聚类中心,并且排序(默认是随机序的)

_ 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[dj], [j ** for ** i ** in ** d[dj]], ** '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. ** 属性构造 - 构造新的属性 **

_ #新属性构造-输出到excel
_ i nputfile= ** '../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 ** ) _ #保存结果 _

_ _

5. ** 小波变换 代码 **

非平稳序列的分析手段。
基于小波变换的特征提取方法:
(1)基于小波变换的多尺度空间能量分布特征提取法
(2)基于小波变换的多尺度空间的模极大特征值提取法
(3)基于小波变换的特征提取方法
(4)基于适应性小波神经网络的特征提取方法

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个数字,第一个数组为逼近系数数组,后面的依次是细节系数数组 _

二、 ** 数据规约 **

数据规约是将海量数据进行规约,规约之后的数据仍接近于 ** 保持原数据的完整性,但数据量小得多。 **

通过数据规约,可以达到:

降低无效、错误数据对建模的影响,提高建模的准确性

少量且具代表性的数据将大幅缩减数据挖掘所需的时间

降低储存数据的成本 。

**
  1. 属性规约常用方法 : **
**1. 合并属性 2 逐步向前选择 3 逐步向后删除 4 决策树 规约 **
**5 主成分分析降维 代码 **

1 数据矩阵 2 将数据矩阵中心标准化 3 求相关系数矩阵 4 求 R 的特征方程 5 确定主成分个数

6 计算 m 个相应的单位特征向量 7 计算主成分

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_ _ #返回各个成分各自的方差百分比 _

_ 三维 _

pca=PCA(3)

pca.fit(data)

low_d=pca.transform(data)#降维

pd.DataFrame(low_d).to_excel(outputfile)

pca.inverse_transform(low_d)

**2 数值规约 : 分箱,回归,聚类,卡方检验,决策树 **

通过选择替代的、较小的数据来减少数据量,包含有参数方法和无参数方法两类;有参数方法使用模型评估数据,不需要存放真实数据,只需要存放参数,例如回归、对数线性模型。

无参数需要数据,例如直方图、聚类、抽样。

** 五、常用数据预处理函数 **

1.interpolate:一维,高维数据插值
f.scipy.interpolate.lagrange(x,y)
2.unique:去除重复元素
np.unique(D)
D.unique( )

** import ** pandas ** as ** pd
** import ** numpy ** as ** np
D=pd.Series([ 1 , 1 , 2 , 3 , 5 ])
d1=D.unique()
d2 =np.unique(D)
print ** "d1 is: \n " ** ,d1
print ** "d2 is: \n " ** , d2

3.isnull/notnull:判断空值/非空值
4.random:生成随机矩阵
k x m x n维0-1之间;
np.random.rand(k,m,n…)
k x m x n维,正态分布;
np.random.randn(k,m,n)
5.PCA:主成分分析

** 第 5 章:挖掘建模 **

**cmplot 混淆矩阵,看 spe , **

_ # -- coding: utf-8 --
_ ** def ** cm_plot(y, yp):
** from ** sklearn.metrics ** import ** confusion_matrix _ # 导入混淆矩阵函数
_ cm = confusion_matrix(y, yp) _ # 混淆矩阵 _

_
_ ** import ** matplotlib.pyplot ** as ** plt _ # 导入作图库
_ plt.matshow(cm, cmap =plt.cm.Greens) _ #
画混淆矩阵图,配色风格使用cm.Greens,更多风格请参考官网。
_ plt.colorbar() _ # 颜色标签

_ ** for ** x ** in ** range ( len (cm)): _ # 数据标签
_ ** for ** y ** in ** range ( len (cm)):
plt.annotate(cm[x, y], xy =(x, y), horizontalalignment = ** 'center' **
, verticalalignment = ** 'center' ** )

plt.ylabel( ** 'True label' ** ) _ # 坐标轴标签
_ plt.xlabel( ** 'Predicted label' ** ) _ # 坐标轴标签
_ ** return ** plt

**1 分类与预测 **

** 算法与模型 **

算法:回归分析( logistics , LDA ),决策树,神经网络,贝叶斯, svm ,随机森林

常用回归模型:逻辑回归,(非)线性回归,岭回归,主成分回归, logistics 回归

**1 、逻辑回归 **

_ #-- coding: utf-8 --

逻辑回归 自动建模

_ ** import ** pandas ** as ** pd

_ #参数初始化
_ filename = ** '../data/bankloan.xls'
** data = pd.read_excel(filename)
x = data.iloc[:,: 8 ].as_matrix()
y = data.iloc[:, 8 ].as_matrix()

** from ** sklearn.linear_model ** import ** LogisticRegression ** as **
LR
** from ** sklearn.linear_model ** import ** RandomizedLogisticRegression
** as ** RLR
rlr = RLR() _ #建立随机逻辑回归模型,筛选变量
_ rlr.fit(x, y) _ #训练模型
_ rlr.get_support() _ #获取特征筛选结果,也可以通过.scores_方法获取各个特征的分数
_ print ( ** u'通过随机逻辑回归模型筛选特征结束。' ** )
print ( ** u'有效特征为:%s' ** % ** ',' **
.join(data.columns[rlr.get_support()]))
x = data[data.columns[rlr.get_support()]].as_matrix() _ #筛选好特征

_ lr = LR() _ #建立逻辑货柜模型
_ lr.fit(x, y) _ #用筛选后的特征数据来训练模型
_ print ( ** u'逻辑回归模型训练结束。' ** )
print ( ** u'模型的平均正确率为:%s' ** % lr.score(x, y)) _ #给出模型的平均正确率,本例为81.4% _

Scikit-learn 提供了 RFE 包,用于特征消除,还提供了 RFECV 通过交叉验证进行特征排序

2、 ** 决策树 ID3,C4.5 , CART **

**ID3 决策树 **

ID3 算法是一种基于信息熵的决策树分类算法,它选择当前样本集中具有最大信息增益值的属性作为测试属性选择增益最大

_ #-- coding: utf-8 --

使用ID3决策树算法预测销量高低

_ ** import ** pandas ** as ** pd

_ #参数初始化
_ inputfile = ** '../data/sales_data.xls'
** data = pd.read_excel(inputfile, index_col = ** u'序号' ** ) _ #导入数据

数据是类别标签,要将它转换为数据

用1来表示“好”、“是”、“高”这三个属性,用-1来表示“坏”、“否”、“低”

_ data[data == ** u'好' ** ] = 1
data[data == ** u'是' ** ] = 1
data[data == ** u'高' ** ] = 1
data[data != 1 ] = - 1
x = data.iloc[:,: 3 ].as_matrix().astype( int )
y = data.iloc[:, 3 ].as_matrix().astype( int )

** from ** sklearn.tree ** import ** DecisionTreeClassifier ** as ** DTC
dtc = DTC( criterion = ** 'entropy' ** ) _ #建立决策树模型,基于信息熵
_ dtc.fit(x, y) _ #训练模型

导入相关函数,可视化决策树。

导出的结果是一个dot文件,需要安装Graphviz才能将它转换为pdf或png等格式。

_ ** from ** sklearn.tree ** import ** export_graphviz
** from ** sklearn.externals.six ** import ** StringIO
** with ** open ( ** "tree.dot" ** , ** 'w' ** ) ** as ** f:
f = export_graphviz(dtc, feature_names = x.columns, out_file = f)

图 2

**CART 决策树模型 **

_ #-- coding: utf-8 --

构建并测试CART决策树模型

_ ** import ** pandas ** as ** pd _ #导入数据分析库
_ ** from ** random ** import ** shuffle _ #导入随机函数shuffle,用来打算数据

_ datafile = ** '../data/model.xls' ** _ #数据名
_ data = pd.read_excel(datafile) _ #读取数据,数据的前三列是特征,第四列是标签
_ data = data.as_matrix() _ #将表格转换为矩阵
_ shuffle(data) _ #随机打乱数据

_ p = 0.8 _ #设置训练数据比例
_ train = data[: int ( len (data)p),:] _ #前80%为训练集
_ test = data[ int ( len (data)
p):,:] _ #后20%为测试集

构建CART决策树模型

_ ** from ** sklearn.tree ** import ** DecisionTreeClassifier _ #导入决策树模型

_ treefile = ** '../tmp/tree.pkl' ** _ #模型输出名字
_ tree = DecisionTreeClassifier() _ #建立决策树模型
_ tree.fit(train[:,: 3 ], train[:, 3 ]) _ #训练

保存模型

_ ** from ** sklearn.externals ** import ** joblib
joblib.dump(tree, treefile)

** from ** cm_plot ** import ** * _ #导入自行编写的混淆矩阵可视化函数
_ cm_plot(train[:, 3 ], tree.predict(train[:,: 3 ])).show() _

显示混淆矩阵可视化结果

注意到Scikit-Learn使用predict方法直接给出预测结果。

_ ** from ** sklearn.metrics ** import ** roc_curve _ #导入ROC曲线函数

_ fpr, tpr, thresholds = roc_curve(test[:, 3 ], tree.predict_proba(test[:,:
3 ])[:, 1 ], pos_label = 1 )
plt.plot(fpr, tpr, linewidth = 2 , label = ** 'ROC of CART' ** ,
color = ** 'green' ** ) _ #作出ROC曲线
_ plt.xlabel( ** 'False Positive Rate' ** ) _ #坐标轴标签
_ plt.ylabel( ** 'True Positive Rate' ** ) _ #坐标轴标签
_ plt.ylim( 0 , 1.05 ) _ #边界范围
_ plt.xlim( 0 , 1.05 ) _ #边界范围
_ plt.legend( loc = 4 ) _ #图例
_ plt.show() _ #显示作图结果 _

3、 ** 人工神经网络 BP\LM\RBF\FNN\GMDH\ANFIS **

_ #-- coding: utf-8 --

使用神经网络算法预测销量高低,用sales_data.xls

_ ** from ** keras.models ** import ** Sequential
** from ** keras.layers.core ** import ** Dense, Activation

model = Sequential() _ #建立模型
_ model.add(Dense( 10 , input_dim = 3 )) _ #三个输入,10个隐藏,1一个输出
_ model.add(Activation( ** 'relu' ** )) _ #用relu函数作为激活函数,能够大幅提供准确度
_ model.add(Dense( 1 , input_dim = 10 ))
model.add(Activation( ** 'sigmoid' ** )) _ #由于是0-1输出,用sigmoid函数作为激活函数

_ model.compile( loss = ** 'binary_crossentropy' ** , optimizer = **
'adam' ** ) # class_mode = ** 'binary' **
_ #编译模型。由于我们做的是二元分类,所以我们指定损失函数为binary_crossentropy,以及模式为binary

另外常见的损失函数还有mean_squared_error、categorical_crossentropy等,请阅读帮助文件。

求解方法我们指定用adam,还有sgd、rmsprop等可选

_ model.fit(x, y, epochs = 1000 , batch_size = 10 ) _

训练模型,学习一千次,x训练失败?

_ yp = model.predict_classes(x).reshape( len (y)) _ #分类预测

_ ** from ** cm_plot ** import ** * _ #导入自行编写的混淆矩阵可视化函数
_ cm_plot(y,yp).show() _ #显示混淆矩阵可视化结果 _

**2 聚类分析: **

** 划分方法(常用: kmean 算法 , k 中心点),系统聚类,层次聚类,谱聚类,基于密度 / 网格 /

模型的聚类,均值漂移聚类:用 scikit-learn , spicy.cluster 也有很多 **

**kmeans 聚类算法过程: **

1 )从 N 个样本数据中随机选取 K 个对象作为初始的聚类中心;

2 )分别计算每个样本到各个聚类中心的距离,将对象分配到距离最近的聚类中;

3 )所有对象分配完成后,重新计算 K 个聚类的中心;

4 )与前一次计算得到的 K 个聚类中心比较,如果聚类中心发生变化,转 2) ,否则转 5) ;

5 )当质心不发生变化时停止并输出聚类结果。

( ** 连续属性: ** 度量样本之间的相似性最常用的是欧几里得距离、曼哈顿距离和闵可夫斯基距离, ** 文档数据: **
使用余弦相似性度量,先将文档数据整理成文档 —词矩阵格式)

误差平方和 SSE

** import ** pandas ** as ** pd

_ #参数初始化
_ inputfile = ** '../data/consumption_data.xls' ** _ #销量及其他属性数据
_ outputfile = ** '../tmp/data_type.xls' ** _ #保存结果的文件名
_ k = 3 _ #聚类的类别
_ iteration = 500 _ #聚类最大循环次数
_ data = pd.read_excel(inputfile, index_col = ** 'Id' ** ) _ #读取数据
_ data_zs = 1.0 *(data - data.mean())/data.std() _ #数据标准化

_ ** from ** sklearn.cluster ** import ** KMeans
** if ** name== ** 'main' ** : _ #加入此行代码即可
_ model = KMeans( n_clusters = k, n_jobs = 4 , max_iter = iteration)
_ #分为k类,并发数4
_ model.fit(data_zs) _ #开始聚类, you must protect your main loop using "if
name == 'main'".

简单打印结果

_ r1 = pd.Series(model.labels_).value_counts() _ #统计各个类别的数目
_ r2 = pd.DataFrame(model.cluster_centers_) _ #找出聚类中心
_ r = pd.concat([r2, r1], axis = 1 ) _ #横向连接(0是纵向),得到聚类中心对应的类别下的数目
_ r.columns = list (data.columns) + [ ** u'类别数目' ** ] _ #重命名表头
_ ** print ** (r)

_ #详细输出原始数据及其类别
_ r = pd.concat([data, pd.Series(model.labels_, index = data.index)], axis
= 1 ) _ #详细输出每个样本对应的类别
_ r.columns = list (data.columns) + [ ** u'聚类类别' ** ] _ #重命名表头
_ r.to_excel(outputfile) _ #保存结果 _

** 绘制聚类后的概率密度图 **

_
_ ** def ** density_plot(data): _ #自定义作图函数
_ p = data.plot( kind = ** 'kde' ** , linewidth = 2 , subplots = **
True ** , sharex = ** False ** )
[p[i].set_ylabel( ** u'密度' ** ) ** for ** i ** in ** range (k)]
plt.legend()
** return ** plt

pic_output = ** '../tmp/pd_' ** _ #概率密度图文件名前缀
_ ** for ** i ** in ** range (k):
density_plot(data[r[ ** u'聚类类别' ** ]==i]).savefig( ** u'%s%s.png' **
%(pic_output, i))

** for ** i ** in ** range ( len (data.iloc[ 0 ])): _ #逐列作图
_ (data.iloc[:,i]).plot( kind = ** 'kde' ** , linewidth = 2 , label
=data.columns[i])

** 聚类后算法评价 **

Purity 评价法:正确聚类占总数比例

RI 评价

F 值评价

** 聚类可视化 TSNE **

_ # 接 kmeans.py _

** from ** sklearn.manifold ** import ** TSNE
** import ** matplotlib.pyplot ** as ** plt

tsne = TSNE()
tsne.fit_transform(data_zs) _ #进行数据降维
_ tsne = pd.DataFrame(tsne.embedding_, index = data_zs.index) _ #转换数据格式

不同类别用不同颜色和样式绘图

_ d = tsne[r[ ** u'聚类类别' ** ] == 0 ] _ #a=r[u'聚类类别'] ==
0,dtype('bool'),r:oject,r.columns:Index([u'R', u'F', u'M', u'聚类类别'],
dtype='object')
_ plt.plot(d[ 0 ], d[ 1 ], ** 'r.' ** )
d = tsne[r[ ** u'聚类类别' ** ] == 1 ]
plt.plot(d[ 0 ], d[ 1 ], ** 'go' ** )
d = tsne[r[ ** u'聚类类别' ** ] == 2 ]
plt.plot(d[ 0 ], d[ 1 ], ** 'b*' ** )
plt.show()

**3 关联规则 aprior,FP-TREE **

( 1 )关联规则的一般形式

支持度:项集 A 、 B 同时发生的概率

置信度:项集 A 发生,则项集 B 也同时发生的概率

( 2 )最小支持度和最小置信度

最小支持度:一个阈值,表示项目集在统计意义上的最低重要性;

最小置信度:一个阈值表示关联规则的最低可靠性。

同时满足最小支持度阈值和最小置信度阈值的规则称作强规则。

** 函数文件 apirior.py **

过程一:找出所有的频繁项集。

过程二:由频繁项集产生强关联规则 _
_ ** def ** connect_string(x, ms):
x = list ( map ( ** lambda ** i: sorted (i.split(ms)), x))
l = len (x[ 0 ])
r = []
** for ** i ** in ** range ( len (x)):
** for ** j ** in ** range (i, len (x)):
** if ** x[i][:l - 1 ] == x[j][:l - 1 ] ** and ** x[i][l - 1 ] !=
x[j][l - 1 ]:
r.append(x[i][:l - 1 ] + sorted ([x[j][l - 1 ], x[i][l - 1 ]]))
** return ** r

_ # 寻找关联规则的函数
_ ** def ** find_rule(d, support, confidence, ms= ** u'--' ** ):
result = pd.DataFrame( index =[ ** 'support' ** , ** 'confidence' ** ])
_ # 定义输出结果

_ support_series = 1.0 * d.sum() / len (d) _ # 支持度序列
_ column = list (support_series[support_series > support].index) _ #
初步根据支持度筛选
_ k = 0

** while ** len (column) > 1 :
k = k + 1
print ( ** u' \n 正在进行第 %s次搜索...' ** % k)
column = connect_string(column, ms)
print ( ** u'数目:%s...' ** % len (column))
sf = ** lambda ** i: d[i].prod( axis = 1 , numeric_only = ** True **
) _ # 新一批支持度的计算函数

创建连接数据,这一步耗时、耗内存最严重。当数据集较大时,可以考虑并行运算优化。

_ d_2 = pd.DataFrame( list ( map (sf, column)), index =[ms.join(i) **
for ** i ** in ** column]).T

support_series_2 = 1.0 * d_2[[ms.join(i) ** for ** i ** in **
column]].sum() / len (d) _ # 计算连接后的支持度
_ column = list (support_series_2[support_series_2 > support].index) _ #
新一轮支持度筛选
_ support_series = support_series.append(support_series_2)
column2 = []

** for ** i ** in ** column: _ #
遍历可能的推理,如{A,B,C}究竟是A+B-->C还是B+C-->A还是C+A-->B?
_ i = i.split(ms)
** for ** j ** in ** range ( len (i)):
column2.append(i[:j] + i[j + 1 :] + i[j:j + 1 ])

cofidence_series = pd.Series( index =[ms.join(i) ** for ** i ** in **
column2]) _ # 定义置信度序列

_ ** for ** i ** in ** column2: _ # 计算置信度序列
_ cofidence_series[ms.join(i)] = support_series[ms.join( sorted (i))] /
support_series[ms.join(i[: len (i) - 1 ])]

** for ** i ** in ** cofidence_series[cofidence_series > confidence].index:
_ # 置信度筛选
_ result [i] = 0.0
result [i][ ** 'confidence' ** ] = cofidence_series[i]
result [i][ ** 'support' ** ] = support_series[ms.join( sorted
(i.split(ms)))]

result = result .T.sort([ ** 'confidence' ** , ** 'support' ** ],
ascending = ** False ** ) _ # 结果整理,输出
_ print ( ** u' \n 结果为: ' ** )
print ( result )

** return ** result

** 使用 Apriori 算法挖掘菜品订单关联规则 **

_ #-- coding: utf-8 --

使用Apriori算法挖掘菜品订单关联规则

_ ** from ** future ** import ** print_function
** import ** pandas ** as ** pd
** from ** apriori ** import ** * _ #导入自行编写的apriori函数

_ inputfile = ** '../data/menu_orders.xls'
** outputfile = ** '../tmp/apriori_rules.xls' ** _ #结果文件
_ data = pd.read_excel(inputfile, header = ** None ** )

**

** 代码好 - 转换原始数据至 0-1矩阵...' ) ? 有问题

ct = lambda x : pd.Series( 1 , index = x[pd.notnull(x)]) _

转换0-1矩阵的过渡函数

_ b = map (ct, data.as_matrix()) _ #用map方式执行
_ data = pd.DataFrame( list (b)).fillna( 0 ) _ #实现矩阵转换,空值用0填充
_ print ( u' \n 转换完毕。 ' )
del b _ #删除中间变量b,节省内存

_ support = 0.2 _ #最小支持度
_ confidence = 0.5 _ #最小置信度
_ ms = ** '---' ** _ #连接符,默认'--',用来区分不同元素,如A--B。需要保证原始表格中不含有该字符

_ find_rule(data, support, confidence, ms).to_excel(outputfile) _ #保存结果 _

**4 时序模式: **

常见的时间序列模型 平滑,趋势拟合法,组合(加法,乘法)、 AR 、 MA,ARMA,ARIMA,ARCH,GARCH ,将重点介绍 AR
模型、 MA 模型、 ARMA 模型和 ARIMA 模型。

** 时间序列的预处理(随机 + 平稳) **

拿到一个观察值序列后, ** 首先要对它的 纯随机性和平稳性 进行检验,这两个重要的检验称为序列的预处理。 **
根据检验结果可以将序列分为不同的类型,对不同类型的序列会采取不同的分析方法。

对于纯随机序列,又叫白噪声序列 ,就意味着序列的各项之间没有任何相关关系,序列在进行完全无序的随机波动,可以终止对该序列的分析。

对于平稳非白噪声序列, 它的均值和方差是常数,现已有一套非常成熟的平稳序列的建模方法。通常是建立一个线性模型来拟合该序列的发展,借此提取该序列的有用信息。
ARMA 模型是最常用的平稳序列拟合模型;

对于非平稳序列, 由于它的均值和方差不稳定,处理方法一般是将其转变为平稳序列,这样就可以应用有关平稳时间序列的分析方法,如建立 ARMA
模型来进行相应得研究。如果一个时间序列经差分运算后具有平稳性,成该序列为差分平稳序列,可以使用 ARIMA 模型进行分析。

1 平稳性检验

对序列的平稳性的检验有两种检验方法,一种是 ** 根据时序图和自相关图的特征做出判断的图 **
检验,该方法操作简单、应用广泛,缺点是带有主观性;另一种是构造检验统计量进行的方法,目前最常用的方法是 ** 单位根检验 **

** ( 1 )时序图检验:如果有明显的趋势性或者周期性那它通常不是平稳序列。 **

( 2 )自相关图检验 **_ (常用) _ **

平稳序列具有短期相关性,随着延迟期数的增加,平稳序列的自相关系数 会比较快的衰减趋向于零,并在零附近随机波动,而非平稳序列的自相关系数衰减的速度比较慢

( 3 )单位根检验是指检验序列中是否存在单位根,因为存在单位根就是非平稳时间序列了。 p 值显著大于 0.05=== 非平稳(不是白噪声)

2 纯随机性检验

纯随机性检验也称 **_ 白噪声检验 _ , ** 一般是构造检验统计量来检验序列的纯随机性,常用的检验统计量有 Q 统计量、 LB
统计量,计算出对应的 p 值,如果 p 值显著大于显著性水平 , 则表示该序列不能拒绝纯随机的原假设,可以停止对该序列的分析。

** 平稳时间序列分析 ARMA **

ARMA 模型的全称是自回归移动平均模型,它是目前最常用的拟合平稳序列的模型。

ARMA 模型又可以细分为 AR 模型、 MA 模型和 ARMA 模型三大类。都可以看作是多元线性回归模型。

下面将分别介绍 AR 模型、 MA 模型和 ARMA 模型三大模型。

** 平稳时间序列的 ARMA 模型建模步骤。 **

某个时间序列经过 预处理,被判定为平稳非白噪声序列,就可以利用 ARMA 模型进行建模。

由 AR 模型、 MA 模型和 ARMA 模型的自相关系数和偏自相关系数的性质,选择出合适的模型。

**AR 、 MA 和 ARMA 模型自相关系数和偏自相关系数的性质如下: **

AR模型:自相关系数拖尾,偏自相关系数截尾;

MA模型:自相关系数截尾,偏自相关函数拖尾;

ARMA模型:自相关函数和偏自相关函数均拖尾。

** 非平稳时间序列分析 ARIMA **

对非平稳时间序列的分析方法可以分为确定性因素分解的时序分析和随机时序分析两大类 。

** 确定性因素分解 ** 的方法把所有序列的变化都归结为四个因素(长期趋势、季节变动、循环变动和随机波动)的综合影响。可以建立加法模型和乘法模型等。

根据时间序列的不同特点, ** 随机时序分析 ** 可以建立的模型有 ARIMA 模型、残差自回归模型、季节模型、异方差模型等。

1、p 阶差分 : 相距一期的两个序 列值之间的减法运算称为 1 阶差分运算;

2、k 步差分 : 相距 k 期的两个序列值之间的减法运算称为 k 步差分运算。

3、 差分运算具有强大的确定性信息提取能力,许多非平稳序列差分后会显示出平稳序列的性质,这时称这个非平稳序列为差分平稳序列。

4、 对差分平稳序列可以使用 ARMA模型进行拟合。

5、ARIMA模型的实质就是差分运算与ARMA模型的组合,掌握了ARMA模型的建模方法和步骤以后,对序列建立ARIMA模型是比较简单的。

** 建模步骤: ( 代码问题 ) **

_ _

** 建模步骤 **

** 计算 ACF 和 PACF( 自相关图平稳性检验 + 白噪声 **

先计算非平稳白噪声序列的自相关系数( ACF )和偏自相关系数( PACF )

不平稳差分后再用 ARIMA 模型

** import ** pandas ** as ** pd
_ #读取数据,指定日期列为指标,Pandas自动将“日期”列识别为Datetime格式
_ discfile = ** '../data/arima_data.xls'
** forecastnum = 5 _
_ data = pd .read_excel(discfile, index_col = ** u'日期' ** ) _
_ ** import ** matplotlib.pyplot ** as ** plt _
_ data.plot()
plt.show()

**

_ #自相关图 和偏自相关图选择模型 _ **

_
_ ** from ** scipy ** import ** stats
** import ** matplotlibt.py p lot ** as ** plt
** import ** statsmodels.api ** as ** sm
** from ** statsmodels.graphics.api ** import ** qqplot

fig=sm.graphic.tsa.plot_acf(dta, lags = 40 , ax =ax1)
fig = sm.graphics.tsa.plot_pacf(dta, lags = 40 , ax =ax2)
_ # 一阶差分后的自相关图与偏自相关图
_ dta = dta.diff( 1 ).dropna() _ # 注意一定要将查分后的空值去掉再取自相关系数
_ fig = sm.graphics.tsa.plot_acf(dta, lags = 40 , ax =ax3)
fig = sm.graphics.tsa.plot_pacf(dta, lags = 40 , ax =ax4)

**# 平稳性检测 # 白噪声检验 **

_
_ ** from ** statsmodels.tsa.stattools ** import ** adfuller ** as ** ADF
print ( ** u'原始序列的ADF检验结果为:' ** , ADF(data[ ** u'销量' ** ]))
_ #返回值依次为adf、pvalue、usedlag、nobs、critical values、icbest、regresults、resstore
_ D_data=data.diff().dropna()
D_data.columns=[ ** u'销量差分' ** ] _
_ ** from ** statsmodels.stats.diagnostic ** import ** acorr_ljungbox
print ( ** u'差分序列的白噪声检验结果为:' ** , acorr_ljungbox(D_data, lags = 1 )) _

返回统计量和p值

_ ** from ** statsmodels.tsa.arima_model ** import ** ARIMA

_ #定阶
_ pmax = int ( len (D_data)/ 10 ) _ #一般阶数不超过length/10
_ qmax = int ( len (D_data)/ 10 ) _ #一般阶数不超过length/10
_ bic_matrix = [] _ #bic矩阵
_ ** for ** p ** in ** range (pmax+ 1 ):
tmp = []
** for ** q ** in ** range (qmax+ 1 ):
** try ** : _ #存在部分报错,所以用try来跳过报错。
_ tmp.append(ARIMA(data, (p, 1 ,q)).fit().bic)
** except ** :
tmp.append( ** None ** )
bic_matrix.append(tmp)

bic_matrix = pd .DataFrame(bic_matrix) _ #从中可以找出最小值
_ p,q = bic_matrix.stack().idxmin() _ #先用stack展平,然后用idxmin找出最小值位置。
_ print ( ** u'BIC最小的p值和q值为:%s、%s' ** %(p,q))

**ARMA 模型识别 **

由 AR 模型、 MA 模型和 ARMA 模型的自相关系数和偏自相关系数的性质,选择出合适的模型。

** 模型定阶 AIC :确定 p 和 q **

(1) 人为识别的方法: 用相关图像 根据 ARMA模型识别原则进行模型定阶

(2) 第二种方法:相对最优模型识别。

计算 ARMA(p,q)当 p 和 q 均小于等于 5 的所有组合的 BIC 信息量,取其中 BIC 信息量达到最小的模型阶数。ARIMA(P ,
1,Q )

** 模型检验 **

确定模型后,需要检验其残差序列是否是白噪声,若 ** 不是 ** ,说明,残差中还存在有用的信息, ** 需要修改模型或者进一步提取 **
。若其残差不是白噪声,重新更换 p,q 的值,重新确定

p 值为: 0.627016 ,大于 0.05 , ** 残差 ** 为白噪声序列,模型通过检验。

** 模型预测 **

只能进行短期预测

model = ARIMA(data, (p, 1 ,q)).fit() _ #建立ARIMA(0, 1, 1)模型
_ model .summary2() _ #给出一份模型报告
_ model .forecast( 5 )

** 模型优化与应用 **

**5 离群点检测 **

threshold= 2
norm = []
** for ** i ** in ** range (k): _ #逐一处理
_ norm_tmp = r[[ ** 'R' ** , ** 'F' ** , ** 'M' ** ]][r[ ** u'聚类类别' ** ] == i]-model.cluster_centers_[i]
norm_tmp = norm_tmp.apply(np.linalg.norm, axis = 1 ) _ #求出绝对距离
_ norm.append(norm_tmp/norm_tmp.median()) _ #求相对距离并添加

norm = pd.concat(norm) #合并

_ norm[norm <= threshold].plot( style = ** 'go' ** ) _ #正常点
_ discrete_points = norm[norm > threshold] _ #离群点
_ discrete_points.plot( style = ** 'ro' ** )

** for ** i ** in ** range ( len (discrete_points)): _ #离群点做标记
_ id = discrete_points.index[i]
n = discrete_points.iloc[i]
plt.annotate( ** '(%s, %0.2f)' ** %(id, n), xy = (id, n), xytext = (id,
n))

plt.xlabel( ** u'编号' ** )
plt.ylabel( ** u'相对距离' ** )
plt.show()

在这里插入图片描述

posted @ 2021-06-28 14:59  老酱  阅读(425)  评论(0编辑  收藏  举报