|
|
|
|
@ -1,7 +1,7 @@
|
|
|
|
|
<template>
|
|
|
|
|
<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">使用“用户商品评论数据”,进行各类文本挖掘任务,分析评论情感情绪,最后提交实训任务。</p>
|
|
|
|
|
<p style="font-weight: 400; font-size: 15px; color: #e2e7ee !important">使用“用户商品评论数据”,进行各类文本挖掘任务,分析评论情感情绪,最后提交实训任务。</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="main-but">
|
|
|
|
|
<el-button @click="knowledgeImport">
|
|
|
|
|
@ -69,7 +69,9 @@
|
|
|
|
|
<el-scrollbar height="550px" style="padding: 20px">
|
|
|
|
|
<div>
|
|
|
|
|
<span style="font-weight: bold; font-size: 18px; color: #3596eb">分析数据:</span>
|
|
|
|
|
|
|
|
|
|
<div class="text-type" v-show="preProcessText.text3 == '评论观点抽取'">
|
|
|
|
|
<el-button :class="s_commentType == text.id ? 'btnActive' : ''" v-for="text in textType" :key="text" type="primary" plain @click="commentType(text)">{{ text.name }}</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="analysis">
|
|
|
|
|
<el-input v-model="g_analyzeTheNumberOfDataItems" :rows="2" type="textarea" placeholder="" />
|
|
|
|
|
</div>
|
|
|
|
|
@ -120,7 +122,7 @@
|
|
|
|
|
<div class="emotion_analysis_title">{{ g_emotionAnalysis == 0 ? "情感偏负向" : g_emotionAnalysis == 1 ? "情感偏中性" : "情感偏正向" }}</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div ref="captureElement" class="comment-opinion" v-if="preProcessText.text3 == '评论观点抽取'">
|
|
|
|
|
<!-- <div ref="captureElement" class="comment-opinion" v-if="preProcessText.text3 == '评论观点抽取'">
|
|
|
|
|
<div class="result" v-for="(item, sentiment) in aCommentOpinion" :key="item.abstract">
|
|
|
|
|
<div class="result-pos" :class="sentiment == 0 ? 'result-neg' : sentiment == 1 ? 'result-neutral' : 'result-img'"></div>
|
|
|
|
|
<div class="result-title">{{ sentiment == 0 ? "负向评价" : sentiment == 1 ? "中性评价" : "正向评价" }}:</div>
|
|
|
|
|
@ -133,12 +135,22 @@
|
|
|
|
|
<div class="result-bar"></div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div> -->
|
|
|
|
|
<div ref="captureElement" class="comment-opinion" v-if="preProcessText.text3 == '评论观点抽取'">
|
|
|
|
|
<div class="result" v-for="(item, sentiment) in aCommentOpinion" :key="item.abstract">
|
|
|
|
|
<div class="result-pos" :class="sentiment == 0 ? 'result-neg' : sentiment == 1 ? 'result-neutral' : 'result-img'"></div>
|
|
|
|
|
<div class="result-title">{{ sentiment == 0 ? "负向评价" : sentiment == 1 ? "中性评价" : "正向评价" }}:</div>
|
|
|
|
|
<div class="result-view" v-for="items in item" :key="items">
|
|
|
|
|
{{ items.prop + items.adj }}
|
|
|
|
|
<div class="result-bar"></div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</el-scrollbar>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<el-dialog v-model="dialogVisible" title="实训任务提交" width="700" custom-class="dialogClass" :show-close="false">
|
|
|
|
|
<el-dialog v-model="dialogVisible" title="实训任务提交" width="700" custom-class="dialogClass" :show-close="false" @close="closeDialog">
|
|
|
|
|
<template #header="{ close, titleId, titleClass }">
|
|
|
|
|
<div class="my-header">
|
|
|
|
|
<span :id="titleId" :class="titleClass">实训任务提交</span>
|
|
|
|
|
@ -503,13 +515,14 @@ const downloadStatus = ref(false);
|
|
|
|
|
//提交校验
|
|
|
|
|
const flat = ref(false);
|
|
|
|
|
const g_submitVerification = ref({
|
|
|
|
|
max: "13",
|
|
|
|
|
frequency: "3",
|
|
|
|
|
text1: "质量",
|
|
|
|
|
text2: "包装好",
|
|
|
|
|
max: "安装",
|
|
|
|
|
frequency: "6",
|
|
|
|
|
text1: "",
|
|
|
|
|
text2: "",
|
|
|
|
|
emotional: "负向",
|
|
|
|
|
prominent: "的",
|
|
|
|
|
prominent: "安装",
|
|
|
|
|
});
|
|
|
|
|
const s_commentType = ref("");
|
|
|
|
|
// 预处理
|
|
|
|
|
const preProcess = (tetx) => {
|
|
|
|
|
if (g_indicatorData.value.length == 0) {
|
|
|
|
|
@ -598,9 +611,15 @@ const submitTask = () => {
|
|
|
|
|
return;
|
|
|
|
|
} else {
|
|
|
|
|
if (formInline.value[key] != g_submitVerification.value[key]) {
|
|
|
|
|
const label = tableLabel.find((item) => item.prop == key);
|
|
|
|
|
proxy.$modal.msgWarning(`${label.label}错误`);
|
|
|
|
|
flat.value = true;
|
|
|
|
|
// 判断text1或text2只要输入包装好,好评少就行顺序不重要
|
|
|
|
|
if (key == "text1" || key == "text2") {
|
|
|
|
|
const validTexts = ["text1", "text2"];
|
|
|
|
|
if (validTexts.includes(key) && !["包装好", "好评少"].includes(formInline.value[key])) {
|
|
|
|
|
flat.value = true;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
flat.value = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -648,6 +667,8 @@ const restart = () => {
|
|
|
|
|
nOriginalWordFrequencyNum.value = 0;
|
|
|
|
|
aWordFrequency.value = [];
|
|
|
|
|
nOriginalWordFrequency.value = [];
|
|
|
|
|
s_commentType.value = "";
|
|
|
|
|
aCommentOpinion.value = "";
|
|
|
|
|
proxy.$modal.msgSuccess("重新开始!");
|
|
|
|
|
multipleTableRef.value.clearSelection();
|
|
|
|
|
};
|
|
|
|
|
@ -709,7 +730,9 @@ const sentimentAnalysis = () => {
|
|
|
|
|
if (preProcessText.value.text2 == "") return proxy.$modal.msgWarning("请先对数据进行预处理!");
|
|
|
|
|
}
|
|
|
|
|
if (preProcessText.value.text3 == "") return proxy.$modal.msgWarning("请先选择模型!");
|
|
|
|
|
|
|
|
|
|
if (preProcessText.value.text3 === "评论观点抽取" && s_commentType.value == "") {
|
|
|
|
|
return proxy.$modal.msgWarning("请先选择评论类型!");
|
|
|
|
|
}
|
|
|
|
|
if (g_analyzeTheNumberOfDataItems.value == "") return proxy.$modal.msgWarning("请先选择指标/手动输入进行情感分析!");
|
|
|
|
|
loading.value = true;
|
|
|
|
|
if (preProcessText.value.text3 === "情感倾向分析") {
|
|
|
|
|
@ -740,7 +763,7 @@ const sentimentAnalysis = () => {
|
|
|
|
|
.catch((err) => {
|
|
|
|
|
loading.value = false;
|
|
|
|
|
});
|
|
|
|
|
} else if (preProcessText.value.text3 !== "评论观点抽取") {
|
|
|
|
|
} else if (preProcessText.value.text3 !== "情感倾向分析") {
|
|
|
|
|
marketingAlgorithmApi
|
|
|
|
|
.getMarketingAlgorithmSentiment({ userId: n_dataTableQuery.value.userId, content: g_analyzeTheNumberOfDataItems.value, modelType: preProcessText.value.text3 == "词云生成" ? "词频分析" : preProcessText.value.text3 })
|
|
|
|
|
.then((res) => {
|
|
|
|
|
@ -751,33 +774,18 @@ const sentimentAnalysis = () => {
|
|
|
|
|
nOriginalWordFrequency.value = res.data;
|
|
|
|
|
aWordFrequency.value = res.data.slice(0, 5);
|
|
|
|
|
nOriginalWordFrequencyNum.value = res.data.length;
|
|
|
|
|
} else {
|
|
|
|
|
aCommentOpinion.value = JSON.parse(res.data).items.reduce((groups, item) => {
|
|
|
|
|
// 如果该 sentiment 的组不存在,则创建
|
|
|
|
|
if (!groups[item.sentiment]) {
|
|
|
|
|
groups[item.sentiment] = [];
|
|
|
|
|
}
|
|
|
|
|
// 将 item 加入到相应的组中
|
|
|
|
|
groups[item.sentiment].push(item);
|
|
|
|
|
return groups;
|
|
|
|
|
}, {});
|
|
|
|
|
}
|
|
|
|
|
downloadStatus.value = true;
|
|
|
|
|
g_submitVerification.value.n_maximumQuantity = nOriginalWordFrequency.value.reduce((longest, current) => {
|
|
|
|
|
return current.keyword.length > longest.keyword.length ? current.keyword : longest.keyword;
|
|
|
|
|
}, nOriginalWordFrequency.value[0]);
|
|
|
|
|
g_submitVerification.value.n_frequency = nOriginalWordFrequency.value.reduce((longest, current) => {
|
|
|
|
|
return item.frequency > max.frequency ? item.n_frequency : max.n_frequency;
|
|
|
|
|
}, nOriginalWordFrequency.value[0]);
|
|
|
|
|
console.log(g_submitVerification.value, "g_submitVerification.value.");
|
|
|
|
|
loading.value = false;
|
|
|
|
|
proxy.$modal.msgSuccess("分析成功");
|
|
|
|
|
})
|
|
|
|
|
.catch((err) => {
|
|
|
|
|
loading.value = false;
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
portraitModel
|
|
|
|
|
.getCommentPoint(JSON.stringify({ text: g_analyzeTheNumberOfDataItems.value }))
|
|
|
|
|
.then((res) => {
|
|
|
|
|
aCommentOpinion.value = res.singleAnalysisResult.reduce((groups, item) => {
|
|
|
|
|
if (!groups[item.sentiment == "正向" ? 2 : 0]) {
|
|
|
|
|
groups[item.sentiment == "正向" ? 2 : 0] = [];
|
|
|
|
|
}
|
|
|
|
|
groups[item.sentiment == "正向" ? 2 : 0].push(item);
|
|
|
|
|
return groups;
|
|
|
|
|
}, {});
|
|
|
|
|
downloadStatus.value = true;
|
|
|
|
|
loading.value = false;
|
|
|
|
|
proxy.$modal.msgSuccess("分析成功");
|
|
|
|
|
})
|
|
|
|
|
@ -785,6 +793,25 @@ const sentimentAnalysis = () => {
|
|
|
|
|
loading.value = false;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
// else {
|
|
|
|
|
// portraitModel
|
|
|
|
|
// .getCommentPoint(JSON.stringify({ text: g_analyzeTheNumberOfDataItems.value }))
|
|
|
|
|
// .then((res) => {
|
|
|
|
|
// aCommentOpinion.value = res.singleAnalysisResult.reduce((groups, item) => {
|
|
|
|
|
// if (!groups[item.sentiment == "正向" ? 2 : 0]) {
|
|
|
|
|
// groups[item.sentiment == "正向" ? 2 : 0] = [];
|
|
|
|
|
// }
|
|
|
|
|
// groups[item.sentiment == "正向" ? 2 : 0].push(item);
|
|
|
|
|
// return groups;
|
|
|
|
|
// }, {});
|
|
|
|
|
// downloadStatus.value = true;
|
|
|
|
|
// loading.value = false;
|
|
|
|
|
// proxy.$modal.msgSuccess("分析成功");
|
|
|
|
|
// })
|
|
|
|
|
// .catch((err) => {
|
|
|
|
|
// loading.value = false;
|
|
|
|
|
// });
|
|
|
|
|
// }
|
|
|
|
|
};
|
|
|
|
|
// 清空
|
|
|
|
|
const clear = () => {
|
|
|
|
|
@ -793,6 +820,8 @@ const clear = () => {
|
|
|
|
|
aWordFrequency.value = [];
|
|
|
|
|
loading.value = false;
|
|
|
|
|
downloadStatus.value = false;
|
|
|
|
|
aCommentOpinion.value = [];
|
|
|
|
|
s_commentType.value = "";
|
|
|
|
|
proxy.$modal.msgSuccess("清空成功");
|
|
|
|
|
};
|
|
|
|
|
const initChart = () => {
|
|
|
|
|
@ -809,6 +838,8 @@ const initChart = () => {
|
|
|
|
|
x: "center",
|
|
|
|
|
textStyle: {
|
|
|
|
|
fontSize: 23,
|
|
|
|
|
color: "#000000",
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
backgroundColor: "#ffffff",
|
|
|
|
|
@ -826,24 +857,24 @@ const initChart = () => {
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
series: [
|
|
|
|
|
{
|
|
|
|
|
name: "词云分析",
|
|
|
|
|
type: "wordCloud",
|
|
|
|
|
// //size: ['9%', '99%'],
|
|
|
|
|
sizeRange: [6, 66],
|
|
|
|
|
// //textRotation: [0, 45, 90, -45],
|
|
|
|
|
rotationRange: [-45, 90],
|
|
|
|
|
// //shape: 'circle',
|
|
|
|
|
// gridSize: 5,
|
|
|
|
|
// sizeRange: [12, 32],
|
|
|
|
|
width: "90%",
|
|
|
|
|
height: "86%",
|
|
|
|
|
textPadding: 0,
|
|
|
|
|
size: ["9%", "99%"],
|
|
|
|
|
sizeRange: [33, 80], // 调整大小范围
|
|
|
|
|
textRotation: [0, 45, 90, -45],
|
|
|
|
|
rotationRange: [-90, 90], // 增大旋转角度范围
|
|
|
|
|
shape: "circle",
|
|
|
|
|
gridSize: 5, // 减小间距
|
|
|
|
|
sizeRange: [33, 80], // 调整大小范围
|
|
|
|
|
width: "100%", // 铺满容器宽度
|
|
|
|
|
height: "100%", // 铺满容器高度
|
|
|
|
|
textPadding: 10, // 减少内边距
|
|
|
|
|
autoSize: {
|
|
|
|
|
enable: true,
|
|
|
|
|
minSize: 16,
|
|
|
|
|
minSize: 33, // 设置最小尺寸
|
|
|
|
|
maxSize: 80, // 设置最大尺寸
|
|
|
|
|
},
|
|
|
|
|
textStyle: {
|
|
|
|
|
color: function () {
|
|
|
|
|
@ -859,7 +890,6 @@ const initChart = () => {
|
|
|
|
|
],
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const wordFrequencyNext = () => {
|
|
|
|
|
if (mWordFrequency.value.frequency !== "" || mWordFrequency.value.namenum !== "") {
|
|
|
|
|
wordFrequencySearch();
|
|
|
|
|
@ -892,7 +922,18 @@ const switchingModels = () => {
|
|
|
|
|
mWordFrequency.value.size = 5;
|
|
|
|
|
mWordFrequency.value.frequency = "";
|
|
|
|
|
mWordFrequency.value.namenum = "";
|
|
|
|
|
s_commentType.value = "";
|
|
|
|
|
};
|
|
|
|
|
const commentType = (text) => {
|
|
|
|
|
s_commentType.value = text.id;
|
|
|
|
|
};
|
|
|
|
|
const closeDialog=()=>{
|
|
|
|
|
dialogVisible.value = false;
|
|
|
|
|
flat.value = false
|
|
|
|
|
for (let key in formInline.value) {
|
|
|
|
|
formInline.value[key] = "";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
|