dev-QQq
方佳 博 2 years ago
parent 8b3967c927
commit 2a84852127

@ -60,7 +60,7 @@ export function clusterAnalysisPlot(data) {
//关联规则挖掘 //关联规则挖掘
export function associationRuleMining(data) { export function associationRuleMining(data) {
return request({ return request({
url: '/api/model/apriori', url: '/api/python/associationRules',
method: 'post', method: 'post',
data:data, data:data,
}) })

@ -153,4 +153,4 @@ export function clusterAnalysis(data) {
method: "post", method: "post",
data: data, data: data,
}); });
} }

@ -50,6 +50,9 @@
<div class="left-top" style="margin-top: 50px"> <div class="left-top" style="margin-top: 50px">
<span>模型参数设置</span> <span>模型参数设置</span>
</div> </div>
<div class="metrics-table">
<el-button @click="codeSetting"></el-button>
</div>
<div class="metrics-table" style="margin-top: 10px"> <div class="metrics-table" style="margin-top: 10px">
<span style="font-weight: 400; font-size: 12px; color: #ffffff">聚类方法</span> <span style="font-weight: 400; font-size: 12px; color: #ffffff">聚类方法</span>
<div class="metrics" style="margin-top: 10px"> <div class="metrics" style="margin-top: 10px">
@ -322,9 +325,17 @@
</div> </div>
</template> </template>
</pop-model> </pop-model>
<pop-model :showModel="runResultShow2" title="设置代码" @closePop="closeCode">
<template v-slot:content>
<div>
<codemirror :code="code"></codemirror>
</div>
</template>
</pop-model>
</template> </template>
<script setup> <script setup>
import codemirror from "@/components/codemirror/index.vue"
import useAlgorithmStore from "@/store/modules/algorithm.js"; import useAlgorithmStore from "@/store/modules/algorithm.js";
const algorithmStore = useAlgorithmStore(); const algorithmStore = useAlgorithmStore();
import * as portraitModel from "@/api/portraitModel"; import * as portraitModel from "@/api/portraitModel";
@ -344,6 +355,7 @@ const formData = reactive({
value4: "", value4: "",
value5: "", value5: "",
}); });
const code=ref('')
const scrollbar=ref(null) const scrollbar=ref(null)
const loading1 =ref(false) const loading1 =ref(false)
const task = () => { const task = () => {
@ -377,78 +389,22 @@ const task = () => {
proxy.$modal.msgSuccess("提交成功"); proxy.$modal.msgSuccess("提交成功");
}); });
}; };
const runResultShow2 = ref(false)
const closeCode=()=>{
runResultShow2.value = false
const inputs = document.querySelectorAll('.codemirror pre code input')
const values = []
inputs.forEach(input => {
values.push(input.value)
})
input5.value=values[0]*100
input6.value=values[1]*100
input4.value='Apriori关联算法'
}
const dialogVisible = ref(false); const dialogVisible = ref(false);
const runResultShow = ref(false); const runResultShow = ref(false);
const tableLabel = reactive([{ prop: "date", label: "" }]); const tableLabel = reactive([{ prop: "date", label: "" }]);
const tableLabel2 = 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 = () => { const getList = () => {
API.selectionMetrics({ userId: JSON.parse(getUserInfo()).userId }).then((res) => { API.selectionMetrics({ userId: JSON.parse(getUserInfo()).userId }).then((res) => {
res.data.forEach((element) => { res.data.forEach((element) => {
@ -548,6 +504,13 @@ const taskSubmit = () => {
dialogVisible.value = true; dialogVisible.value = true;
}; };
const tableData = ref([]); const tableData = ref([]);
const codeSetting=()=>{
if(input.value==="购物车数据表"){
runResultShow2.value=true
}else{
proxy.$modal.msgWarning("请选择购物车数据表!")
}
}
const headerCellStyle = () => { const headerCellStyle = () => {
return { return {
backgroundColor: "#1882DE !important", // backgroundColor: "#1882DE !important", //
@ -572,7 +535,66 @@ const optionData2 = () => {
tableData2.value = []; tableData2.value = [];
tableData2.value = res.data; tableData2.value = res.data;
proxy.$modal.msgSuccess("预处理成功!"); proxy.$modal.msgSuccess("预处理成功!");
}); }).then(()=>{
code.value=`
# -*- coding: utf-8 -*-
import json
from itertools import chain, combinations
def powerset(s):
return chain.from_iterable(combinations(s, r) for r in range(1, len(s) + 1))
def calculate_support(itemset, transactions):
return sum(1 for transaction in transactions if itemset.issubset(transaction)) / len(transactions)
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:
rule = {
"correlation": list(subset),
"associated": list(diff),
"confidenceLevel": round(confidence, 2),
"rule": f"[{', '.join(subset)}]==>[{', '.join(diff)}]==>{round(confidence, 2)}"
}
association_rules.append(rule)
prev_frequent_itemsets = new_frequent_itemsets
result = {
# "frequentItemsets": [list(itemset) for itemset in frequent_itemsets],
"associationRules": association_rules
}
print(json.dumps(result, ensure_ascii=False))
transactions = [
${resTable2.value.map(item => "{" + item.consumer_goods.split(',').map(good => "'" + good + "'").join(',') + "}").join(',')}
]
min_support = ___
min_confidence = ___
apriori(transactions, min_support, min_confidence)
`
})
} }
}; };
@ -585,25 +607,31 @@ const computation = () => {
return; return;
} }
if (input5.value && input6.value && input4.value) { if (input5.value && input6.value && input4.value) {
const sendData = { const sendData =ref({
confidence: parseFloat(input5.value) / 100, minConfidence: parseFloat(input6.value) / 100,
support: parseFloat(input6.value) / 100, minSupport: parseFloat(input5.value) / 100,
userId: JSON.parse(getUserInfo()).userId, type: input.value,
deduplicatedDataList: resTable2.value, data: Object.keys(resTable2.value[0]).reduce((acc, key) => {
}; acc[key] = resTable2.value.map(item => item[key]);
API.associationRuleMining(sendData) return acc;
}, {}),
})
if(input.value==="购物车数据表"){
sendData.value.data = {consumer_goods:resTable2.value.map(item => item.consumer_goods.split(','))}
}
API.associationRuleMining(sendData.value)
.then((res) => { .then((res) => {
loading1.value = true; loading1.value = true;
uplodFlag.value = true; uplodFlag.value = true;
tableData3.value = []; tableData3.value = [];
tableLabel2.length = 0; tableLabel2.length = 0;
for (const key in res.data[0]) { for (const key in res.data.associationRules[0]) {
tableLabel2.push({ tableLabel2.push({
label: key, label: key,
prop: key, prop: key,
}); });
} }
tableData3.value = res.data; tableData3.value = res.data.associationRules;
// //
setTimeout(() => { setTimeout(() => {
loading1.value = false; loading1.value = false;

@ -555,7 +555,6 @@ const headerCellStyle = () => {
}; };
const codeSetting=()=>{ const codeSetting=()=>{
runResultShow2.value=true runResultShow2.value=true
console.log(runResultShow2.value);
} }
const optionData2 = () => { const optionData2 = () => {
if (tableData2.value.length === 0) { if (tableData2.value.length === 0) {
@ -581,9 +580,13 @@ const optionData2 = () => {
loading2.value = false; loading2.value = false;
}, 500); }, 500);
}).then(()=>{ }).then(()=>{
age.value=resTable2.value.map(item=>item.age).join(',') const fields = Object.keys(resTable2.value[0])
income.value=resTable2.value.map(item=>item.annual_income).join(',') const data = {}
code.value=` fields.forEach(field => {
const values = resTable2.value.map(item => item[field]).join(',')
data[field] = values
})
code.value=`
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import numpy as np import numpy as np
import pandas as pd import pandas as pd
@ -593,8 +596,7 @@ import json
# 模拟输入数据可以根据实际输入动态更改 # 模拟输入数据可以根据实际输入动态更改
data = { data = {
'age': [${age.value}], ${Object.entries(data).map(([key, value]) => `'${key}': [${value}]`).join(',\n ')}
'income': [${income.value}]
} }
# 将字典转换为 DataFrame # 将字典转换为 DataFrame
@ -744,10 +746,10 @@ const clusterAnalysisCalculation = () => {
maxIterations: input6.value, maxIterations: input6.value,
clusteringFrequency: input5.value, clusteringFrequency: input5.value,
// userId: JSON.parse(getUserInfo()).userId, // userId: JSON.parse(getUserInfo()).userId,
data: { data:Object.keys(resTable2.value[0]).reduce((acc, key) => {
age: resTable2.value.map(item => item.age), acc[key] = resTable2.value.map(item => item[key]);
income: resTable2.value.map(item => item.annual_income) return acc;
}, }, {}),
}; };
API.clusterAnalysis2(sendData2).then((res) => { API.clusterAnalysis2(sendData2).then((res) => {
myChart.setOption({ myChart.setOption({

@ -46,8 +46,8 @@ const activeIndex = (index) => {
const map = { const map = {
用户数据库: 1, 用户数据库: 1,
描述性统计: 2, 描述性统计: 2,
关联规则挖掘: 3, 聚类分析: 3,
聚类分析: 4, 关联规则挖掘: 4,
回归分析: 5, 回归分析: 5,
情感分析: 6, 情感分析: 6,
}; };

Loading…
Cancel
Save