数据挖掘实战(3)(挖掘建模)


内容分为一个部分:
第一部分:《Python数据分析与挖掘实战》第五章 :挖掘建模的内容;

课件 PDF 和 源码 移步到Github : https://github.com/Stormzudi/Python-Data-Mining
邮箱:442395572@qq.com

目录

    • 第一部分
    • 第5章 挖掘建模
      • 5.1 分类与预测
          • 5.1.1 实现过程
          • 5.1.2 常用的分类与预测算法
          • 5.1.3 回归分析
          • 5.1.4 决策树
          • 5.1.5 人工神经网络
          • 5.1.6 分类与预测算法评价
          • 5.1.7 Python分类预测模型特点
      • 5.2 聚类分析
          • 5.2.1 常用聚类分析算法
          • 5.2.2 K-Means 聚类算法
          • 5.2.3 聚类分析算法评价
          • 5.2.4 Python 主要聚类分析算法
      • 5.3 关联规则
          • 5.3.1 常用关联规则算法
          • 5.3.2 Apriori 算法
      • 5.4 时序模式
          • 5.4.1 时间序列算法
          • 5.4.2 时间序列的预处理
          • 5.4.3 平稳时间序列分析
          • 5.4.4 非平稳时间序列分析
          • 5.4.5 Python主要时序模式算法
      • 5.5 离群点检测
          • 5.5.1 离群点检测方法
          • 5.5.2 基于模型的离群点检测方法
          • 5.5.3 基于聚类的离群点检测方法
      • 5.6 小结


(1)在学习这部分内容时,我们可以参考sklearn-learn的官网进行学习:
scikit-learn 英文官网
scikit-learn (sklearn) 官方文档中文版
建议从英文的官网开始学习。

(2)其他学习链接:
学习路径:机器学习入门
学习路径:机器学习入门


第一部分 第5章 挖掘建模 经过数据探索与数据预处理,得到了可以直接建模的数据。根据挖掘目标和数据形式可以建立分类与预测聚类分析关联规则时序模式偏差检测等模型。
5.1 分类与预测
5.1.1 实现过程 分类算法有两步过程:
  1. 第一步是学习步,通过归纳分析训练样本集来建立分类模型得到分类规则;
  2. 第二步是分类步,先用已知的测试样本集评估分类规则的准确率,如果准确率是可以接受的,则使用该模型对未知类标号的待测样本集进行预测。
    数据挖掘实战(3)(挖掘建模)
    文章图片


5.1.2 常用的分类与预测算法 常用的分类与预测算法见下表:
数据挖掘实战(3)(挖掘建模)
文章图片

5.1.3 回归分析 回归分析研究的范围大致如下:
数据挖掘实战(3)(挖掘建模)
文章图片

那么回归分析常见的模型与算法有哪些呢?
数据挖掘实战(3)(挖掘建模)
文章图片

数据挖掘实战(3)(挖掘建模)
文章图片

接下来介绍两个模型 Logistic回归、岭回归 的代码。
(1)Logistic回归属于概率型非线性回归,分为二分类和多分类的回归模型,因变量一般有1和0两种取值。
# -*- coding: utf-8 -*- # 逻辑回归 自动模型 import pandas as pd from sklearn.linear_model import LogisticRegression as LR from stability_selection.randomized_lasso import RandomizedLogisticRegression as RLR# 参数初始化 filename = '../data/bankloan.xls' data = https://www.it610.com/article/pd.read_excel(filename) x = data.iloc[:, :8].values y = data.iloc[:, 8].valuesrlr = RLR() rlr.fit(x, y) rlr.get_support() print('通过随机逻辑回归模型筛选特征结束。') print(u'有效特征为:', ','.join(data.columns[rlr.get_support()])) x = data[data.columns[rlr.get_support()]].as_matrix()lr = LR() lr.fit(x, y) print('逻辑回归模型训练结果') print('模型的平均正确率', lr.score(x, y))

