Advertisement

数据挖掘实战—餐饮行业的数据挖掘之挖掘建模

阅读量:

文章目录

    • 引言
    • 一、分类与预测
      • 1.常用的分类与预测算法
      • 2. 回归分析
      • 3.决策树
      • 4.人工神经网络
  • 第二部分为聚类分析

  • 列举常见的聚类分析算法

  • K-Means聚类方法详细阐述其工作流程

  • 探讨数据类型及其相似性评估的标准

    复制代码
    * 3\. 目标函数
    * 4.消费行为特征分析
    * 5.python中主要的聚类分析算法

第三部分、关联规则分析

复制代码
  * 3.Apriori算法—python实现
  • 四、时间序列模式
  • 第五章 离群点检测
    • 第一节 离群点的成因及分类
    • 第二节 离群点检测方法
    • 第三节 基于聚类的离群点检测方法
      • 第三节1 聚类分析中的异常数据识别策略

      • 3.2 基于原型的聚类



引言

在进行数据研究并进行优化后所得出的数据能够直接用于建模。依据其目标导向和数据特征我们能够开发出包括分类与预测聚类分析关联规则时序模式以及离群点检测在内的多种应用以为企业识别潜在机会提供支持。

一、分类与预测

对于餐饮行业,常遇到如下问题:

在这里插入图片描述

1.常用的分类与预测算法

在这里插入图片描述

2. 回归分析

基于数据挖掘环境框架中,在此场景下研究者通常会关注两个关键要素:自变量与因变量之间的关联性分析。其中自变量是可得的数据输入项而因变量则是需要进行预测的对象两者间存在显著的相关性关系这一特性成为构建回归模型的基础依据。常见的回归模型如下:

在这里插入图片描述

当自变量之间存在多重共线性时,在应用最小二乘法估计回归系数的过程中会出现偏差。通过采用以下参数改进方法来消除多重共线性的影响——岭回归以及主成分分析法——是主要的解决途径。

3.决策树

它是一种层级结构的形式;每一个\text{叶结点}都代表着一个分类类别;每个\text{内部节点}则代表某个性质分割;根据样本在该属性上的不同取值将被划分为若干个子集;对于\text{非纯}叶节点多数类标签确定了那些落入该节点的所有样本所属类别;构造决策树是在每一次分裂阶段选择合适的特征来进行分割

在这里插入图片描述
复制代码
    #!usr/bin/env python
    # -*- coding:utf-8 -*-
    """
    @author: admin
    @file: ID3决策树.py
    @time: 2021/03/31
    @desc:
    """
    import pandas as pd
    from sklearn.tree import DecisionTreeClassifier, export_graphviz
    from sklearn.preprocessing import LabelEncoder
    import graphviz
    import matplotlib as mpl
    
    data = pd.read_excel('data/sales_data.xls', index_col='序号')
    
    data[data == '好'] = 1
    data[data == '高'] = 1
    data[data == '是'] = 1
    data[data != 1] = -1
    x = data.iloc[:, :3].values.astype(int)
    y = data.iloc[:, 3].values.astype(int)
    dtc = DecisionTreeClassifier(criterion='entropy')
    dtc.fit(x, y)
    
    dot_data = export_graphviz(dtc, out_file='tree.dot',
                           feature_names=['天气', '是否周末', '是否有促销'],
                           class_names=['高', '低'], filled=True,
                           rounded=True, special_characters=True)
    
    with open('tree.dot', encoding='utf-8') as f:
    dot_grapth = f.read()
    dot = graphviz.Source(dot_grapth.replace("helvetica", "MicrosoftYaHei"))   # 解决中文乱码replace("helvetica", "MicrosoftYaHei")
    dot.view()
    
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读
在这里插入图片描述

4.人工神经网络

在应用人工神经网络模型时需设定其网络拓扑架构、单个神经元特性以及相应的学习机制以指导数据处理过程。通常用于执行分类与预测的任务的人工神经网络算法包括

