|
|
<template>
|
|
|
<!-- <el-scrollbar ref="scrollbar" height="800px"> -->
|
|
|
<div class="main-top">
|
|
|
<span style="font-weight: bold; font-size: 18px; color: #3596eb">任务描述</span>
|
|
|
<p style="font-weight: 400; font-size: 12px; color: #e2e7ee !important">使用“购物车数据”,对所购商品进行购物篮分析(关联规则挖掘),其中min_support = 0.4,min_confidence = 0.5,最后将运行结果提交实训任务。</p>
|
|
|
</div>
|
|
|
<div class="main-but">
|
|
|
<el-button @click="runResultShow = true">
|
|
|
<img src="../../../assets/images/导入.png" alt="" />
|
|
|
算法知识导入
|
|
|
</el-button>
|
|
|
<el-button @click="taskSubmit">
|
|
|
<img src="../../../assets/images/提交.png" alt="" />
|
|
|
实训任务提交
|
|
|
</el-button>
|
|
|
</div>
|
|
|
<div class="app-main">
|
|
|
<div class="main-left">
|
|
|
<el-scrollbar height="640px" style="padding: 0 10px" min-size="5">
|
|
|
<div>
|
|
|
<div class="left-top">
|
|
|
<span>一、选择指标</span>
|
|
|
</div>
|
|
|
<div class="metrics">
|
|
|
<el-select v-model="input" placeholder="请选择" style="width: 180px" @change="optionData">
|
|
|
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
</el-select>
|
|
|
</div>
|
|
|
<div class="metrics-table" style="margin-top: 10px">
|
|
|
<el-table border :data="tableData" style="width: 100%" :header-cell-style="headerCellStyle" @selection-change="handleSelectionChange">
|
|
|
<el-table-column type="selection" label="Date" align="center" :selectable="flag" />
|
|
|
<el-table-column prop="text" label="指标" align="center" />
|
|
|
</el-table>
|
|
|
<el-button @click="taskZB">确定</el-button>
|
|
|
</div>
|
|
|
<div class="left-top" style="margin-top: 50px">
|
|
|
<span>二、数据预处理</span>
|
|
|
</div>
|
|
|
<div class="metrics">
|
|
|
<el-select v-model="input2" @change="optionData2" placeholder="请选择" style="width: 180px">
|
|
|
<el-option v-for="item in options2" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
</el-select>
|
|
|
</div>
|
|
|
<div class="metrics" style="margin-top: 15px">
|
|
|
<el-select v-model="input3" @change="optionData2" placeholder="请选择" style="width: 180px">
|
|
|
<el-option v-for="item in options3" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
</el-select>
|
|
|
</div>
|
|
|
<div class="left-top" style="margin-top: 50px">
|
|
|
<span>三、模型参数设置</span>
|
|
|
</div>
|
|
|
<div class="metrics-table" style="margin-top: 10px">
|
|
|
<span style="font-weight: 400; font-size: 12px; color: #ffffff">聚类方法:</span>
|
|
|
<div class="metrics" style="margin-top: 10px">
|
|
|
<el-select v-model="input4" placeholder="请选择" style="width: 180px">
|
|
|
<el-option v-for="item in options4" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
</el-select>
|
|
|
</div>
|
|
|
<div style="margin-top: 10px; color: #ffffff">
|
|
|
<span style="font-weight: 400; font-size: 12px; color: #ffffff">最小支持度阀值:</span>
|
|
|
<el-input v-model="input5" style="width: 160px; margin-top: 5px" />
|
|
|
%
|
|
|
</div>
|
|
|
<div style="margin-top: 10px; color: #ffffff">
|
|
|
<span style="font-weight: 400; font-size: 12px; color: #ffffff">最小置信度:</span>
|
|
|
<el-input v-model="input6" style="width: 160px; margin-top: 5px" />
|
|
|
%
|
|
|
</div>
|
|
|
<el-button @click="computation">计算</el-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div style="margin-top: auto">
|
|
|
<div class="startOver" @click="startOver()">
|
|
|
<img src="../../../assets/images/重新开始.png" alt="" />
|
|
|
<span>重新开始</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</el-scrollbar>
|
|
|
|
|
|
</div>
|
|
|
<div class="main-right">
|
|
|
<el-scrollbar height="550px" ref="scrollbar" style="padding: 20px">
|
|
|
<div>
|
|
|
<span style="font-weight: bold; font-size: 18px; color: #3596eb">分析数据:</span>
|
|
|
<el-table :data="tableData2" style="width: 100%; margin-top: 10px" :header-cell-style="headerCellStyle" height="350">
|
|
|
<el-table-column v-for="column in tableLabel" :key="column.prop" :prop="column.prop" :label="column.label" align="center" />
|
|
|
</el-table>
|
|
|
<!-- <el-pagination style="margin-top:10px" background layout="prev, pager, next" :total="1000" /> -->
|
|
|
</div>
|
|
|
<div class="analysisResults" style="margin-top: 20px">
|
|
|
<span style="font-weight: bold; font-size: 18px; color: #3596eb; display: block">分析结果:</span>
|
|
|
<el-button v-if="uplodFlag" @click="upload">下载</el-button>
|
|
|
<el-table ref="exportTableRef" v-loading="loading1" :data="tableData3" row-key="TSuid" style="width: 100%; margin-top: 10px" :header-cell-style="headerCellStyle" height="400">
|
|
|
<el-table-column v-for="column in tableLabel2" :key="column.prop" :prop="column.prop" :label="column.label" align="center" />
|
|
|
</el-table>
|
|
|
<!-- <el-pagination style="margin-top:10px" background layout="prev, pager, next" :total="1000" /> -->
|
|
|
</div>
|
|
|
</el-scrollbar>
|
|
|
</div>
|
|
|
</div>
|
|
|
<!-- </el-scrollbar> -->
|
|
|
|
|
|
<el-dialog v-model="dialogVisible" title="实训任务提交" width="400" custom-class="dialogClass" :show-close="false">
|
|
|
<template #header="{ close, titleId, titleClass }">
|
|
|
<div class="my-header">
|
|
|
<span :id="titleId" :class="titleClass">实训任务提交</span>
|
|
|
<img class="gbImg" src="../../../assets/images/关闭.png" @click="close" alt="" />
|
|
|
</div>
|
|
|
<img class="xtImg" src="../../../assets/images/线条.png" alt="" />
|
|
|
</template>
|
|
|
<div class="from-item">
|
|
|
<span style="color: #ffffff; font-weight: 700">最终筛选的关联子集:</span>
|
|
|
<div>
|
|
|
<el-checkbox v-model="formData.value1" label="{'牛奶', '面包'}" size="large" />
|
|
|
</div>
|
|
|
<div>
|
|
|
<el-checkbox v-model="formData.value2" label="{'牛奶', '黄油'}" size="large" />
|
|
|
</div>
|
|
|
<div>
|
|
|
<el-checkbox v-model="formData.value3" label="{'面包', '黄油'}" size="large" />
|
|
|
</div>
|
|
|
<div>
|
|
|
<el-checkbox v-model="formData.value4" label="{'啤酒', '黄油'}" size="large" />
|
|
|
</div>
|
|
|
<div>
|
|
|
<el-checkbox v-model="formData.value5" label="{'面包', '啤酒'}" size="large" />
|
|
|
</div>
|
|
|
</div>
|
|
|
<template #footer>
|
|
|
<div class="dialog-footer">
|
|
|
<el-button @click="task()">确定</el-button>
|
|
|
<el-button type="primary" @click="dialogVisible = false">返回</el-button>
|
|
|
</div>
|
|
|
</template>
|
|
|
</el-dialog>
|
|
|
|
|
|
<pop-model :showModel="runResultShow" title="回归分析" @closePop="runResultShow = false">
|
|
|
<template v-slot:content>
|
|
|
<div>
|
|
|
<p style="font-weight: 700; font-size: 22px">一、简介</p>
|
|
|
<p>Apriori算法是一种用于挖掘数据集中频繁项集的算法,进而用于生成关联规则。这种算法在数据挖掘、机器学习、市场篮子分析等多个领域都有广泛的应用。</p>
|
|
|
<p style="font-size: 19px; font-weight: 600">什么是关联规则挖掘?</p>
|
|
|
<p>
|
|
|
关联规则挖掘是数据挖掘中的一个重要分支,其目标是发现在一个数据集中变量间存在的有趣的关联或模式。
|
|
|
<br />
|
|
|
例子: 假设在一个零售商的交易数据中,如果客户购买了啤酒,他们也很有可能购买薯片。这里的“啤酒”和“薯片”就形成了一个关联规则。
|
|
|
</p>
|
|
|
<p style="font-size: 19px; font-weight: 600">什么是频繁项集?</p>
|
|
|
<p>
|
|
|
频繁项集是在数据集中出现次数大于或等于最小支持度(Minimum Support Threshold)的项的集合。
|
|
|
<br />
|
|
|
例子: 在超市购物数据中,如果“牛奶”和“面包”这一组合经常一起出现在同一个购物篮里,并且出现的次数超过了最小支持度,那么{"牛奶", "面包"}就是一个频繁项集。
|
|
|
</p>
|
|
|
<p style="font-size: 19px; font-weight: 600">什么是支持度与置信度?</p>
|
|
|
<li>
|
|
|
支持度(Support): 是某个项集在所有交易中出现的频率。它用于衡量一个项集的普遍性。
|
|
|
<br />
|
|
|
例子: 如果我们有100笔交易,其中有30笔交易包含了“牛奶”,那么“牛奶”的支持度就是30%。
|
|
|
</li>
|
|
|
<li>
|
|
|
置信度(Confidence): 是在A出现的情况下,B出现的条件概率。
|
|
|
<br />
|
|
|
例子: 如果在包含“牛奶”的所有交易中,有70%的交易也包含了“面包”,那么从“牛奶”到“面包”的置信度就是70%。
|
|
|
</li>
|
|
|
<p style="font-size: 19px; font-weight: 600">Apriori算法的重要性</p>
|
|
|
<p>
|
|
|
Apriori算法由于其简单、高效的特性,在数据挖掘中有着广泛的应用。它不仅能用于挖掘数据中的隐藏模式,还能用于诸如产品推荐、用户行为分析、网络安全等多个应用场景。
|
|
|
<br />
|
|
|
例子: 在电子商务网站中,Apriori算法可以用于分析用户购买历史数据,进而实现个性化推荐,提升销售额和用户满意度。
|
|
|
</p>
|
|
|
<p style="font-size: 19px; font-weight: 600">应用场景</p>
|
|
|
<p>由于其广泛的用途和灵活性,Apriori算法在以下几个主要领域内有着广泛的应用:</p>
|
|
|
<li>市场篮子分析: 了解哪些产品经常被一起购买,以进行有效的产品布局或优惠策略。</li>
|
|
|
<li>医疗诊断: 分析病人的历史数据,找出病症和治疗方案之间的关联。</li>
|
|
|
<li>网络安全: 通过分析网络日志,找出异常模式,以预防或检测安全威胁。</li>
|
|
|
<p>通过这些定义和例子,我们可以更全面地了解Apriori算法的基本概念、重要性和应用范围,为后续的技术解析和实战应用打下坚实的基础。</p>
|
|
|
<p style="font-weight: 700; font-size: 22px">二、理论基础</p>
|
|
|
<p>在深入探讨Apriori算法之前,理解其背后的理论基础是非常重要的。本节将详细介绍关联规则挖掘的基础概念,包括项集、支持度、置信度、提升度以及如何使用这些概念来挖掘有用的关联规则。</p>
|
|
|
<p style="font-size: 19px; font-weight: 600">项和项集</p>
|
|
|
<li>
|
|
|
项(Item): 在关联规则挖掘中,项通常指数据集中的一个元素。
|
|
|
<br />
|
|
|
例子: 在一个超市的购物篮数据中,"牛奶"、"面包"、"啤酒"等都是单个的项。
|
|
|
</li>
|
|
|
<li>
|
|
|
项集(Itemset): 是一个项的集合,可以包含一个或多个项。
|
|
|
<br />
|
|
|
例子: {"牛奶", "面包"} 和 {"啤酒", "薯片", "面包"} 都是项集。
|
|
|
</li>
|
|
|
<p style="font-size: 19px; font-weight: 600">支持度(Support)</p>
|
|
|
<p>
|
|
|
支持度是一个度量,用于表示一个项集在整个数据集中出现的频率。
|
|
|
<br />
|
|
|
!file
|
|
|
</p>
|
|
|
<p style="font-size: 19px; font-weight: 600">置信度(Confidence)</p>
|
|
|
<p>置信度表示在包含项集X的所有事务中,也包含项集Y的事务的概率。</p>
|
|
|
<img src="@/assets/images/f2001.png" alt="" style="width: 600px;"/>
|
|
|
<p style="font-size: 19px; font-weight: 600">提升度(Lift)</p>
|
|
|
<p>提升度用于衡量项集X和Y的出现是否相互独立。</p>
|
|
|
<img src="@/assets/images/f2002.png" alt="" style="width: 600px;"/>
|
|
|
<p style="font-size: 19px; font-weight: 600">Apriori原理</p>
|
|
|
<p>
|
|
|
Apriori原理是Apriori算法的核心,它基于一个简单但重要的观察:一个项集是频繁的,那么它的所有子集也必须是频繁的。
|
|
|
<br />
|
|
|
例子: 如果{"牛奶", "面包", "啤酒"}是一个频繁项集,那么{"牛奶", "面包"}、{"牛奶", "啤酒"}和{"面包", "啤酒"}也必须是频繁项集。
|
|
|
<br />
|
|
|
通过以上的概念和例子,我们应该对关联规则挖掘的基础理论有了更深入的了解。这为我们后续详解Apriori算法以及实际应用提供了坚实的基础。
|
|
|
</p>
|
|
|
<p style="font-weight: 700; font-size: 22px">三、Apriori算法概述</p>
|
|
|
<p>Apriori算法是由Agrawal和Srikant于1994年提出的,用于高效地挖掘频繁项集和生成关联规则。其名字“Apriori”来源于拉丁语,意为“从先验知识”。这很好地反映了算法的核心思想:利用已知的频繁项集(即先验知识)来更有效地找到更大的频繁项集。</p>
|
|
|
<p style="font-size: 19px; font-weight: 600">算法步骤</p>
|
|
|
<img src="@/assets/images/f2004.png" alt="" />
|
|
|
<p>
|
|
|
Apriori算法的执行流程主要包含两个步骤:
|
|
|
<br />
|
|
|
1.频繁项集生成(Frequent Itemset Generation): 找出满足最小支持度阈值的所有频繁项集。
|
|
|
<br />
|
|
|
2.关联规则生成(Association Rule Generation): 从频繁项集中生成高置信度的关联规则。
|
|
|
</p>
|
|
|
<p style="font-size: 19px; font-weight: 600">频繁项集生成</p>
|
|
|
<p>
|
|
|
1.扫描数据集,找出所有单一项的支持度,并筛选出满足最小支持度的项。
|
|
|
<br />
|
|
|
2.使用满足最小支持度的项生成新的候选项集。
|
|
|
<br />
|
|
|
3.计算新生成的候选项集的支持度,并再次筛选。
|
|
|
<br />
|
|
|
4.重复上述步骤,直到不能生成新的频繁项集。
|
|
|
<br />
|
|
|
例子: 假设有一个购物交易数据集,其中包括5笔交易。第一步是计算所有单一商品(如“牛奶”,“面包”等)在这5笔交易中的出现次数,并筛选出那些出现次数达到最小支持度的商品。
|
|
|
</p>
|
|
|
<p style="font-size: 19px; font-weight: 600">关联规则生成</p>
|
|
|
<p>
|
|
|
1.对于每一个频繁项集,生成所有可能的非空子集。
|
|
|
<br />
|
|
|
2.对每一条生成的规则 ( A \Rightarrow B ),计算其置信度。
|
|
|
<br />
|
|
|
3.如果规则的置信度满足最小置信度要求,则该规则为有效关联规则。
|
|
|
</p>
|
|
|
<p>例子: 对于频繁项集 {"牛奶", "面包", "黄油"},可能的规则有 "牛奶, 面包 -> 黄油", "牛奶, 黄油 -> 面包" 等。计算这些规则的置信度,并筛选出满足最小置信度的规则。</p>
|
|
|
<p style="font-size: 19px; font-weight: 600">优缺点</p>
|
|
|
<p style="font-size: 19px; font-weight: 600">优点</p>
|
|
|
<li>简单易懂: Apriori算法基于直观的原理,并且计算过程简单。</li>
|
|
|
<li>可扩展性强: 算法可以应用于大规模的数据集。</li>
|
|
|
<p style="font-size: 19px; font-weight: 600">缺点</p>
|
|
|
<li>计算量大: 在大数据集上,可能需要生成大量的候选项集。</li>
|
|
|
<li>多次扫描数据: 算法需要多次扫描数据集以计算项集的支持度,这在数据集很大时可能是低效的。</li>
|
|
|
<p>
|
|
|
例子: 在一个包含百万级交易数据的电子商务网站中,使用Apriori算法可能需要消耗大量计算资源和时间。
|
|
|
<br />
|
|
|
通过以上的详细描述和例子,我们应该对Apriori算法有了全面而深入的理解。这为我们后续的技术解析和实战应用奠定了基础。
|
|
|
</p>
|
|
|
<p style="font-weight: 700; font-size: 22px">四、实战应用</p>
|
|
|
<p>
|
|
|
在理解了Apriori算法的理论基础和工作原理之后,现在我们将进一步探讨其在实际场景中的应用。特别是在购物篮分析和推荐系统中,Apriori算法被广泛应用。
|
|
|
<br />
|
|
|
为了更好地说明这一点,下面将通过Python展示如何实现Apriori算法,并用一个简单的购物数据集进行演示。
|
|
|
</p>
|
|
|
<p style="font-size: 19px; font-weight: 600">购物篮分析</p>
|
|
|
<p>购物篮分析(Market Basket Analysis)是一种在零售业非常流行的技术,用于发现顾客购买产品之间的关联规则。</p>
|
|
|
<p style="font-size: 19px; font-weight: 600">输入和输出</p>
|
|
|
<li>输入: 一组交易数据,每一笔交易包含多个购买的商品。</li>
|
|
|
<li>输出: 满足最小支持度和最小置信度的关联规则。</li>
|
|
|
<p style="font-size: 19px; font-weight: 600">Python实现代码</p>
|
|
|
<MdPreview v-model="text" />
|
|
|
<p style="font-weight: 700; font-size: 22px">五、性能优化与扩展</p>
|
|
|
<p>Apriori算法虽然在多个领域有着广泛的应用,但其在大数据集上的性能表现并不尽如人意。这是由于它需要多次扫描数据集以及生成大量的候选项集。在这一节中,我们将讨论针对这些问题的性能优化方案和扩展方法。</p>
|
|
|
<p style="font-size: 19px; font-weight: 600">优化策略</p>
|
|
|
<p>优化Apriori算法的主要方法包括:</p>
|
|
|
<p style="font-size: 19px; font-weight: 600">减少数据扫描次数</p>
|
|
|
<p>
|
|
|
由于Apriori算法在每一轮都需要扫描整个数据集以计算支持度,因此一个直观的优化方式就是减少数据扫描的次数。
|
|
|
<br />
|
|
|
例子: 通过构建一个事务-项倒排索引,你可以在单次数据集扫描后立即找到任何项集的支持度。
|
|
|
</p>
|
|
|
<p style="font-size: 19px; font-weight: 600">采用数据压缩技术</p>
|
|
|
<p>
|
|
|
可以通过压缩事务数据来减少计算量,例如使用位向量来表示事务。
|
|
|
<br />
|
|
|
例子: 若数据集中有100个商品,每一笔交易都可以通过一个100位的位向量来表示。这种方式可以显著减少数据的存储需求。
|
|
|
</p>
|
|
|
<p style="font-size: 19px; font-weight: 600">使用Hashing技术</p>
|
|
|
<p>
|
|
|
通过使用哈希表来存储候选项集和它们的计数,可以加速支持度的计算。
|
|
|
<br />
|
|
|
例子: 在生成候选项集时,可以使用哈希函数来将项集映射到哈希表的一个位置,并在该位置增加相应的计数。
|
|
|
</p>
|
|
|
<p style="font-size: 19px; font-weight: 600">扩展方法</p>
|
|
|
<p style="font-size: 19px; font-weight: 600">并行化</p>
|
|
|
<p>
|
|
|
Apriori算法可以通过数据或任务并行化进行扩展,以利用多处理器或分布式计算环境。
|
|
|
<br />
|
|
|
例子: 在一个分布式系统中,可以将数据集划分为多个子集,并在各个节点上并行计算支持度和生成频繁项集。
|
|
|
</p>
|
|
|
<p style="font-size: 19px; font-weight: 600">支持近似挖掘</p>
|
|
|
<p>
|
|
|
对于一些应用场景,完全精确的频繁项集挖掘可能不是必需的。在这种情况下,可以使用近似算法来加速计算。
|
|
|
<br />
|
|
|
例子: 使用Monte Carlo方法或其他随机抽样技术,通过部分数据来估计整个数据集的频繁项集。
|
|
|
</p>
|
|
|
<p style="font-size: 19px; font-weight: 600">集成其他数据挖掘算法</p>
|
|
|
<p>
|
|
|
Apriori算法可以与其他数据挖掘或机器学习算法结合使用,以解决更复杂的问题。
|
|
|
<br />
|
|
|
例子: 在一个推荐系统中,除了使用Apriori算法找出频繁项集外,还可以使用聚类算法对用户进行分群,从而实现更个性化的推荐。
|
|
|
<br />
|
|
|
通过这些优化和扩展方法,我们不仅可以提升Apriori算法在大数据环境下的性能,还可以拓宽其应用范围。这些都为进一步的研究和应用提供了有益的方向。
|
|
|
</p>
|
|
|
<p style="font-weight: 700; font-size: 22px">六、总结</p>
|
|
|
<p>通过本文的探讨,我们不仅对Apriori算法有了全面且深入的了解,而且掌握了它在实际问题中的应用,特别是在购物篮分析和推荐系统方面。然而,我们也注意到了这一算法在面对大规模数据时存在的局限性。</p>
|
|
|
<li>支持度与置信度的平衡: 在实际应用中,选择合适的支持度和置信度阈值是一门艺术。过低的阈值可能会导致大量不显著的关联规则,而过高的阈值可能会漏掉一些有用的规则。</li>
|
|
|
<li>实时性问题: 在动态变化的数据集上,如何实现Apriori算法的实时或近实时分析也是一个值得关注的问题。这在电子商务等快速响应的场景中尤为重要。</li>
|
|
|
<li>多维、多层分析: 现有的Apriori算法主要集中在单一的项集层面,未来可以考虑如何将其扩展到多维或多层的关联规则挖掘。</li>
|
|
|
<li>算法与模型的集成: 未来的研究趋势可能会更多地集中在将关联规则挖掘与其他机器学习模型(如神经网络、决策树等)集成,以解决更为复杂的问题。</li>
|
|
|
<p>
|
|
|
在今后的工作中,探究这些技术洞见的相关性和应用价值,以及将Apriori算法与现代计算架构(如GPU、分布式计算等)更紧密地结合,将是关键的研究方向。
|
|
|
<br />
|
|
|
总之,Apriori算法在数据挖掘和关联分析领域有着广阔的应用前景。然而,为了使其能够更好地适应现代数据的规模和复杂性,还需要在算法优化和应用扩展方面进行更多的研究和探索。希望本文能为您在这一领域的学习和应用提供有用的信息和启示。
|
|
|
</p>
|
|
|
</div>
|
|
|
</template>
|
|
|
</pop-model>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
import * as portraitModel from "@/api/portraitModel";
|
|
|
import * as echarts from "echarts";
|
|
|
import * as XLSX from "XLSX";
|
|
|
import { MdEditor, MdPreview } from "md-editor-v3";
|
|
|
import "md-editor-v3/lib/style.css";
|
|
|
import * as API from "@/api/AI.js";
|
|
|
import { getUserInfo } from "@/utils/auth";
|
|
|
import { onMounted, reactive, ref } from "vue";
|
|
|
import popModel from "@/views/components/popModal.vue";
|
|
|
const { proxy } = getCurrentInstance();
|
|
|
const formData = reactive({
|
|
|
value1: "",
|
|
|
value2: "",
|
|
|
value3: "",
|
|
|
value4: "",
|
|
|
value5: "",
|
|
|
});
|
|
|
const scrollbar=ref(null)
|
|
|
const loading1 =ref(false)
|
|
|
const task = () => {
|
|
|
let errorNumber=0
|
|
|
if (Object.values(formData).every((item) => item == "")) {
|
|
|
proxy.$modal.msgWarning("请填写完整");
|
|
|
return;
|
|
|
}
|
|
|
if(!formData.value3||!formData.value2){
|
|
|
errorNumber=1
|
|
|
}else
|
|
|
if(formData.value1||formData.value4||formData.value5){
|
|
|
errorNumber=1
|
|
|
}
|
|
|
portraitModel
|
|
|
.submit({
|
|
|
userId: JSON.parse(getUserInfo()).userId,
|
|
|
taskName: "关联规则挖掘",
|
|
|
numberOfErrors: errorNumber,
|
|
|
})
|
|
|
.then((res) => {
|
|
|
dialogVisible.value = false;
|
|
|
proxy.$modal.msgSuccess("提交成功");
|
|
|
});
|
|
|
};
|
|
|
const dialogVisible = ref(false);
|
|
|
const runResultShow = ref(false);
|
|
|
const tableLabel = reactive([{ prop: "date", label: "" }]);
|
|
|
const tableLabel2 = reactive([{ prop: "date", label: "" }]);
|
|
|
const text = ref(`首先导入必要的库:
|
|
|
\`\`\`python
|
|
|
from itertools import chain, combinations
|
|
|
\`\`\`
|
|
|
接着定义几个辅助函数:
|
|
|
\`\`\`python
|
|
|
# 生成候选项集的所有非空子集
|
|
|
def powerset(s):
|
|
|
return chain.from_iterable(combinations(s, r) for r in range(1, len(s)))
|
|
|
# 计算支持度
|
|
|
def calculate_support(itemset, transactions):
|
|
|
return sum(1 for transaction in transactions if itemset.issubset(transaction)) / len(transactions)
|
|
|
\`\`\`
|
|
|
现在我们来实现Apriori算法:
|
|
|
\`\`\`python
|
|
|
def apriori(transactions, min_support, min_confidence):
|
|
|
# 初始化频繁项集和关联规则列表
|
|
|
frequent_itemsets = []
|
|
|
association_rules = []
|
|
|
# 第一步:找出单项频繁项集
|
|
|
singletons = {frozenset([item]) for transaction in transactions for item in transaction}
|
|
|
singletons = {itemset for itemset in singletons if calculate_support(itemset, transactions) >= min_support}
|
|
|
frequent_itemsets.extend(singletons)
|
|
|
# 迭代找出所有其他频繁项集
|
|
|
prev_frequent_itemsets = singletons
|
|
|
while prev_frequent_itemsets:
|
|
|
# 生成新的候选项集
|
|
|
candidates = {itemset1 | itemset2 for itemset1 in prev_frequent_itemsets for itemset2 in prev_frequent_itemsets if len(itemset1 | itemset2) == len(itemset1) + 1}
|
|
|
# 计算支持度并筛选
|
|
|
new_frequent_itemsets = {itemset for itemset in candidates if calculate_support(itemset, transactions) >= min_support}
|
|
|
frequent_itemsets.extend(new_frequent_itemsets)
|
|
|
# 生成关联规则
|
|
|
for itemset in new_frequent_itemsets:
|
|
|
for subset in powerset(itemset):
|
|
|
subset = frozenset(subset)
|
|
|
diff = itemset - subset
|
|
|
if diff:
|
|
|
confidence = calculate_support(itemset, transactions) / calculate_support(subset, transactions)
|
|
|
if confidence >= min_confidence:
|
|
|
association_rules.append((subset, diff, confidence))
|
|
|
prev_frequent_itemsets = new_frequent_itemsets
|
|
|
return frequent_itemsets, association_rules
|
|
|
\`\`\`
|
|
|
### 示例和输出
|
|
|
假设我们有以下简单的购物数据集:
|
|
|
\`\`\`python
|
|
|
transactions = [
|
|
|
{'牛奶', '面包', '黄油'},
|
|
|
{'啤酒', '面包'},
|
|
|
{'牛奶', '啤酒', '黄油'},
|
|
|
{'牛奶', '鸡蛋'},
|
|
|
{'面包', '鸡蛋', '黄油'}
|
|
|
]
|
|
|
\`\`\`
|
|
|
调用Apriori算法:
|
|
|
\`\`\`python
|
|
|
min_support = 0.4
|
|
|
min_confidence = 0.5
|
|
|
frequent_itemsets, association_rules = apriori(transactions, min_support, min_confidence)
|
|
|
print("频繁项集:", frequent_itemsets)
|
|
|
print("关联规则:", association_rules)
|
|
|
\`\`\`
|
|
|
输出可能如下:
|
|
|
\`\`\`python
|
|
|
频繁项集: [{'牛奶'}, {'面包'}, {'黄油'}, {'啤酒'}, {'鸡蛋'}, {'牛奶', '面包'}, {'牛奶', '黄油'}, {'面包', '黄油'}, {'啤酒', '黄油'}, {'面包', '啤酒'}]
|
|
|
关联规则: [(('牛奶',), ('面包',), 0.6666666666666666), (('面包',), ('牛奶',), 0.6666666666666666), ...]
|
|
|
\`\`\`
|
|
|
通过这个实战应用,我们不仅学习了如何在Python中实现Apriori算法,还了解了它在购物篮分析中的具体应用。这为进一步的研究和实际应用提供了有用的指导。`);
|
|
|
const getList = () => {
|
|
|
API.selectionMetrics({ userId: JSON.parse(getUserInfo()).userId }).then((res) => {
|
|
|
res.data.forEach((element) => {
|
|
|
options.value.push({
|
|
|
value: element,
|
|
|
label: element,
|
|
|
});
|
|
|
});
|
|
|
});
|
|
|
};
|
|
|
const showChart = ref(false);
|
|
|
const fileList = ref([]);
|
|
|
const handleChange = (info) => {
|
|
|
fileList.value.push(info);
|
|
|
};
|
|
|
const flag = ref(false);
|
|
|
|
|
|
onMounted(() => {
|
|
|
getList();
|
|
|
});
|
|
|
const optionData = () => {
|
|
|
API.viewingMetrics({ userId: JSON.parse(getUserInfo()).userId, tableName: input.value, algorithmName: "关联规则挖掘" }).then((res) => {
|
|
|
tableData.value = [];
|
|
|
input3.value = "";
|
|
|
res.data.forEach((element) => {
|
|
|
tableData.value.push({
|
|
|
text: element,
|
|
|
});
|
|
|
});
|
|
|
});
|
|
|
};
|
|
|
const selectedRows = ref([]);
|
|
|
const handleSelectionChange = (selection) => {
|
|
|
selectedRows.value = selection;
|
|
|
};
|
|
|
const tableData2 = ref([]);
|
|
|
const tableData3 = ref([]);
|
|
|
const resTable2 = ref([]);
|
|
|
const taskZB = () => {
|
|
|
flag.value = true;
|
|
|
if (selectedRows.value.length === 0) {
|
|
|
return proxy.$modal.msgWarning("请选择指标!");
|
|
|
}
|
|
|
const sendData = {
|
|
|
tableName: input.value,
|
|
|
userId: JSON.parse(getUserInfo()).userId,
|
|
|
fieldList: selectedRows.value.map((item) => item.text),
|
|
|
};
|
|
|
API.analysisDataDisplay(sendData).then((res) => {
|
|
|
tableLabel.length = 0;
|
|
|
for (const key in res.data[0]) {
|
|
|
tableLabel.push({
|
|
|
label: key,
|
|
|
prop: key,
|
|
|
});
|
|
|
}
|
|
|
tableData2.value = res.data;
|
|
|
flag.value = true;
|
|
|
});
|
|
|
};
|
|
|
const formInline = reactive({
|
|
|
user: "",
|
|
|
region: "",
|
|
|
});
|
|
|
const input = ref();
|
|
|
const options = ref([]);
|
|
|
const input2 = ref();
|
|
|
const options2 = ref([
|
|
|
{
|
|
|
value: "数据区重",
|
|
|
label: "数据去重",
|
|
|
},
|
|
|
]);
|
|
|
const input3 = ref();
|
|
|
const options3 = ref([
|
|
|
{
|
|
|
value: "缺失值处理--剔除数据",
|
|
|
label: "缺失值处理--剔除数据",
|
|
|
},
|
|
|
{
|
|
|
value: "缺失值处理--均值替换",
|
|
|
label: "缺失值处理--均值替换",
|
|
|
},
|
|
|
]);
|
|
|
const input4 = ref();
|
|
|
const options4 = ref([
|
|
|
{
|
|
|
value: "Apriori关联算法",
|
|
|
label: "Apriori关联算法",
|
|
|
},
|
|
|
]);
|
|
|
const input5 = ref();
|
|
|
const input6 = ref();
|
|
|
const taskSubmit = () => {
|
|
|
dialogVisible.value = true;
|
|
|
};
|
|
|
const tableData = ref([]);
|
|
|
const headerCellStyle = () => {
|
|
|
return {
|
|
|
backgroundColor: "#1882DE !important", // 设置表头背景颜色
|
|
|
color: "#ffffff !important",
|
|
|
};
|
|
|
};
|
|
|
const optionData2 = () => {
|
|
|
if (tableData2.value.length === 0) {
|
|
|
input2.value = "";
|
|
|
input3.value = "";
|
|
|
proxy.$modal.msgWarning("请先选择指标!");
|
|
|
return;
|
|
|
}
|
|
|
if (input2.value && input3.value) {
|
|
|
const sendData = ref({
|
|
|
mapList: tableData2.value,
|
|
|
method: input3.value,
|
|
|
userId: JSON.parse(getUserInfo()).userId,
|
|
|
});
|
|
|
API.dataPreprocessing(sendData.value).then((res) => {
|
|
|
resTable2.value = res.data;
|
|
|
tableData2.value = [];
|
|
|
tableData2.value = res.data;
|
|
|
proxy.$modal.msgSuccess("预处理成功!");
|
|
|
});
|
|
|
}
|
|
|
};
|
|
|
|
|
|
//生产表格
|
|
|
const exportTableRef = ref(null);
|
|
|
const uplodFlag = ref(false);
|
|
|
const computation = () => {
|
|
|
if (resTable2.value.length == 0 || input2.value == "" || input3.value == "") {
|
|
|
proxy.$modal.msgWarning("请先计算/对数据进行预处理!");
|
|
|
return;
|
|
|
}
|
|
|
if (input5.value && input6.value && input4.value) {
|
|
|
loading1.value = true;
|
|
|
const sendData = {
|
|
|
confidence: parseFloat(input5.value) / 100,
|
|
|
support: parseFloat(input6.value) / 100,
|
|
|
userId: JSON.parse(getUserInfo()).userId,
|
|
|
deduplicatedDataList: resTable2.value,
|
|
|
};
|
|
|
API.associationRuleMining(sendData)
|
|
|
.then((res) => {
|
|
|
uplodFlag.value = true;
|
|
|
tableData3.value = [];
|
|
|
tableLabel2.length = 0;
|
|
|
for (const key in res.data[0]) {
|
|
|
tableLabel2.push({
|
|
|
label: key,
|
|
|
prop: key,
|
|
|
});
|
|
|
}
|
|
|
tableData3.value = res.data;
|
|
|
//一秒后执行
|
|
|
setTimeout(() => {
|
|
|
loading1.value = false;
|
|
|
}, 500);
|
|
|
nextTick(() => {
|
|
|
setTimeout(() => {
|
|
|
const scrollContainer = scrollbar.value?.$el.querySelector(".el-scrollbar__wrap");
|
|
|
if (scrollContainer) {
|
|
|
scrollContainer.scrollTo({
|
|
|
top: scrollContainer.scrollHeight,
|
|
|
behavior: "smooth", // 平滑滚动
|
|
|
});
|
|
|
}
|
|
|
}, 500);
|
|
|
});
|
|
|
})
|
|
|
.catch(() => {
|
|
|
loading1.value = false;
|
|
|
});
|
|
|
} else {
|
|
|
proxy.$modal.msgWarning("请模型参数进行设置!");
|
|
|
}
|
|
|
};
|
|
|
const upload = () => {
|
|
|
const tableDom = exportTableRef.value?.$el;
|
|
|
if (!tableDom) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
const wb = XLSX.utils.table_to_book(tableDom);
|
|
|
XLSX.writeFile(wb, "关联规则挖掘.xlsx");
|
|
|
};
|
|
|
const startOver = () => {
|
|
|
input.value = "";
|
|
|
tableData.value = [];
|
|
|
tableData2.value = [];
|
|
|
tableData3.value = [];
|
|
|
input2.value = "";
|
|
|
input3.value = "";
|
|
|
input4.value = "";
|
|
|
input5.value = "";
|
|
|
input6.value = "";
|
|
|
tableLabel.length = 0;
|
|
|
tableLabel2.length = 0;
|
|
|
uplodFlag.value = false;
|
|
|
};
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
.main-top {
|
|
|
margin: 20px 20px 0;
|
|
|
margin-top: 10px;
|
|
|
height: 85px;
|
|
|
background: #001d40;
|
|
|
border: 1px solid #0452c6;
|
|
|
padding: 5px 20px;
|
|
|
}
|
|
|
.app-main {
|
|
|
// background-color: #f5f5f5;
|
|
|
// min-height: 965px;
|
|
|
margin: 0px 20px 0;
|
|
|
height: 100%;
|
|
|
display: flex;
|
|
|
// overflow: auto;
|
|
|
.main-left {
|
|
|
//水平居中
|
|
|
flex-direction: column;
|
|
|
// min-height: 965px;
|
|
|
display: flex;
|
|
|
width: 205px;
|
|
|
height: 100%;
|
|
|
background: #041c49;
|
|
|
// padding: 0px 10px;
|
|
|
.left-top {
|
|
|
padding: 10px;
|
|
|
span {
|
|
|
font-weight: bold;
|
|
|
font-size: 18px;
|
|
|
color: #3596eb;
|
|
|
}
|
|
|
}
|
|
|
.metrics-table {
|
|
|
.el-button {
|
|
|
width: 149px;
|
|
|
height: 48px;
|
|
|
background: url("../../../assets/images/确定.png");
|
|
|
color: #ffffff;
|
|
|
border-color: #ffffff00;
|
|
|
background-size: 100% 100%;
|
|
|
margin: 15px;
|
|
|
}
|
|
|
.el-input {
|
|
|
--el-input-text-color: #ffffff;
|
|
|
--el-input-bg-color: #002651;
|
|
|
--el-input-border-color: #67b3d6;
|
|
|
}
|
|
|
}
|
|
|
.startOver {
|
|
|
width: 150px;
|
|
|
height: 40px;
|
|
|
background: #00f4ff;
|
|
|
margin: auto;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
:deep(.el-table) {
|
|
|
--el-table-row-hover-bg-color: #002651 !important;
|
|
|
--el-table-border-color: #7ac1ff;
|
|
|
.el-table__row {
|
|
|
background-color: #002652 !important;
|
|
|
color: #e6e6e6;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
.main-right {
|
|
|
width: 1639px;
|
|
|
// height: 100%;
|
|
|
// padding: 20px;
|
|
|
border: 1px solid #0452c6;
|
|
|
:deep(.el-table__header) {
|
|
|
.el-table__cell {
|
|
|
background: linear-gradient(0deg, #5304be 0%, #9126fe 100%) !important;
|
|
|
}
|
|
|
}
|
|
|
:deep(.el-table) {
|
|
|
--el-table-row-hover-bg-color: #002651 !important;
|
|
|
--el-table-border-color: #002651;
|
|
|
--el-table-bg-color: #ffffff00;
|
|
|
.el-table__row {
|
|
|
background-color: #002652 !important;
|
|
|
color: #e6e6e6;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
.metrics {
|
|
|
:deep(.el-input) {
|
|
|
.el-input__wrapper {
|
|
|
background-color: #ffffff00;
|
|
|
background-image: url("../../../assets/images/下拉框.png");
|
|
|
background-size: 100% 100%;
|
|
|
}
|
|
|
--el-input-text-color: #ffffff;
|
|
|
--el-input-border-color: #ffffff00;
|
|
|
--el-input-hover-border-color: #ffffff00;
|
|
|
--el-input-hover-border: #ffffff00;
|
|
|
--el-select-border-color-hover: #ffffff00;
|
|
|
--el-select-input-focus-border-color: #ffffff00;
|
|
|
--el-input-placeholder-color: #ffffff;
|
|
|
.el-input__inner {
|
|
|
color: #ffffff;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
.analysisResults {
|
|
|
.el-button {
|
|
|
width: 89px;
|
|
|
height: 31px;
|
|
|
background: url("../../../assets/images/下载.png");
|
|
|
color: black;
|
|
|
border-color: #ffffff00;
|
|
|
// background-size: 100% 100%;
|
|
|
margin: 15px 0px 5px;
|
|
|
}
|
|
|
}
|
|
|
:deep(.el-form-item__label) {
|
|
|
color: #ffffff;
|
|
|
}
|
|
|
.from-item {
|
|
|
padding: 20px;
|
|
|
.el-input {
|
|
|
--el-input-text-color: #ffffff;
|
|
|
--el-input-bg-color: #002651;
|
|
|
--el-input-border-color: #67b3d6;
|
|
|
}
|
|
|
}
|
|
|
.dialog-footer {
|
|
|
margin-bottom: 20px;
|
|
|
}
|
|
|
:deep(.el-table__expand-icon) {
|
|
|
color: #9126fe;
|
|
|
.el-icon {
|
|
|
font-size: 16px;
|
|
|
}
|
|
|
}
|
|
|
:deep(.el-checkbox) {
|
|
|
color: #ffffff;
|
|
|
}
|
|
|
</style>
|