(2)岭回归模型是一种改进的最小二乘法模型,可以参考:[机器学习] - 岭回归与Lasso回归。
#!/usr/bin/env python # -*- coding: utf-8 -*- # @File: 5-1_lasso.py # @Author: Stormzudi # @Date: 2020/7/24 22:27""" 实现岭回归分析 """import numpy as np import pandas as pd from sklearn.linear_model import Ridge# 通过sklearn.linermode1加载岭回归方法 import matplotlib.pyplot as plt from sklearn.preprocessing import PolynomialFeatures# 通过sklearn.preprocessing加载PolynomialFeatures用于创建多项式特征 from sklearn.model_selection import train_test_split# 交叉验证filename = '../data/bankloan.xls' data_df = pd.read_excel(filename) data = https://www.it610.com/article/np.array(data_df) plt.plot(data[:, 8])# 展示车流量信息X = data[:, 0:8]# X用于保存1-4维数据,即属性 y = data[:, 8]# y用于保存第5维数据,即车流量 poly = PolynomialFeatures(6)# 用于创建最高次数6次方的的多项式特征,多次试验后决定采用6次 X = poly.fit_transform(X)# X为创建的多项式特征train_set_X, test_set_X, train_set_y, test_set_y = train_test_split(X, y, test_size=0.3, random_state=0) # 将所有数据划分为训练集和测试集, test_ size表示测试集的比例, random_state是随机数种子clf = Ridge(alpha=1.0, fit_intercept=True)# 创建岭回归实例 clf.fit(train_set_X, train_set_y)# 调用fit函数使用训练集训练回归器 score = clf.score(test_set_X, test_set_y)# 评价拟合值的好坏(最大值:1) # print(score)''' # 利用测试集计算回归曲线的拟合优度,clf. score返回值为0.7620拟合优度, # 用于评价拟合好坏,最大为1,无最小值,当对所有输入都输出同一个值时,拟合优度为0。 # '''# 绘制拟合曲线 start = 200# 画一段200到300范围内的拟合曲线 end = 300 y_pre = clf.predict(X)# 是调用predict函数的拟合值 time = np.arange(start, end)fig = plt.figure()# 定义一个图片 ax = fig.add_subplot(1, 1, 1) ax.plot(time, y[start:end], label='real') ax.plot(time, y_pre[start:end],'r', label='predict')# 展示真实数据(蓝色)以及拟合的曲线(红色) plt.legend(loc = 'upper left') # 设置图例的位置 props = { 'title' : 'Traffic flow forecast', 'xlabel' : 'Period of time[200-300]', 'ylabel' : 'Number of traffic' } ax.set(**props) plt.show()


5.1.4 决策树
# -*- coding: utf-8 -*- # 使用ID3决策树算法预测销量高低 import pandas as pd from sklearn.tree import DecisionTreeClassifier as DTC from sklearn.tree import export_graphviz# 参数初始化 inputfile = '../data/sales_data.xls' data = https://www.it610.com/article/pd.read_excel(inputfile, index_col = u'序号')# 导入数据# 数据是类别标签,要将它转换为数据 # 用1来表示“好”“是”“高” 这三个属性,用-1来表示“坏”“否”“低” data[data =https://www.it610.com/article/= u'好'] = 1 data[data =https://www.it610.com/article/= u'是'] = 1 data[data =https://www.it610.com/article/= u'高'] = 1 data[data != 1] = -1 x = data.iloc[:,:3].values.astype(int) y = data.iloc[:,3].values.astype(int)dtc = DTC(criterion='entropy')# 建立决策树模型,基于信息熵 dtc.fit(x, y)# 训练模型# 导入相关函数,可视化决策树。 # 导出的结果是一个dot文件,需要安装Graphviz才能将它转换为pdf或png等格式。x = pd.DataFrame(x) with open("tree.dot", 'w') as f: f = export_graphviz(dtc, feature_names = x.columns, out_file = f)