在这里插入图片描述
复制代码
    import pandas as pd
    import tensorflow as tf
    from tensorflow import keras
    from tensorflow.keras import layers, Model, optimizers, losses, metrics, activations
    from tensorflow.keras.layers import Dense, Dropout, Input, Lambda
    import matplotlib as mpl
    
    data = pd.read_excel('data/sales_data.xls', index_col='序号')
    
    data[data == '好'] = 1
    data[data == '高'] = 1
    data[data == '是'] = 1
    data[data != 1] = 0
    x = data.iloc[:, :3].values.astype(int)
    y = data.iloc[:, 3].values.astype(int)
    
    
    def bpModel():
    input = Input(shape=(3,))
    x = Dense(10, activation=tf.nn.relu)(input)
    x = Dense(10, activation=tf.nn.relu)(x)
    output = Dense(1, activation='sigmoid')(x)
    
    model = Model(inputs=input, outputs=output)
    model.compile(optimizer=optimizers.Adam(learning_rate=0.01),
                  loss='binary_crossentropy',
                  metrics=['accuracy'])
    return model
    
    
    def cm_plot(y, yp):
    """
    混淆矩阵可视化
    :param y:
    :param yp:
    :return:
    """
    from sklearn.metrics import confusion_matrix
    
    cm = confusion_matrix(y, yp)
    print(cm)
    import matplotlib.pyplot as plt
    plt.matshow(cm, cmap=plt.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
    
    
    bp = bpModel()
    bp.fit(x, y, epochs=1000, batch_size=10)
    y_pred = bp.predict(x)
    y_pred[y_pred >= 0.5] = 1
    y_pred[y_pred < 0.5] = 0
    
    # 可视化
    cm_plot(y, y_pred).show()
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读
在这里插入图片描述

二、聚类分析

在当前市场环境下,消费者需求呈现出多样性和独特性的趋势。针对餐饮行业而言,常见遇到以下问题:(1)产品同质化程度较高;(2)市场竞争异常激烈。

在这里插入图片描述

这些问题都可以通过聚类分析来实现。

1.常用的聚类分析算法

聚类方法是一种经典的无监督学习技术。在未标记的数据集中进行聚类时,算法通过分析数据间的相似性和差异性将它们分组成若干个群体。这种分类基于以下两个主要标准:首先,在同一类别内的样本之间具有较小的距离;其次,在不同类别之间的样本之间具有较大的距离。

在这里插入图片描述

常用聚类分析方法:

在这里插入图片描述

2.K-Means聚类算法

K-Means聚类方法是一种典型的以距离为基础进行非层次划分的聚类技术。它通过计算样本间的距离来衡量它们之间的相似程度,并在此基础上将样本集划分为预先设定的数量K个类别。为了最小化总误差而将样本集划分为预先设定的数量K个类别。该方法通过计算样本间的距离来衡量它们之间的相似程度,并在此基础上将样本集划分为预先设定的数量K个类别。该方法通过计算样本间的距离来衡量它们之间的相似程度,并在此基础上将样本集划分为预先设定的数量K个类别。

2.1 算法过程
在这里插入图片描述

该聚类方法的结果会受到初始聚类中心随机设置的影响 ,可能会导致结果偏离整体最优分类。通常建议在实际应用中重复执行K-Means算法,并采用误差平方和最小值 对应的聚类划分作为最终结果。

2.2 数据类型与相似性的度量

对于连续属性,要先对各属性值进行标准化,再进行距离计算。

在这里插入图片描述

对于文档数据,可使用余弦相似性。可先将文档数据转换成文档—词矩阵

在这里插入图片描述

3. 目标函数

在这里插入图片描述
在这里插入图片描述

4.消费行为特征分析

以部分餐饮客户消费行为特征数据为例,聚类分析得

复制代码
    import pandas as pd
    import numpy as np
    from sklearn.cluster import KMeans
    from sklearn.preprocessing import StandardScaler
    
    # 加载数据
    data = pd.read_excel('data/consumption_data.xls', index_col='Id')
    # 连续属性标准化
    ss = StandardScaler()
    x = ss.fit_transform(data)
    
    k = 3  # 聚类中心数
    n_iterations = 500  # 聚类的最大循环次数
    kmeans = KMeans(n_clusters=k, max_iter=n_iterations, n_jobs=-1, random_state=1234)
    kmeans.fit(data)  # 训练
    
    # 统计各类别的数目
    r1 = pd.Series(kmeans.labels_).value_counts()
    # 找出聚类中心
    r2 = pd.DataFrame(kmeans.cluster_centers_)
    # 拼接,得到各聚类中心下类别的数目
    r = pd.concat([r2, r1], axis=1)
    # 重命名表头
    r.columns = list(data.columns) + ['类别数目']
    
    # 将聚类类别保存到数据中
    data = pd.concat([data, pd.Series(kmeans.labels_, index=data.index)], axis=1)
    data.to_excel('data/data_type.xls')
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读
在这里插入图片描述

绘制聚类后的概率密度图

复制代码
    import pandas as pd
    import numpy as np
    from sklearn.cluster import KMeans
    from sklearn.preprocessing import StandardScaler
    import matplotlib.pyplot as plt
    
    # 加载数据
    data = pd.read_excel('data/consumption_data.xls', index_col='Id')
    # 连续属性标准化
    ss = StandardScaler()
    x = ss.fit_transform(data)
    
    k = 3  # 聚类中心数
    n_iterations = 500  # 聚类的最大循环次数
    kmeans = KMeans(n_clusters=k, max_iter=n_iterations, n_jobs=-1, random_state=1234)
    kmeans.fit(data)  # 训练
    
    # 统计各类别的数目
    r1 = pd.Series(kmeans.labels_).value_counts()
    # 找出聚类中心
    r2 = pd.DataFrame(kmeans.cluster_centers_)
    # 拼接,得到各聚类中心下类别的数目
    r = pd.concat([r2, r1], axis=1)
    # 重命名表头
    r.columns = list(data.columns) + ['类别数目']
    print(r)
    # 将聚类类别保存到数据中
    rs = pd.concat([data, pd.Series(kmeans.labels_, index=data.index)], axis=1)
    rs.columns = list(data.columns) + ['聚类类别']
    rs.to_excel('data/data_type.xls')
    
    # 解决中文字体问题
    plt.rcParams['font.sans-serif'] = [u'simHei']
    plt.rcParams['axes.unicode_minus'] = False
    
    
    def density_plot(data1):
    p = data1.plot(kind='kde', linewidth=2, subplots=True, sharex=False)
    [p[i].set_ylabel(u'密度') for i in range(3)]
    plt.legend()
    return plt
    
    
    # 概率密度图文件名前缀
    pic_output = './data/pd'
    for i in range(k):
    density_plot(data[rs[u'聚类类别'] == i]).show()
    # density_plot(data[rs[u'聚类类别'] == i]).savefig(u'%s%s.png' %(pic_output, i))
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.python中主要的聚类分析算法

scikit-learn库中实现的主要聚类算法包括:K-Means聚算法、层次聚合法以及基于神经网络的聚类算法等技术。其中一些关键的功能模块及其具体实现可参考下表所示。

在这里插入图片描述

三、关联规则

关联规则分析被视为数据挖掘领域中最具代表性的研究方法之一。
其主要目标是在复杂的数据集合中识别各项目之间的潜在联系,并使这些联系以非直观的方式呈现。
该方法在餐饮业中的应用非常广泛。
例如,在某些情况下(如某道主菜搭配其配菜),它们之间存在相互促进的关系;
而在另一些情况下(如某类食材与其竞争对手),则可能形成激烈的竞争态势。
通过向顾客推荐与他们当前选择项目高度相关的商品组合(如根据某一餐品自动推荐其常见搭配),能够帮助消费者做出更具针对性的选择。

1.常用的关联规则算法

在这里插入图片描述

2.Apriori算法

Apriori算法的核心理念在于识别事务数据库中频率最高的项目组合,并基于获得的最大频繁项目组合以及预设的最小置信度阈值来构建具有较强关联性的规则。

2.1.Apriori的性质

每个非空子集合必然都是一个频繁项目集合。
基于这一特性可知:当将事务A加入到非频繁项目集合I中时,
新的项目组合I∪A必定不再是高频项目组合。

2.2.Apriori算法实现过程

第一步:
识别所有满足条件的频繁项集(其支持度均不低于预设的最小支持度阈值),在此过程中将连接操作与剪枝操作相结合,最终获得最大的k-阶频繁项目集合L_k

连接步的主要任务是识别 K 项集。对于给定的具体最小支持度阈值, 我们首先从所有可能的一项目前集合中筛选出满足最低支持度要求的一项目前集合;接着, 我们通过将上一步获得的一项目前集合自连运算生成所有可能的二项目前组合, 并从中移除不满足最低支持度要求的部分以获得二项目前集合;随后, 我们继续通过将当前二项目前集合与上一步的一项目前集合进行组合运算生成三项目前组合, 并从中筛选出符合条件的部分以确定三项目前集合;以此类推, 直到我们通过持续迭代的方式最终确定最大项目的频繁集合。

  • 剪枝步
    剪枝步随后紧随连接步,在生成候选项集C_k时的目标是缩减搜索空间。基于Apriori原则:任何频繁项集的所有非空子集都必然是频繁项集。因此,在构建候选项集C_k时,只有满足这一原则的项集才会被保留。这一过程被称为剪枝操作。

第二步:
由频繁项集生成强关联规则。基于第一步的结果表明,在未达到预定的最小支持阈值的情况下筛选出的相关项目集合后,在剩余符合条件的相关项目集合中进行处理,则可挖掘出强关联规则。

2.3.Apriori算法实现过程实例

基于餐饮行业的点餐数据作为研究对象,在处理事务数据时将其整理为符合关联规则模型需求的数据格式。设定最低支持度阈值为0.2,并对菜品ID进行编码处理。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.Apriori算法—python实现

数据集链接

复制代码
    import numpy as np
    import pandas as pd
    
    
    def connect_string(x, ms):
    """
    与1项频繁集连接生成新的项集
    :param x: 项集
    :param ms:
    :return: 新的项集
    """
    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'-'):
    """
    寻找关联规则
    :param d: 数据集
    :param support: 最小支持度
    :param confidence: 最小置信度
    :param ms: 项集之间连接符号
    :return: 强关联规则以及其支持度与置信度
    """
    # 存储输出结果
    result = pd.DataFrame(index=['support', 'confidence'])
    
    # 1项集的支持度序列
    support_series = 1.0 * d.sum(axis=0) / d.shape[0]
    # 基于给定的最小支持度进行筛选,得到1项频繁集
    column = list(support_series[support_series > support].index)
    
    # 当1项频繁集个数大于1时
    k = 0
    while len(column) > 1:
        k = k + 1
        print(u'\n正在进行第%s次搜索...' % k)
        column = connect_string(column, ms)
        print(u'数目:%s...' % len(column))
        # 乘积为1表示两个项集同时发生,乘积为0表示不同发生
        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 = []
        # 遍历可能的推理,如{A,B,C}究竟是A+B-->C还是B+C-->A还是C+A-->B?
        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
    
    
    if __name__ == '__main__':
    # 加载数据
    data = pd.read_excel('../data/menu_orders.xls', header=None)
    print('转换原数据到0-1矩阵')
    ct = lambda x: pd.Series(1, index=x[pd.notnull(x)])
    b = map(ct, data.values)
    data = pd.DataFrame(list(b)).fillna(0)
    # 删除中间变脸b
    del b
    
    support = 0.2  # 最小支持度
    confidence = 0.5  # 最小置信度
    
    find_rule(data, support, confidence)
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读
复制代码
    转换原数据到0-1矩阵
    
    正在进行第1次搜索...
    数目:6...
    
    正在进行第2次搜索...
    数目:3...
    
    正在进行第3次搜索...
    数目:0...
    
    结果为:
       support  confidence
    e-a        0.3    1.000000
    e-c        0.3    1.000000
    c-e-a      0.3    1.000000
    a-e-c      0.3    1.000000
    c-a        0.5    0.714286
    a-c        0.5    0.714286
    a-b        0.5    0.714286
    c-b        0.5    0.714286
    b-a        0.5    0.625000
    b-c        0.5    0.625000
    a-c-e      0.3    0.600000
    b-c-a      0.3    0.600000
    a-c-b      0.3    0.600000
    a-b-c      0.3    0.600000
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

