期末复习
数据挖掘 数据挖掘基本任务 数据挖掘的基本任务包括利用分类与预测、聚类分析、关联规则、时序模式、偏差检测、智能推荐等方法,帮助企业提取数据中蕴含的商业价值,提高企业的竞争力。
数据挖掘建模过程
定义挖掘目标
数据取样
数据探索
数据预处理
挖掘建模
模型评价
1.目标定义
任务理解
指标明确
2.数据采集
建模抽样
质量把控
实时采集
3.数据整理
数据探索
数据清洗
数据变换
4.构建模型
模式发现
构建模型
验证模型
5.模型评价
设定评价标准
多模型对比
模型优化
6.模型发布
模型部署
模型重构
第三章 数据探索 P39 需要考虑的问题
样本数据集的数量和质量是否满足模型构建的要求?
有没有出现从未设想过的数据状态?
其中有没有明显的规律和趋势?
各因素之间有什么样的关联性?
1.数据质量分析 主要任务 检查原始数据中是否存在脏数据,脏数据一般指不符合要求以及不能直接进行相应分析的数据,如缺失值、异常值、不一致值、重复数据及含有特殊符号的数据
缺失值分析 产生的原因
信息暂时无法获取,或者获取信息的代价太大
信息被遗漏,包括人为因素遗漏及数据采集设备故障导致的非人为因素遗漏
属性值不存在,如一个未婚者的配偶姓名,一个儿童的固定收入
缺失值的影响
数据挖掘建模将丢失大量的有用信息
数据挖掘模型所变现出的不确定性更加显著,规律更难把握
包含空值的数据回事建模过程陷入混乱,导致不可靠的输出
缺失值的分析
使用简单的统计分析,可以得到含有缺失值的属性的个数及每个属性的未缺失数、缺失数与缺失率等
对缺失值的处理
异常值分析 异常值分析是检验数据是否有录入错误,是否含有不合常理的数据。
异常值是指样本中的个别值,其数值明显偏离其他的观测值。
异常值也称为离群点 ,异常值分析也称为离群点分析
1. 简单统计量分析 对变量进行描述性统计,进而查看哪些数据是不合理的,如统计最大值和最小值,用来判断这个变量的取值是否超出了合理范围。
2. 3σ准则
在 正态分布 中σ代表 标准差 ,μ代表 均值 。x=μ即为图像的对称轴 3σ原则为 数值分布在(μ-σ,μ+σ)中的概率为0.6826 数值分布在(μ-2σ,μ+2σ)中的概率为0.9544 数值分布在(μ-3σ,μ+3σ)中的概率为0.9974 可以认为,Y 的取值几乎全部集中在(μ-3σ,μ+3σ)] 区间 内,超出这个范围的可能性仅占不到0.3%.
3σ准则是建立在正态分布的等精度重复测量基础上而造成奇异数据的干扰或噪声难以满足正态分布.如果一组测量数据中某个测量值的残余误差的绝对值 νi>3σ,则该测量值为坏值,应剔除.通常把等于 ±3σ的误差作为极限误差,对于正态分布的随机误差,落在 ±3σ以外的概率只有 0.27%,它在有限次测量中发生的可能性很小,故存在3σ准则.3σ准则是最常用也是最简单的粗大误差判别准则,它一般应用于测量次数充分多( n ≥30)或当 n>10做粗略判别时的情况.
3. 箱型图分析 箱形图依据实际数据绘制,不需要事先假定数据服从特定的分布形式,没有对数据作任何限制性要求,它只是真实直观地表现数据分布的本来面貌;另一方面,箱形图判断异常值的标准以四分位数和四分位距为基础,四分位数具有一定的鲁棒性:多达25%的数据可以变得任意远而不会很大地扰动四分位数,所以异常值不能对这个标准施加影响,箱形图识别异常值的结果比较客观。由此可见,箱形图在识别异常值方面有一定的优越性。
一致性分析 数据不一致性是指数据的矛盾性、不相容性。直接对不一致的数据进行挖掘,可能会产生与实际相违背的挖掘结果。
在数据挖掘过程中,不一致的数据的产生主要发生在数据集成的过程中,可能是由于被挖掘数据来自于不同的数据源,对于重复存放的数据未能进行一致性更新造成的,比如两张表中都存储了用户的地址,在用户的地址发生改变时,如果只更新了一张表中的数据,那么这两张表中就有了不一致的数据。
2. 数据特征分析 1. 分布分析 1. 定量数据的分布分析
求极差
决定组距和组数
决定分点
列出频率分布表
绘制频率分布直方图
要求
各组之间必须是相互排斥的
各组必须将所有的数据包括在内
各组的组宽最好相等
2. 定性数据分析 对于定性变量,常常根据变量的分类类型来分组。
2. 对比分析
绝对数比较
相对数比较
结构相对数:将同一总体内的部分数值与全部数值进行对比求得比重,用以说明事物的性质、结构或质量
比例相对数:将同一总体内不同部分的数值进行对比,表明总体内各部分的比例关系。
比较相对数:将同一时期两个性质相同的指标数值进行对比,说明同类现象在不同空间条件下的数量对比关系。
强度相对数:将两个性质不同但有一定联系的总量指标进行对比,用以说明现象的强度、密度和普遍程度。
计划完成程度相对数:将某一时期实际完成数与计划完成数进行对比用以说明计划完成程度。
动态相对数:将同一现象在不同时期的指标数值进行对比,用以说明发展法向和变化速度,如发展速度、增长速度等。
3. 统计量分析 1. 集中趋势程度
均值
中位数
众数
2. 离中趋势度量
极差
标准差
变异系数
四分位数间距
4. 周期性分析 周期性分析是探索某个变量是否随着时间的变化而呈现出某种周期变化趋势。
5. 贡献度分析 贡献度分析又称帕累托分析,它的原理是帕累托法则,又称20/80定律。同样的投入放在不同的地方会产生不同的效益,例如,对一个公司来讲,80%的利润常常来自于20%最畅销的产品,而其他80%的产品只产生了20%的利润。
6. 相关性分析 1. 直接绘制散点图 判断两个变量是否具有线性相关关系最直观的方法 是直接绘制散点图
2. 绘制散点图矩阵 3. 计算相关系数 为了更加准确地描述变量之间的线性相关程度,可以通过相关系数的计算来进行相关分析
Pearson相关系数(要求连续变量的取值服从正态分布)
Spearman秩相关系数(不服从正态分布的变量或等级变量之间的关系)
判定系数,判定系数是相关系数的平方,用$r^2$表示。$r^2$越接近1,表明x与y之间的相关性越强,$r^2$越接近0,表明x与y之间几乎没有直线相关关系
Python主要数据探索函数 1. 基本统计特征函数
方法名
函数功能
所属库
sum()
计算数据样本的总和
pandas
mean()
计算数据样本的算术平均数
pandas
var()
计算数据样本的方差
pandas
std()
计算数据样本的标准差
pandas
corr()
计算数据样本的Spearman(Pearson)相关系数矩阵
pandas
cov()
计算数据样本的协方差矩阵
pandas
skew()
样本值的偏度(三阶矩)
pandas
kurt()
样本值的峰度(四阶矩)
pandas
describe()
给出样本的基本描述(基本统计量如均值、标准差等)
pandas
2. 拓展统计特征函数 累计计算(cum
)和滚动计算(pd.rolling_
),如cumsum()
依次给出前1,2,… n个数的和,rolling(2).sum()
依次对相邻的两项求和
3. 统计绘图函数
绘图函数名
绘图函数功能
所属工具箱
plot()
绘制线性二维图,折线图
Matplotlib/pandas
pie()
绘制饼图
Matplotlib/pandas
hist()
绘制二维条形直方图,可显示数据的分配情形
Matplotlib/pandas
boxplot()
绘制样本数据的箱型图
pandas
plot(logy = True)
绘制y轴的对数图形
pandas
plot(yerr = error)
绘制误差条形图
pandas
4. 代码实例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 import pandas as pdD = pd.DataFrame([range(1 , 8 ), range(2 , 9 )]) print(D.corr(method='spearman' )) S1 = D.loc[0 ] S2 = D.loc[1 ] print(S1.corr(S2, method='pearson' )) import numpy as npD = pd.DataFrame(np.random.randn(6 , 5 )) print(D.cov()) print(D[0 ].cov(D[1 ])) import numpy as npD = pd.DataFrame(np.random.randn(6 , 5 )) print(D.skew()) print(D.kurt()) import numpy as npD = pd.DataFrame(np.random.randn(6 , 5 )) print(D.describe()) D=pd.Series(range(0 , 20 )) print(D.cumsum()) print(D.rolling(2 ).sum()) import matplotlib.pyplot as plt plt.rcParams['font.sans-serif' ] = ['SimHei' ] plt.rcParams['axes.unicode_minus' ] = False plt.figure(figsize = (7 , 5 )) import numpy as npx = np.linspace(0 ,2 *np.pi,50 ) y = np.sin(x) plt.plot(x, y, 'bp--' ) plt.show() import matplotlib.pyplot as pltlabels = 'Frogs' , 'Hogs' , 'Dogs' , 'Logs' sizes = [15 , 30 , 45 , 10 ] colors = ['yellowgreen' , 'gold' , 'lightskyblue' , 'lightcoral' ] explode = (0 , 0.1 , 0 , 0 ) plt.pie(sizes, explode=explode, labels=labels, colors=colors, autopct='%1.1f%%' , shadow=True , startangle=90 ) plt.axis('equal' ) plt.show() import matplotlib.pyplot as pltimport numpy as npx = np.random.randn(1000 ) plt.hist(x, 10 ) plt.show() import matplotlib.pyplot as pltimport numpy as npimport pandas as pdx = np.random.randn(1000 ) D = pd.DataFrame([x, x+1 ]).T D.plot(kind = 'box' ) plt.show() import matplotlib.pyplot as pltplt.rcParams['font.sans-serif' ] = ['SimHei' ] plt.rcParams['axes.unicode_minus' ] = False import numpy as npimport pandas as pdx = pd.Series(np.exp(np.arange(20 ))) plt.figure(figsize = (8 , 9 )) ax1 = plt.subplot(2 , 1 , 1 ) x.plot(label = u'原始数据图' , legend = True ) ax1 = plt.subplot(2 , 1 , 2 ) x.plot(logy = True , label = u'对数数据图' , legend = True ) plt.show() import matplotlib.pyplot as pltplt.rcParams['font.sans-serif' ] = ['SimHei' ] plt.rcParams['axes.unicode_minus' ] = False import numpy as npimport pandas as pderror = np.random.randn(10 ) y = pd.Series(np.sin(np.arange(10 ))) y.plot(yerr = error) plt.show()
第四章 数据预处理 P75
1. 数据清洗 数据清洗主要是删除原始数据集中的无关数据、重复数据,平滑噪声数据,筛选掉与挖掘主题无关的数据,处理缺失值、异常值等
1. 缺失值处理 处理方法可分为三类:删除记录、数据插补和不处理
插补方法
方法描述
均值、中位数、众数插补
根据属性值的类型,用该属性取值的平均数、中位数、众数进行插补
使用固定值
将缺失的属性值用一个常量替换
最近临插补
在记录中找到与缺失样本最接近的样本的该属性卡值插补
回归方法
对带有缺失值的变量,根据已有数据和与其有关的其他变量(因变量)的数据建立拟合模型来预测确实的属性值
插值法
插值法是利用已知点建立合适的插值函数$f(x)$,未知数由对应点$x_i$求出的函数值$f(x_i)$近似代替
1. 拉格朗日插值法 2. 牛顿插值法 2. 异常值处理
异常值处理方法
方法描述
删除含有异常值的记录
直接将含有异常值的记录删除
视为缺失值
将异常值视为缺失值,利用缺失值处理的方法进行处理
平均值修正
可用前后两个观测值修正该异常值
不处理
直接在具有异常值的数据集上进行挖掘建模
2. 数据集成 数据挖掘需要的数据往往分布在不同的数据源中,数据集成就是将多个数据源合并存放在一个一致的数据储存位置(如数据仓库)中的过程。
1. 实体识别
同名异义:数据源A中的属性ID和数据源B三的属性ID分别描述的是菜品编号和订单编号,即描述的是不同的实体
异名同义:数据源A中的sales_dt和数据源B中的sales_date都是描述销售日期的
单位不统一:描述同一个实体时分别用的是国际单位和中国传统的计量单位
2. 冗余属性识别
同一属性多次出现
同一属性命名不一致导致重复
3. 数据变换 主要是对数据进行规范化处理,将数据转换成“适当的”形式,以适用于挖掘任务和算法的需要。
简单函数变换,对原始数据进行某些数学函数变换,包括平方、取对数、差分运算等
规范化
最小-最大规范化,也叫离差标准化,对原始数据的线性变换,将数值映射到[0,1]之间。
$$ x^*=\frac{(x-min)}{(max-min)} $$
0-均值规范化,也叫标准差标准化,经过处理的数据均值为0,标准差为1。
$$ x^*= \frac{x-\overline{x}}{σ} $$
小数定标规范化,通过移动属性值的小数位数,将属性值映射到[-1,1]之间,移动的小数位数取决于属性值绝对值的最大值
$$ x^*=\frac{x}{10^k} $$
连续属性离散化,如某些分类算法,ID3算法、Apriori算法,要求数据是分类属性形式。
离散化的过程,连续属性离散化就是在数据的取值范围内设定若干个离散的划分点,将取值范围划分为一些离散化的区间,最后用不同的符号或整数值代表落在每个子区间中的数据值
常用的离散化方法,等宽法和(一维)聚类。
等宽法,将属性的值域分成具有相同宽度的区间,区间的个数由数据本身的特点决定或者用户指定,类似与制作频率分布表
等频法,将相同数量的记录放进每个区间
这两种方法简单,易于操作,但都需要认为规定划分区间的个数。同时,等宽法缺点在于它对离群点比较敏感,倾向于不均匀地把属性值分布到各个区间。有些区间包含许多数据,而另外一些区间的数据极少,这样会严重损坏建立的决策模型。等频法虽然避免了上述问题的产生,却可能将相同的数据值分布到不同的区间,以满足每个区间中固定的数据个数
基于聚类分析的方法,一维聚类方法包括两个步骤:首先将连续属性的值用聚类算法(如K-Means算法)进行聚类,然后再将聚类得到的簇进行处理,合并到一个簇的连续属性值做同一标记。聚类分析的离散化方法也需要用户制定簇的个数,从而决定产生的区间数。
属性构造,利用已有的属性集构造新的属性,并加入到现有的属性集合中。
小波变换 P(88),信号分析手段
3. 数据规约 在大数据集上进行复杂的数据分析和挖掘需要很长时间。数据规约产生更小且保持原数据完整性的新数据集,在规约后的数据集上进行分析和挖掘将提高效率。
意义
降低无效、错误数据对建模的影响,提高建模的准确性
少量却具有代表性的数据将大幅缩减数据挖掘的时间
降低储存数据的成本
1. 属性规约 属性规约通过属性合并创建新属性维数,或者通过直接删除不相关的属性(维)来减少数据维数,从而提高数据挖掘的效率,降低计算成本。属性规约的目标是寻找最小的属性子集并确保新数据子集的概率分布尽可能接近原来的数据集的概率分布。
属性规约方法
方法描述
方法解析
合并属性
将一些旧属性合并为新属性
初始属性集:{$A_1,A_2,A_3,B_1,B_2,B_3,C$},{$A_1,A_2,A_3$}->$A$ {$B_1,B_2,B_3$}->$B$ 规约后属性集{$A,B,C$}
逐步向前选择
从一个空属性集开始,每次从原来属性集合中选择一个当前最优的属性添加到当前属性子集中。直到无法选出最优属性或满足一定阈值约束为止
初始属性集:{$A_1,A_2,A_3,A_4,A_5,A_6$},{}->{$A_1$}->{$A_1,A_4$} 规约后属性集{$A_1,A_4,A_6$}
逐步向后删除
从一个全属性集开始,每次从当前属性子集中选择一个当前最差的属性并将其从当前属性子集中消去。直到无法选出最差属性为止或满足一定阈值约束为止
初始属性集:{$A_1,A_2,A_3,A_4,A_5,A_6$},{$A_1,A_3,A_4,A_5,A_6$}->{$A_1,A_4,A_5,A_6$} 规约后属性集{$A_1,A_4,A_6$}
决策树归纳
利用决策树的归纳方法对初始数据进行分类归纳学习,获得一个初始决策树,所有没有出现在这个决策树上的属性均可认为是无关属性,因此将这些属性从初始集合中删除,就可以获得一个较优的属性子集
略
主成分分析
用较少的变量去解释原始数据中的大部分变量,即将许多线性相关性很高的变量转化成彼此互相独立或不相关的变量
略
逐步向前选择、逐步向后删除和决策树归纳是属于直接删除不相关属性(维)的方法。主成分分析法是一种用于连续属性的数据降维方法,它构造了原始数据的一个正交变换,新空间的基底去除了原始空间基底下数据的相关性,只需要使用少数新变量就能解释原始数据中的大部分变异。
在应用中,通常是选出比原始变量个数少,能解释大部分数据中的变量的几个新变量,即所谓主成分,来代替原始变量进行建模。
主成分分析计算步骤 主成分分析的步骤:中心化数据集-计算协方差矩阵-计算特征根-计算主成分矩阵-得到降维后的数据集
设原始变量$X_1,X_2,…,X_p$的$n$次观测数据矩阵为式 $$ X=\begin{Bmatrix} X_{11} & X_{12} & \dots & X_{13} \\ X_{21} & X_{22} & \dots & X_{23} \\ \dots & \dots & \dots & \dots \\ X_{n1} & X_{n2} & \dots & X_{np} \\ \end{Bmatrix}=(X_1,X_2,\dots,X_P) $$
将数据矩阵按列进行中心标准化。
求相关系数矩阵 $\mathbf{R}$ ,$ \mathbf{R} = (r_{ij})_ {p\times p} $ , $r_{ij}$定义为式,其中$r_{ij}=r_{ji},r_{ij}=1$ $$ r_{rj}= \sum\nolimits_{k=1}^n (x_{ki}-\overline{x_i})(x_{kj}-\overline{x_j}) / \sqrt{ \sum\nolimits_{k=1}^n (x_{ki}-\overline{x_i})^2 \sum\nolimits_{k=1}^n (x_{kj}-\overline{x_j})^2 } $$
求$\mathbf{R}$的特征方程 $ det(\mathbf{R}-λ\mathbf{E})=0 $ 的特征根$λ_1\geλ_2\ge…λ_p>0$
确定主成分个数,α根据实际问题确定,一般取80% $$ m: \frac{\sum\nolimits_{i=1}^m \lambda_i} {\sum\nolimits_{i=1}^p \lambda_i} \ge \alpha $$
计算m个相应的单位特征向量,如式 $$ \mathbf{\beta_1}=\begin{pmatrix} \beta_1 \\ \beta_2 \\ …\\ \beta_{p1} \end{pmatrix} , \mathbf{\beta_2}=\begin{pmatrix} \beta_{12} \\ \beta_{22} \\ …\\ \beta_{p2} \end{pmatrix} , \mathbf{\beta_m}=\begin{pmatrix} \beta_{1m} \\ \beta_{2m} \\ …\\ \beta_{pm} \end{pmatrix} $$
计算主成分,如式 $$ Z_i=\beta_{1i}X_1+\beta_{2i}X_2+…+\beta_{pi}X_p (i=1,2,…,m) $$
python中主成分分析函数:
1 sklearn.decomposition.PCA(n_components=None , copy=True , whiten=False )
参数名称
意义
类型
n_components
PCA算法中索要保留的主成分个数n,就是保留下来的特征个数n
int/str
copy
表示是否在运行算法时,将原始训练数据复制一份
bool
whiten
白化,使得每个特征具有相同的方差
bool
2. 数值规约 数值规约通过选择代替的、较小的数据来减少数据量,包括有参数方法和无参数方法两类。有参数方法是使用一个模型来评估数据,只需存放参数,而不需要存放实际数据,例如回归(线性回归和多元回归)和对数线性模型(近似离散属性集中的多维概率分布)。无参数方法就需要存放实际数据,如直方图、聚类、抽样(采样)。
直方图
聚类
抽样
常用抽样方法
s个样本无放回简单随机抽样
s个样本有放回地简单随机抽样
聚类抽样
分层抽样
参数回归
4. Python主要数据预处理函数
函数名
函数功能
所属拓展库
interpolate
一维、高维数据插值
SciPy
unique
去除数据中的重复元素,得到单值元素列表,它是对象的方法名
pandas/Numpy
isnull
判断是否空值
pandas
notnull
判断是否非空值
pandas
PCA
对指标变量矩阵进行主成分分析
Scikit-learn
random
生成随机矩阵
Numpy
代码实例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import pandas as pdimport numpy as npD = pd.Series([1 , 1 , 2 , 3 , 5 ]) D.unique() np.unique(D) from sklearn.decomposition import PCAD = np.random.rand(10 ,4 ) pca = PCA() pca.fit(D) pca.components_ pca.explained_variance_ratio_
第五章 挖掘建模 P102 1. 分类与预测 1. 实现过程
分类是构造一个分类模型,输入样本的属性值,输出对应的类别,将每个样本映射到预先定义好的类别。分类模型建立在已有类标记的数据集上,模型在已有样本上的准确率可以方便的绩,所以分类属于有监督的学习。
预测,预测是建立两种或两种以上变量间相互依赖的函数模型,然后进行预测或控制
实现过程,分类为和预测的实现过程类似,以分类模型为例。
2. 常用的分类与预测算法
算法名称
算法描述
回归分析
回归分析是确定预测属性(数值型)与其他变量间相互依赖的定量关系最常用的统计学方法,包括线性回归、非线性回归、Logistic回归、岭回归、主成分回归、最小二乘回归等模型
决策树
决策树采用自顶向下的递归方式,在内部节点进行属性值的比较,并根据不同的属性值从该节点向下分支,最终得到的叶节点是学习划分的类
人工神经网络
人工神经网络是一种模型大脑神经网络结构和功能而建立的信息处理系统,表示神经网络的输入与输出变量之间的关系的模型
贝叶斯网络
贝叶斯网络又称信度网络,是Bayes方法的扩展,是目前不确定知识表达和推理领域最有效的理论模型之一
支持向量机
支持向量机是一种通过某种非现行映射,把低维的非现行可分转化为高维的线性可分,在高维空间进行线性分析的算法
3. 回归分析
回归模型名称
适用条件
算法描述
线性回归
因变量与自变量是线性关系
对一个或多个自变量与因变量之间的线性关系进行建模,可用最小二乘法求解模型系数
非线性回归
因变量与自变量之间不都是线性关系
对一个或多个自变量和因变量之间的非线性关系进行建模。如果可转化为线性关系则用线性关系求解,否则用非线性最小二乘方法求解
Logistic回归
一般是因变量的有1-0(是否)两种取值
是广义线性回归模型的特例,利用Logistic函数将因变量的取值范围控制在的0和1之间,表示取值1的概率
岭回归
参与建模的自变量之间具有多重共线性
是一种改进最小二乘估计的方法
主成分回归
参与建模的自变量之间具有多重共线性
根据主成分分析思想,对最小二乘法的一种改进,它是参数估计的一种有偏估计,可消除自变量之间的多重共线性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import pandas as pdfrom sklearn.linear_model import LogisticRegression as LRfilename = '../data/bankloan.xls' data = pd.read_excel(filename) x = data.iloc[:,:8 ].as_matrix() y = data.iloc[:,8 ].as_matrix() lr = LR() lr.fit(x, y) print('模型的平均准确度为:%s' % lr.score(x, y))
4. 决策树
熵(entropy)
决策树算法
算法描述
ID3算法
其核心是在决策树的各级节点上,使用信息增益方法作为属性的选择标准,来帮助确定生成每个节点时所应采用的合适属性
C4.5算法
相对于ID3算法的重要改进是使用信息增益率来选择节点属性。C4.5算法可以克服ID3算法存在的不足:ID3算法只适用于离散的描述属性,而C4.5算法既能够处理离散的描述属性,也可以处理连续的描述属性
CART算法
CART决策树是一种十分有效的非参数分类和回归方法,通过构建树、修剪树、评估树来构建一个二叉树。当中节点是连续变量时,该树为回归树,当终节点是分类变量时,该树为分类树
ID3算法实现步骤
对当前样本集合,计算所有属性的信息增益
选择信息增益最大的属性作为测试属性,把测试属性取值相同的样本划分为同一个样本子集
若子样本集的类别属性只含有单个属性,则分支为叶子节点,判断其属性值并标上相应的符号,然后返回调用处;否则对子样本集递归调用本算法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 import pandas as pdfilename = '../data/sales_data.xls' data = pd.read_excel(filename, index_col = u'序号' ) data[data == u'好' ] = 1 data[data == u'是' ] = 1 data[data == u'高' ] = 1 data[data != 1 ] = -1 x = data.iloc[:,:3 ].astype(int) y = data.iloc[:,3 ].astype(int) from sklearn.tree import DecisionTreeClassifier as DTCdtc = DTC(criterion='entropy' ) dtc.fit(x, y) from sklearn.tree import export_graphvizx = pd.DataFrame(x) """ string1 = ''' edge [fontname="NSimSun"]; node [ fontname="NSimSun" size="15,15"]; { ''' string2 = '}' """ with open("../tmp/tree.dot" , 'w' ) as f: export_graphviz(dtc, feature_names = x.columns, out_file = f) f.close() ''' from IPython.display import Image from sklearn import tree import pydotplus dot_data = tree.export_graphviz(dtc, out_file=None, #regr_1 是对应分类器 feature_names=data.columns[:3], #对应特征的名字 class_names=data.columns[3], #对应类别的名字 filled=True, rounded=True, special_characters=True) graph = pydotplus.graph_from_dot_data(dot_data) graph.write_png('../tmp/example.png') #保存图像 Image(graph.create_png()) '''
5. 人工神经网络 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 import pandas as pdinputfile = '../data/sales_data.xls' data = pd.read_excel(inputfile, index_col = u'序号' ) data[data == u'好' ] = 1 data[data == u'是' ] = 1 data[data == u'高' ] = 1 data[data != 1 ] = 0 x = data.iloc[:,:3 ].astype(int) y = data.iloc[:,3 ].astype(int) from keras.models import Sequentialfrom keras.layers.core import Dense, Activationmodel = Sequential() model.add(Dense(input_dim = 3 , units = 10 )) model.add(Activation('relu' )) model.add(Dense(input_dim = 10 , units = 1 )) model.add(Activation('sigmoid' )) model.compile(loss = 'binary_crossentropy' , optimizer = 'adam' ) model.fit(x, y, epochs = 1000 , batch_size = 10 ) yp = model.predict_classes(x).reshape(len(y)) from cm_plot import * cm_plot(y,yp).show()
2. 聚类分析 K-Means聚类分析 K-Means算法是典型的基于举例的非层次聚类算法,在最小化误差函数的基础上将数据划分为预定的磊K,采用距离作为相似性评价指标,即认为两个对象的距离越近,相似度越大
1. 算法过程
从$n$个样本数据中随机选取$k$个对象作为初始的聚类中心。
分别计算每个样本到各个聚类中心的距离,将对象分配到距离最近的聚类中。
所有对象分配完成后,重新计算$k$个聚类的中心。
与前一次计算得到的$k$个聚类中心比较,如果聚类中心发生变化,转至步骤2,否则继续步骤5
当质心不发生变化时,停止并输出聚类结果。
2. 代码实例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 import pandas as pdinputfile = '../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 KMeansmodel = KMeans(n_clusters = k, n_jobs = 4 , max_iter = iteration,random_state=1234 ) model.fit(data_zs) r1 = pd.Series(model.labels_).value_counts() r2 = pd.DataFrame(model.cluster_centers_) r = pd.concat([r2, r1], axis = 1 ) r.columns = list(data.columns) + ['类别数目' ] print(r) r = pd.concat([data, pd.Series(model.labels_, index = data.index)], axis = 1 ) r.columns = list(data.columns) + ['聚类类别' ] r.to_excel(outputfile) def density_plot (data) : import matplotlib.pyplot as plt plt.rcParams['font.sans-serif' ] = ['SimHei' ] plt.rcParams['axes.unicode_minus' ] = False 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))
3. 关联规则 Apriori算法 核心思想:通过连接产生候选项与其支持度,然后通过剪枝生成频繁项集。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 import numpy as npimport pandas as pddef 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: 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_values(['confidence' ,'support' ], ascending = False ) print(u'\n结果为:' ) print(result) return result
其他
数据挖掘六个步骤 每个步骤展开三个层次
例如:
第三个步骤 数据预处理 第一个层次 :数据缺省值 如何处理 数据的转换 处理方法,缺失值删除,属性删除,插值(均值插值 牛顿法 拉格朗日法) 第二个层次:……
chapter 6 GM11.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 def GM11 (x0) : import numpy as np x1 = x0.cumsum() z1 = (x1[:len(x1)-1 ] + x1[1 :])/2.0 z1 = z1.reshape((len(z1),1 )) B = np.append(-z1, np.ones_like(z1), axis = 1 ) Yn = x0[1 :].reshape((len(x0)-1 , 1 )) [[a],[b]] = np.dot(np.dot(np.linalg.inv(np.dot(B.T, B)), B.T), Yn) f = lambda k: (x0[0 ]-b/a)*np.exp(-a*(k-1 ))-(x0[0 ]-b/a)*np.exp(-a*(k-2 )) delta = np.abs(x0 - np.array([f(i) for i in range(1 ,len(x0)+1 )])) C = delta.std()/x0.std() P = 1.0 *(np.abs(delta - delta.mean()) < 0.6745 *x0.std()).sum()/len(x0) return f, a, b, x0[0 ], C, P
01-lasso.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import numpy as npimport pandas as pdfrom sklearn.linear_model import Lassoinputfile = '../data/data.csv' data = pd.read_csv(inputfile) lasso = Lasso(1000 ) lasso.fit(data.iloc[:,0 :14 ],data['y' ]) print('相关系数为:' ,np.round(lasso.coef_,5 )) print('相关系数非零个数为:' ,np.sum(lasso.coef_ != 0 )) mask = lasso.coef_ != 0 print('相关系数是否为零:' ,mask) outputfile ='../tmp/new_reg_data.csv' new_reg_data = data.iloc[:, mask] new_reg_data.to_csv(outputfile) print('输出数据的维度为:' ,new_reg_data.shape)
02-gm_predict.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import syssys.path.append('../code' ) import numpy as npimport pandas as pdfrom GM11 import GM11 inputfile1 = '../tmp/new_reg_data.csv' inputfile2 = '../data/data.csv' new_reg_data = pd.read_csv(inputfile1) data = pd.read_csv(inputfile2) new_reg_data.index = range(1994 , 2014 ) new_reg_data.loc[2014 ] = None new_reg_data.loc[2015 ] = None l = ['x1' , 'x4' , 'x5' , 'x6' , 'x7' , 'x8' ] for i in l: f = GM11(new_reg_data.loc[range(1994 , 2014 ),i].values)[0 ] new_reg_data.loc[2014 ,i] = f(len(new_reg_data)-1 ) new_reg_data.loc[2015 ,i] = f(len(new_reg_data)) new_reg_data[i] = new_reg_data[i].round(2 ) outputfile = '../tmp/new_reg_data_GM11.xls' y = list(data['y' ].values) y.extend([np.nan,np.nan]) new_reg_data['y' ] = y new_reg_data.to_excel(outputfile) print('预测结果为:\n' ,new_reg_data.loc[2014 :2015 ,:])
03-svr_predict.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 import numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom sklearn.svm import LinearSVRinputfile = '../tmp/new_reg_data_GM11.xls' data = pd.read_excel(inputfile) np.array(data) feature = ['x1' , 'x4' , 'x5' , 'x6' , 'x7' , 'x8' ] data_train = data.loc[range(0 ,20 )].copy() data_mean = data_train.mean() data_std = data_train.std() data_train = (data_train - data_mean)/data_std x_train = data_train[feature].values y_train = data_train['y' ].values linearsvr = LinearSVR() linearsvr.fit(x_train,y_train) x = ((data[feature] - data_mean[feature])/data_std[feature]).values data[u'y_pred' ] = linearsvr.predict(x) * data_std['y' ] + data_mean['y' ] outputfile = '../tmp/new_reg_data_GM11_revenue.xls' data.to_excel(outputfile) print('真实值与预测值分别为:\n' ,data[['y' ,'y_pred' ]]) fig = data[['y' ,'y_pred' ]].plot(subplots = True , style=['b-o' ,'r-*' ]) plt.show()
chapter 7 01-data_explore.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import pandas as pddatafile= '../data/air_data.csv' resultfile = '../tmp/explore.csv' data = pd.read_csv(datafile, encoding = 'utf-8' ) explore = data.describe(percentiles = [], include = 'all' ).T explore['null' ] = len(data)-explore['count' ] explore = explore[['null' , 'max' , 'min' ]] explore.columns = [u'空值数' , u'最大值' , u'最小值' ] ''' 这里只选取部分探索结果。 describe()函数自动计算的字段有count(非空值数)、unique(唯一值数)、top(频数最高者)、 freq(最高频数)、mean(平均值)、std(方差)、min(最小值)、50%(中位数)、max(最大值) ''' explore.to_csv(resultfile)
02-data_distribution.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 import pandas as pdimport matplotlib.pyplot as plt datafile= '../data/air_data.csv' data = pd.read_csv(datafile, encoding = 'utf-8' ) from datetime import datetimeffp = data['FFP_DATE' ].apply(lambda x:datetime.strptime(x,'%Y/%m/%d' )) ffp_year = ffp.map(lambda x : x.year) fig = plt.figure(figsize = (8 ,5 )) plt.rcParams['font.sans-serif' ] = 'SimHei' plt.rcParams['axes.unicode_minus' ] = False plt.hist(ffp_year, bins='auto' , color='#0504aa' ) plt.xlabel('年份' ) plt.ylabel('入会人数' ) plt.title('各年份会员入会人数' ) plt.show() plt.close male = pd.value_counts(data['GENDER' ])['男' ] female = pd.value_counts(data['GENDER' ])['女' ] fig = plt.figure(figsize = (7 ,4 )) plt.pie([ male, female], labels=['男' ,'女' ], colors=['lightskyblue' , 'lightcoral' ], autopct='%1.1f%%' ) plt.title('会员性别比例' ) plt.show() plt.close lv_four = pd.value_counts(data['FFP_TIER' ])[4 ] lv_five = pd.value_counts(data['FFP_TIER' ])[5 ] lv_six = pd.value_counts(data['FFP_TIER' ])[6 ] fig = plt.figure(figsize = (8 ,5 )) plt.bar(x=range(3 ), height=[lv_four,lv_five,lv_six], width=0.4 , alpha=0.8 , color='skyblue' ) plt.xticks([index for index in range(3 )], ['4' ,'5' ,'6' ]) plt.xlabel('会员等级' ) plt.ylabel('会员人数' ) plt.title('会员各级别人数' ) plt.show() plt.close() age = data['AGE' ].dropna() age = age.astype('int64' ) fig = plt.figure(figsize = (5 ,10 )) plt.boxplot(age, patch_artist=True , labels = ['会员年龄' ], boxprops = {'facecolor' :'lightblue' }) plt.title('会员年龄分布箱线图' ) plt.grid(axis='y' ) plt.show() plt.close lte = data['LAST_TO_END' ] fc = data['FLIGHT_COUNT' ] sks = data['SEG_KM_SUM' ] fig = plt.figure(figsize = (5 ,8 )) plt.boxplot(lte, patch_artist=True , labels = ['时长' ], boxprops = {'facecolor' :'lightblue' }) plt.title('会员最后乘机至结束时长分布箱线图' ) plt.grid(axis='y' ) plt.show() plt.close fig = plt.figure(figsize = (5 ,8 )) plt.boxplot(fc, patch_artist=True , labels = ['飞行次数' ], boxprops = {'facecolor' :'lightblue' }) plt.title('会员飞行次数分布箱线图' ) plt.grid(axis='y' ) plt.show() plt.close fig = plt.figure(figsize = (5 ,10 )) plt.boxplot(sks, patch_artist=True , labels = ['总飞行公里数' ], boxprops = {'facecolor' :'lightblue' }) plt.title('客户总飞行公里数箱线图' ) plt.grid(axis='y' ) plt.show() plt.close ec = data['EXCHANGE_COUNT' ] fig = plt.figure(figsize = (8 ,5 )) plt.hist(ec, bins=5 , color='#0504aa' ) plt.xlabel('兑换次数' ) plt.ylabel('会员人数' ) plt.title('会员兑换积分次数分布直方图' ) plt.show() plt.close ps = data['Points_Sum' ] fig = plt.figure(figsize = (5 ,8 )) plt.boxplot(ps, patch_artist=True , labels = ['总累计积分' ], boxprops = {'facecolor' :'lightblue' }) plt.title('客户总累计积分箱线图' ) plt.grid(axis='y' ) plt.show() plt.close data_corr = data[['FFP_TIER' ,'FLIGHT_COUNT' ,'LAST_TO_END' , 'SEG_KM_SUM' ,'EXCHANGE_COUNT' ,'Points_Sum' ]] age1 = data['AGE' ].fillna(0 ) data_corr['AGE' ] = age1.astype('int64' ) data_corr['ffp_year' ] = ffp_year dt_corr = data_corr.corr(method = 'pearson' ) print('相关性矩阵为:\n' ,dt_corr) import seaborn as snsplt.subplots(figsize=(10 , 10 )) sns.heatmap(dt_corr, annot=True , vmax=1 , square=True , cmap='Blues' ) plt.show() plt.close
03-data_clean.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import numpy as npimport pandas as pddatafile = '../data/air_data.csv' cleanedfile = '../tmp/data_cleaned.csv' airline_data = pd.read_csv(datafile,encoding = 'utf-8' ) print('原始数据的形状为:' ,airline_data.shape) airline_notnull = airline_data.loc[airline_data['SUM_YR_1' ].notnull() & airline_data['SUM_YR_2' ].notnull(),:] print('删除缺失记录后数据的形状为:' ,airline_notnull.shape) index1 = airline_notnull['SUM_YR_1' ] != 0 index2 = airline_notnull['SUM_YR_2' ] != 0 index3 = (airline_notnull['SEG_KM_SUM' ]> 0 ) & (airline_notnull['avg_discount' ] != 0 ) index4 = airline_notnull['AGE' ] > 100 airline = airline_notnull[(index1 | index2) & index3 & ~index4] print('数据清洗后数据的形状为:' ,airline.shape) airline.to_csv(cleanedfile)
04-zscore_data.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import pandas as pdimport numpy as npcleanedfile = '../tmp/data_cleaned.csv' airline = pd.read_csv(cleanedfile, encoding = 'utf-8' ) airline_selection = airline[['FFP_DATE' ,'LOAD_TIME' ,'LAST_TO_END' , 'FLIGHT_COUNT' ,'SEG_KM_SUM' ,'avg_discount' ]] print('筛选的属性前5行为:\n' ,airline_selection.head()) L = pd.to_datetime(airline_selection['LOAD_TIME' ]) - pd.to_datetime(airline_selection['FFP_DATE' ]) L = L.astype('str' ).str.split().str[0 ] L = L.astype('int' )/30 airline_features = pd.concat([L,airline_selection.iloc[:,2 :]],axis = 1 ) airline_features.columns = ['L' ,'R' ,'F' ,'M' ,'C' ] print('构建的LRFMC属性前5行为:\n' ,airline_features.head()) from sklearn.preprocessing import StandardScalerdata = StandardScaler().fit_transform(airline_features) np.savez('../tmp/airline_scale.npz' ,data) print('标准化后LRFMC五个属性为:\n' ,data[:5 ,:])
05-KMeans_cluster.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 import pandas as pdimport numpy as npfrom sklearn.cluster import KMeans airline_scale = np.load('../tmp/airline_scale.npz' )['arr_0' ] k = 5 kmeans_model = KMeans(n_clusters = k,n_jobs=4 ,random_state=123 ) fit_kmeans = kmeans_model.fit(airline_scale) kmeans_cc = kmeans_model.cluster_centers_ print('各类聚类中心为:\n' ,kmeans_cc) kmeans_labels = kmeans_model.labels_ print('各样本的类别标签为:\n' ,kmeans_labels) r1 = pd.Series(kmeans_model.labels_).value_counts() print('最终每个类别的数目为:\n' ,r1) %matplotlib inline import matplotlib.pyplot as plt cluster_center = pd.DataFrame(kmeans_model.cluster_centers_,\ columns = ['ZL' ,'ZR' ,'ZF' ,'ZM' ,'ZC' ]) cluster_center.index = pd.DataFrame(kmeans_model.labels_ ).\ drop_duplicates().iloc[:,0 ] print(cluster_center) labels = ['ZL' ,'ZR' ,'ZF' ,'ZM' ,'ZC' ] legen = ['客户群' + str(i + 1 ) for i in cluster_center.index] lstype = ['-' ,'--' ,(0 , (3 , 5 , 1 , 5 , 1 , 5 )),':' ,'-.' ] kinds = list(cluster_center.iloc[:, 0 ]) cluster_center = pd.concat([cluster_center, cluster_center[['ZL' ]]], axis=1 ) centers = np.array(cluster_center.iloc[:, 0 :]) n = len(labels) angle = np.linspace(0 , 2 * np.pi, n, endpoint=False ) angle = np.concatenate((angle, [angle[0 ]])) fig = plt.figure(figsize = (8 ,6 )) ax = fig.add_subplot(111 , polar=True ) plt.rcParams['font.sans-serif' ] = ['SimHei' ] plt.rcParams['axes.unicode_minus' ] = False for i in range(len(kinds)): ax.plot(angle, centers[i], linestyle=lstype[i], linewidth=2 , label=kinds[i]) ax.set_thetagrids(angle * 180 / np.pi, labels) plt.title('客户特征分析雷达图' ) plt.legend(legen) plt.show() plt.close