将运行得到的文件,它保存为UTF-8格式。为了进一步将它转换为可视化格式,需要安装Graphviz (跨平台的、基于命令行的绘图工具)。
Graphviz安装及入门教程
然后在命令行中以如下方式编译。
dot -Tpng tree.dot -0 tree.pdf
数据挖掘实战(3)(挖掘建模)
文章图片
5.1.5 人工神经网络 人工神经网络的学习也称为训练,指的是神经网络在受到外部环境的刺激下调整神经网络的参数,使神经网络以一种新的方式对外部环境作出反应的一个过程。在分类与预测中,人工神将网络主要使用有指导的学习方式,即根据给定的训练样本,调整人工神经网络的参数以使网络输出接近于已知的样本类标记或其他形式的因变量。
数据挖掘实战(3)(挖掘建模)
文章图片

还有一些关于人工神经网络算法的描述。
以下是运用神经网络算法库Keras,简单来说实现BP神经网络。
#!/usr/bin/env python # -*- coding: utf-8 -*- # @File: 5-3_neural_network.py # @Author: Stormzudi # @Date: 2020/7/24 22:27# 使用神经网络算法预测销量高低import pandas as pd from sklearn.metrics import confusion_matrix# 导入混淆矩阵函数 from keras.models import Sequential from keras.layers.core import Dense, Activation# 参数初始化 inputfile = '../data/sales_data.xls' data = https://www.it610.com/article/pd.read_excel(inputfile, index_col = u'序号')# 导入数据# 数据是类别标签,要将它转化为数据 # 用1来表示“好”、“是”、“高”这3个属性,用0来表示“坏”、“否”、“低”data[data =https://www.it610.com/article/= u'好'] = 1 data[data =https://www.it610.com/article/= u'是'] = 1 data[data =https://www.it610.com/article/= u'高'] = 1 data[data != 1] = 0 x = data.iloc[:,:3].values.astype(int) y = data.iloc[:,3].values.astype(int)model = Sequential()# 建立模型 model.add(Dense(input_dim = 3, output_dim = 10)) model.add(Activation('relu'))# 用relu函数作为激活函数,能够答复提供准确度 model.add(Dense(input_dim = 10, output_dim = 1)) model.add(Activation('sigmoid'))# 由于是0-1输出,用sigmoid函数作为激活函数model.compile(loss = 'binary_crossentropy', optimizer = 'adam') # 编译模型。由于我们做的是二元分类,所以我们指定损失函数为binary_crossentropy, 以及模式为binary # 另外常见的损失函数还有mean_squared_ error、 categorical_crossentropy等, 请阅读帮助文件。 # 求解方法我们指定用adam,还有sgd, rmsprop等 可选。model.fit(x, y, batch_size=10, nb_epoch=1000)# 训练模型,学习100次 yp = model.predict_classes(x).reshape(len(y))# 分类预测 print(yp)# 画出混淆矩阵 def cm_plot(y, yp): """ 输入:y为真实值,yp为预测值 """ 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')# 坐标轴标签 plt.show()# 显示作图结果cm_plot(y, yp)

绘制的混淆矩阵图:
数据挖掘实战(3)(挖掘建模)
文章图片


5.1.6 分类与预测算法评价 分类与预测模型对训练集进行预测而得出的准确率并不能很好地反映预测模型未来的性能,为了有效判断一个预测模型的性能表现,需要- -组没有 参与预测模型建立的数据集,并在该数据集上评价预测模型的准确率,这组独立的数据集叫作测试集。
模型预测效果评价,通常用相对/绝对误差平均绝对误差均方误差均方根误差等指标来衡量。
(1)绝对误差与相对误差
这个很好理解,这是一种直观的误差表示方法。绝对误差等于真实值减去实际值。相对误差等于绝对误差再除以实际值*100%。
(2)平均绝对误差
平均绝对误差(MAE)等于所有样本的绝对误差的平均值。
(3)均方误差
均方误差(MSE)等于所有样本的绝对误差平方的平均值。
本方法用于还原平方失真程度。
均方误差是预测误差平方之和的平均数,它避免了正负误差不能相加的问题。由于对误差E进行了平方,加强了数值大的误差在指标中的作用,从而提高了这个指标的灵敏性,是一大优点。均方误差是误差分析的综合指标法之一。
(4)均方根误差
均方根误差(RMSE)等于均方误差的平方根。
这是均方误差的平方根,代表了预测值的离散程度,也称为标准误差,最佳拟合情况为RMSE=0。均方根误差也是误差分析的综合指标之一。
(5)平均绝对百分误差
平均绝对百分误差(MAPE)等于所有样本的相对误差的平均值。
一般认为MAPE小于10时,预测精度较高。
(6)Kappa统计
学习链接: Kappa统计
(7)识别准确度
(8)识别精确度
(9)反馈率
学习链接: 【机器学习】准确率(Accuracy), 精确率(Precision), 召回率(Recall)
(10)ROC曲线
(11)混淆矩阵