其中,'e—a’具体来说即表示e的发生能够推出a的发生情况。该关系式的可信度达到100%,支撑率为30%。通过搜索获得的相关规则未必具有实际价值,在实际应用中需依据具体场景筛选出具有实用价值的相关关联规则并给予合理的解释说明

四、时间序列模式

见这个博客

五、离群点检测

离群点检测是数据挖掘中的一个重要组成部分,在这一领域发挥着关键作用。它的主要职责是识别出与其他大多数对象明显不同的个体。然而,在大多数情况下这些差异性信息会被视为噪音而被排除在外。值得注意的是在某些情况下那些看似普通的噪音数据可能会隐藏着更为重要的研究价值

1.离群点的成因及分类

离群点的主要原因在于数据来自不同类别以及在自然变化中存在波动,并且受到数据采集过程中的测量误差的影响。

在这里插入图片描述

2.离群点检测方法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.基于聚类的离群点检测方法

聚类分析主要用于识别局部强关联的对象集合;而异常检测则关注那些与多数对象关联度较低的对象。由此可见,聚类分析同样适用于离群点识别。以下将介绍两种基于聚类的离群点检测方法。

3.1 丢弃远离其他簇的小簇
在这里插入图片描述

3.2 基于原型的聚类

在这里插入图片描述

下面使用第二种

复制代码
    import numpy as np
    import pandas as pd
    
    # 参数初始化
    inputfile = '../data/consumption_data.xls'  # 销量及其他属性数据
    k = 3  # 聚类的类别
    threshold = 2  # 离散点阈值
    iteration = 500  # 聚类最大循环次数
    data = 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) + ['聚类类别']  # 重命名表头
    
    norm = []
    for i in range(k):  # 逐一处理
      norm_tmp = r[['R', 'F', 'M']][r['聚类类别'] == 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('编号')
    plt.ylabel('相对距离')
    plt.show()
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

参考:

  • 《python分析与数据挖掘实战》

如果您觉得我的内容对您有所帮助,请不要客气麻烦点击右上角的"在看"并留意关注哦!对我来说确实非常重要的是您的认可与支持!如果您愿意互相关注的话可以在评论区留下您的反馈或者通过私信与我联系哦!

在这里插入图片描述

全部评论 (0)

还没有任何评论哟~