5.1.7 Python分类预测模型特点 【数据挖掘实战(3)(挖掘建模)】分类预测模型属于监督学习的范畴。
这里简述有监督学习模型:
学习链接: https://developer.ibm.com/zh/articles/cc-supervised-learning-models/
数据挖掘实战(3)(挖掘建模)
文章图片

经过对前面章节中的分类与预测的学习,我们应该基本认识到了Python 建模的特点。首先,我们需要认识到:Python 本身是一门面向对象的编程语言,这就意味着很多Python的程序是面向对象的。放到建模之中,我们就会发现,不管是在Scikit-Learn还是Keras中,建模的第一个步骤是建立一个对象,这个对象是空白的,需要进一步训练的, 然后我们要设置模型的参数,接着就是通过fit()方法对模型进行训练,最后通过predict() 方法预测结果。当然,还有一些方法有助于我们完成对模型的评估,如score()等。
Scikit-Learn和Keras的功能都非常强大,我们能够做的仅仅是通过一些简单的例子介绍它们的基本功能,这仅仅是它们本身功能的冰山一角。因此,我们再次强调,如果遇到书本上没有讲解过的问题,应当尽可能地查阅官方的帮助文档。只有官方的帮助文章,才有可能全面地提供解决问题的答案。


5.2 聚类分析
之前写过关于聚类分析的博客,不喜勿喷。
(1) 基于聚类的“图像分割”案例——K-means聚类算法
(2) [无监督学习] K-Means聚类
5.2.1 常用聚类分析算法 相比回归与预测这些监督算法,聚类模型可以建立在无类别标签的数据上,是一种非监督的学习算法。
数据挖掘实战(3)(挖掘建模)
文章图片

数据挖掘实战(3)(挖掘建模)
文章图片

数据挖掘实战(3)(挖掘建模)
文章图片

5.2.2 K-Means 聚类算法 算法流程在原书PDF中有详细讲解,代码如下:
# -*- coding: utf-8 -*- # 使用K-Means算法聚类消费行为特征数据from sklearn.manifold import TSNE from sklearn.cluster import KMeans import pandas as pd import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei']# 用来正常显示中文标签 plt.rcParams['axes.unicode_minus'] = False# 用来正常显示负号# 参数初始化 inputfile = '../data/consumption_data.xls'# 销量及其他属性数据 outputfile = '../tmp/data_type.xls'# 保存结果的文件名 k = 3 #聚类的类别 iteration = 500 #聚类最大循环次数 data = https://www.it610.com/article/pd.read_excel(inputfile, index_col ='Id') #读取数据 data_zs = 1.0*(data - data.mean())/data.std() #数据标准化model = KMeans(n_clusters = k, n_jobs = 4, max_iter = iteration) #分为k类,并发数4 model.fit(data_zs) #开始聚类# 简单打印结果 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 pltpic_output = '../tmp/pd_' #概率密度图文件名前缀 for i in range(k): density_plot(data[r[u'聚类类别']==i]).savefig(u'%s%s.png' %(pic_output, i))# 绘制聚类效果图 tsne = TSNE() tsne.fit_transform(data_zs) #进行数据降维 tsne = pd.DataFrame(tsne.embedding_, index = data_zs.index) #转换数据格式# 不同类别用不同颜色和样式绘图 fig = plt.figure()# 增加一个画布 d = tsne[r[u'聚类类别'] == 0] 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()

5.2.3 聚类分析算法评价 聚类分析仅根据样本数据本身将样本分组。其目标是实现组内的对象相互之间是相似的(相关的),而不同组中的对象是不同的(不相关的)。组内的相似性越大,组间差别越大,聚类效果就越好。
算法评价:
(1)purity 评价法
(2)RI评价法
(3)F值评价法
5.2.4 Python 主要聚类分析算法 数据挖掘实战(3)(挖掘建模)
文章图片



5.3 关联规则
关联规则分析:是数据挖掘中最活跃的研究方法之–,目的是在一个数据集中找出各项之间的关联关系,而这种关系并没有在数据中直接表示出来。
5.3.1 常用关联规则算法 数据挖掘实战(3)(挖掘建模)
文章图片

5.3.2 Apriori 算法 在书籍中有详细讲解Aprior算法,于是我想在这里以我的理解,再次详细讲解。
Apriori算法:是最经典的挖掘频繁项集的算法,其核心思想是通过连接产生候选项与其支持度,然后通过剪枝生成频繁项集,最后,得到满足最大项的频繁项集。

  • 关联规则和频繁项集
    (1)关联规则的一般形式
    项集A、B同时发生的概率称为关联规则的支持度(也称相对支持度)
    S u p p o r t ( A ? B ) = P ( A ? B ) Support\left( {A \Rightarrow B} \right) = P\left( {A\bigcup B } \right) Support(A?B)=P(A?B)
    项集A发生,则项集B发生的概率为关联规则的置信度
    C o n f i d e n c e ( A ? B ) = P ( A ∣ B ) Confidence\left( {A \Rightarrow B} \right) = P\left( {A|B } \right) Confidence(A?B)=P(A∣B)
    (2)最小支持度和最小置信度
    最小支持度是用户或专家定义的衡量支持度的一一个阈值,表示项目集在统计意义上的最低重要性;最小置信度是用户或专家定义的衡量置信度的一个阈值, 表示关联规则的最低可靠性。同时满足最小支持度阈值和最小置信度阈值的规则称作强规则。
    (3)项集
    项集是项的集合。包含k个项的项集称为k项集,如集合{牛奶,麦片,糖}是一个3项集。项集的出现频率是所有包含项集的事务计数,又称作绝对支持度或支持度计数。如果项集I的相对支持度满足预定义的最小支持度阈值,则I是频繁项集。频繁k项集通常记作k。
    (4)支持度计数
    项集A的支持度计数是事务数据集中包含项集A的事务个数,简称为项集的频率或计数。
    已知项集的支持度计数,则规则A= B的支持度和置信度很容易从所有事务计数、项集A和项集A∪B的支持度计数推出。
    数据挖掘实战(3)(挖掘建模)
    文章图片

    也就是说,一旦得到所有事务个数,A,B和A∩B的支持度计数,就可以导出对应的关联规则A→B和B→A,并可以检查该规则是否是强规则。
  • Apriori算法:使用候选产生频繁项集
    Apriori算法的主要思想是找出存在于事务数据集中的最大的频繁项集,在利用得到的最大频繁项集与预先设定的最小置信度阈值生成强关联规则。
    (1)Apriori的性质
    频繁项集的所有非空子集也必须是频繁项集。根据该性质可以得出:向不是频繁项集I的项集中添加事务A,新的项集IUA一定也不是频繁项集。
    (2)Apriori算法实现的两个过程如下:
    1)找出所有的频繁项集(支持度必须大于给定的最小支持度阈值),在这个过程中连接步和剪枝互相融合,最终得到最大频繁项集 L i L_i Li?。
    连接步:
    初始:对给定的最小支持度阈值,
    Step1:分别对1项候选集CI,剔除小于该阈值的项集得到1项频繁集L1;
    Step2:由L1自身连接产生2项候选集C2,保留C2中满足约束条件的项集得到2项频繁集,记为L2;
    Step3:由L2与L3连接产生3项候选集C3,保留C2中满足约束条件的项集得到3项频繁集,记为L3.

    这样循环下去,得到最大频繁项集Lk。
    剪枝步:
    剪枝步紧接着连接步,在产生候选项Ck的过程中起到减小搜索空间的目的。由于Ck是 L k ? 1 L_{k-1} Lk?1?与 L 1 L_1 L1?连接产生的,根据Apriori的性质频繁项集的所有非空子集也必须是频繁项集,所以不满足该性质的项集不会存在于Ck中,该过程就是剪枝。
    2) 频繁项集产生强关联规则:由过程1)可知超过预定的最小支持度阈值的项集已被剔除,如果剩下这些规则又满足了预定的最小置信度阈值,那么就挖掘出了强关联规则,就可以展示出来。

原始数据集:
数据挖掘实战(3)(挖掘建模)
文章图片


过程一:找到最大K项频繁集
首先,设支持度为0.2(支持度计数为2)
(1)执行一次Step1:
数据挖掘实战(3)(挖掘建模)
文章图片

简单扫描所有的事务,事务中的每一项都有候选1项集的集合 C 1 C_1 C1?的成员,计算每一项的支持度。例如, P ( a ) = 项 集 { a } 的 支 持 度 计 数 / 所 有 事 务 的 个 数 = 7 / 10 = 0.7 P({a})={项集\{a\}的支持度计数/所有事务的个数}=7/10=0.7 P(a)=项集{a}的支持度计数/所有事务的个数=7/10=0.7。

对 C 1 C_1 C1?中各项集中的支持度与预先设定的最小支持度阈值进行比较,保留大于或者等于该阈值的项,得到1项频繁集 L 1 L_1 L1?。
(2)执行一次Step2:
数据挖掘实战(3)(挖掘建模)
文章图片

扫描所有事务, L 1 L_1 L1?与 L 2 L_2 L2?连接得候选2项集 C 2 C_2 C2?,并计算每一项的支持度。如 P ( a , b ) = 项 集 { a , b } 的 支 持 度 计 数 / 所 有 事 务 个 数 = 5 / 10 = 0.5 P({a,b})=项集\{a,b\}的支持度计数/所有事务个数=5/10=0.5 P(a,b)=项集{a,b}的支持度计数/所有事务个数=5/10=0.5。接下来就是剪枝步,由于 C 2 C_2 C2?的每一个子集(即 L 1 L_1 L1?)都是频繁集,所有没有项集从 C 2 C_2 C2?中剔除。

对 C 2 C_2 C2?中各项集中的支持度与预先设定的最小支持度阈值进行比较,保留大于或者等于该阈值的项,得到2项频繁集 L 2 L_2 L2?。
(3)执行一次Step3:
数据挖掘实战(3)(挖掘建模)
文章图片

扫描所有事务, L 2 L_2 L2?与 L 1 L_1 L1?连接得候选3项集 C 3 C_3 C3?,我认为课本上 C 3 C_3 C3?有三个,分别是:{a,b,c}、{a,c,e}、{a,b,d}。并计算每一项的支持度。如 P ( a , b , c ) = 项 集 { a , b , c } 的 支 持 度 计 数 / 所 有 事 务 个 数 = 3 / 10 = 0.3 P({a,b,c})=项集\{a,b,c\}的支持度计数/所有事务个数=3/10=0.3 P(a,b,c)=项集{a,b,c}的支持度计数/所有事务个数=3/10=0.3。接下来就是剪枝步,最后,剔除掉3项集{a,b,d},最后的 C 3 C_3 C3?中的项集只有{a,b,c}和{a,c,e};
代码:
#!/usr/bin/env python # -*- coding: utf-8 -*- # @File: apriori.py # @Author: Stormzudi # @Date: 2020/8/1 17:31from __future__ import print_function import pandas as pd# 自定义连接函数,用于实现L_{k-1}到C_k的连接 def connect_string(x, ms): x = list(map(lambda i: sorted(str(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='--'): result = pd.DataFrame(index=['support', 'confidence'])# 定义输出结果support_series = 1.0 * d.sum() / len(d)# 支持度序列 column = list(support_series[support_series > support].index)# 初步根据支持度筛选 k = 0while 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)# 新一批支持度的计算函数 # 创建连接数据,这一步耗时、耗内存最严重。当数据集较大时,可以考虑并行运算优化。 # print(sf) print(column) # print(list(map(sf, column))) d_2 = pd.DataFrame(list(map(sf, column)), index=[ms.join(i) for i in column]).Tsupport_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_values(['confidence', 'support'], ascending=False)# 结果整理,输出 print(u'\n结果为:') print(result)return result

#-*- 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 = https://www.it610.com/article/pd.read_excel(inputfile, header = None)print(u'\n转换原始数据至0-1矩阵...') ct = lambda x : pd.Series(1, index = x[pd.notnull(x)]) #转换0-1矩阵的过渡函数 b = map(ct, data.values) #用map方式执行 data = https://www.it610.com/article/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)# 保存结果

结果显示:
数据挖掘实战(3)(挖掘建模)
文章图片



5.4 时序模式
研究时间序列的数据目标是在给定的一个已被观察了的时间序列,预测该序列的未来值。
之前写过关于时序模式的博客:
ARIMA模型 - [SPSS & Python]
5.4.1 时间序列算法 数据挖掘实战(3)(挖掘建模)
文章图片


5.4.2 时间序列的预处理 时间序列的预处理分成两个部分:平稳性检查纯随机性检验
(1)平稳性检查
定义: 时间序列 { X t , t ∈ T } \{X_t,t∈T\} {Xt?,t∈T}在某一个常数附近波动并且波动范围有限,即有常数均值和常数方差,并且延期k期的序列变量的自协方差和自相关系数是相等的或者说说是延期k期的序列变量之间的影响程度是一样的,这样的序列称为平稳的序列。
检验: 检验的方法有两种:一种是时序图、自相关图的特征做出判断的图检测,两一种是构造检验统计量进行检验的方法,例如单位根检验。
(2)纯随机性检验
纯随机性检验也称为白噪声检验,一般是构造检验统计量检验序列的纯随机性,如果一个序列是纯随机序列,那么他的序列值之间应该没有任何关系。实际上纯随机序列的样本自相关系数不会绝对为零,但是很接近零,并在零附近随机波动。

5.4.3 平稳时间序列分析 目前最常见的平稳序列的模型是ARMA模型,可以看作是多元线性回归模型。
ARMA模型是AR模型与MA模型的多元线性组合。
(1)AR模型
数据挖掘实战(3)(挖掘建模)
文章图片

之前写过关于AR模型的博客,链接: 自回归AR模型
(2)MA模型
数据挖掘实战(3)(挖掘建模)
文章图片

了解AR、和MA模型,要学会通过自相关图和偏相关图来选取合适的参数p、q。
(3)ARMA模型与平稳时间序列建模
自回归移动平均模型,又简称为ARMA(p,q)。
一个平稳的ARMA(p,q)的性质,见下表。
数据挖掘实战(3)(挖掘建模)
文章图片

当q=0,ARMA(p,q)是AR(p)模型,当p=0,ARMA(p,q)是MA(q)模型。
平稳时间序列建模
某个时间序列经过预处理,被判定为平稳非白噪声序列,就可以利用ARMA模型进行建模。计算出平稳非白噪声序列{X}的自相关系数和偏自相关系数,再由AP§模型、MA(q)和ARMA(p, q)的自相关系数和偏自相关系数的性质,选择合适的模型。
数据挖掘实战(3)(挖掘建模)
文章图片

平稳时间序列建模步骤如下:
(1)计算ACF和PACF。先计算非平稳白噪声序列的自相关系数(ACF)和偏自相关系数(PACF)
(2)ARMA模型识别,也称为模型定阶,有AR(p)模型、MA(q)和ARMA(p,q)的自相关系数和偏相关系数的性质,选择合适的模型。
(3)估计模型中未知参数的值,并对参数进行检验。
(4)模型检验
(5)模型优化
(6)模型应用:进行短期预测
数据挖掘实战(3)(挖掘建模)
文章图片

5.4.4 非平稳时间序列分析 之前写过关于非平稳时间序列分析ARIMA的博客:
ARIMA模型 - [SPSS & Python]
5.4.5 Python主要时序模式算法 主要程序:
#-*- coding: utf-8 -*- #arima时序模型import pandas as pd#参数初始化 discfile = '../data/arima_data.xls' forecastnum = 5#读取数据,指定日期列为指标,Pandas自动将“日期”列识别为Datetime格式 data = https://www.it610.com/article/pd.read_excel(discfile, index_col = u'日期')#时序图 import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签 plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号 data.plot() plt.show()#自相关图 from statsmodels.graphics.tsaplots import plot_acf plot_acf(data).show()#平稳性检测 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 = https://www.it610.com/article/data.diff().dropna() D_data.columns = [u'销量差分'] D_data.plot() #时序图 plt.show() plot_acf(D_data).show() #自相关图 from statsmodels.graphics.tsaplots import plot_pacf plot_pacf(D_data).show() #偏自相关图 print(u'差分序列的ADF检验结果为:', ADF(D_data[u'销量差分'])) #平稳性检测#白噪声检验 from statsmodels.stats.diagnostic import acorr_ljungbox print(u'差分序列的白噪声检验结果为:', acorr_ljungbox(D_data, lags=1)) #返回统计量和p值from statsmodels.tsa.arima_model import ARIMAdata[u'销量'] = data[u'销量'].astype(float) #定阶 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)) model = ARIMA(data, (p,1,q)).fit()# 建立ARIMA(0, 1, 1)模型 model.summary2()# 给出一份模型报告 model.forecast(5)# 作为期5天的预测,返回预测结果、标准误差、置信区间。



5.5 离群点检测
离群点检测时数据挖掘中重要的一部分,它的任务时发现于大部分其他对象显著不同的对象。大部分数据挖掘方法都将这种差异信息是为噪声而丢弃,然而在一些应用中,罕见的数据可能蕴含着更多的研究价值。
离群点的大致分类:
(1)从数据范围角度,分为全局离群点和局部离群点
(2)从数据类型角度,分为数值型离群点和分类型离群点
(3)从属性的个数角度,分为一维离群点和多维离群点

5.5.1 离群点检测方法 常见的离群点检测的方法:
数据挖掘实战(3)(挖掘建模)
文章图片

5.5.2 基于模型的离群点检测方法 通过估计概率分布的参数来建立-个数据模型。如果一个数据对象不能很好地同该模型拟合,即如果它很可能不服从该分布,则它是一个离群点。
(1)一元正态分布中的离群点检测
这个部分就是我们之前讲过的 3 σ 3\sigma 3σ原则寻找异常值(数据是服从正太分布的)。
(2)高斯模型的离群点检测
5.5.3 基于聚类的离群点检测方法
#-*- coding: utf-8 -*- #使用K-Means算法聚类消费行为特征数据import numpy as np import pandas as pd#参数初始化 inputfile = '../data/consumption_data.xls' #销量及其他属性数据 k = 3 #聚类的类别 threshold = 2 #离散点阈值 iteration = 500 #聚类最大循环次数 data = https://www.it610.com/article/pd.read_excel(inputfile, index_col ='Id') #读取数据 data_zs = 1.0*(data - data.mean())/data.std() #数据标准化from sklearn.cluster import KMeans model = KMeans(n_clusters = k, n_jobs = 4, max_iter = iteration) #分为k类,并发数4 model.fit(data_zs) #开始聚类#标准化数据及其类别 r = pd.concat([data_zs, pd.Series(model.labels_, index = data.index)], axis = 1)#每个样本对应的类别 r.columns = list(data.columns) + [u'聚类类别']# 重命名表头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) #合并import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei']# 用来正常显示中文标签 plt.rcParams['axes.unicode_minus'] = False# 用来正常显示负号 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()

数据挖掘实战(3)(挖掘建模)
文章图片



5.6 小结
数据挖掘技术的基本任务主要体现在分类和预测、聚类、关联规则、时序模式、离群点检测5个方面。
通过对本章的学习,可以在以后的数据挖掘过程中采用适当的算法,并按所陈述的步骤实现综合应用。

    推荐阅读