|
|
|
@ -1,12 +1,18 @@
|
|
|
|
<template>
|
|
|
|
<template>
|
|
|
|
<el-scrollbar ref="scrollbar" height="800px">
|
|
|
|
<el-scrollbar ref="scrollbar" height="800px">
|
|
|
|
<div class="main-top">
|
|
|
|
<div class="main-top">
|
|
|
|
<span style="font-weight: bold;font-size: 18px;color: #3596EB;">任务描述</span>
|
|
|
|
<span style="font-weight: bold; font-size: 18px; color: #3596eb">任务描述</span>
|
|
|
|
<p style="font-weight: 400;font-size: 12px;color: #E6E6E6;">(给出任务清单参考,做哪些数据的统计分析)Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. Proin gravida dolor sit amet lacus accumsan et viverra justo commodo. Proin sodales pulvinar sic tempor. Sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam fermentum, nulla luctus pharetra vulputate, felis tellus mollis orci, sed rhoncus pronin sapien nunc accuan eget.</p>
|
|
|
|
<p style="font-weight: 400; font-size: 12px; color: #e6e6e6">(给出任务清单参考,做哪些数据的统计分析)Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. Proin gravida dolor sit amet lacus accumsan et viverra justo commodo. Proin sodales pulvinar sic tempor. Sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam fermentum, nulla luctus pharetra vulputate, felis tellus mollis orci, sed rhoncus pronin sapien nunc accuan eget.</p>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="main-but">
|
|
|
|
<div class="main-but">
|
|
|
|
<el-button @click="algorithmicKnowledge()"><img src="../../../assets/images/导入.png" alt="">算法知识导入</el-button>
|
|
|
|
<el-button @click="algorithmicKnowledge()">
|
|
|
|
<el-button @click="taskSubmit"><img src="../../../assets/images/提交.png" alt="">实训任务提交</el-button>
|
|
|
|
<img src="../../../assets/images/导入.png" alt="" />
|
|
|
|
|
|
|
|
算法知识导入
|
|
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
|
|
<el-button @click="taskSubmit">
|
|
|
|
|
|
|
|
<img src="../../../assets/images/提交.png" alt="" />
|
|
|
|
|
|
|
|
实训任务提交
|
|
|
|
|
|
|
|
</el-button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="app-main">
|
|
|
|
<div class="app-main">
|
|
|
|
<div class="main-left">
|
|
|
|
<div class="main-left">
|
|
|
|
@ -16,12 +22,7 @@
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="metrics">
|
|
|
|
<div class="metrics">
|
|
|
|
<el-select v-model="input" placeholder="请选择" style="width: 180px" @change="optionData">
|
|
|
|
<el-select v-model="input" placeholder="请选择" style="width: 180px" @change="optionData">
|
|
|
|
<el-option
|
|
|
|
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
|
v-for="item in options"
|
|
|
|
|
|
|
|
:key="item.value"
|
|
|
|
|
|
|
|
:label="item.label"
|
|
|
|
|
|
|
|
:value="item.value"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</el-select>
|
|
|
|
</el-select>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="metrics-table" style="margin-top: 10px">
|
|
|
|
<div class="metrics-table" style="margin-top: 10px">
|
|
|
|
@ -36,157 +37,230 @@
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="metrics">
|
|
|
|
<div class="metrics">
|
|
|
|
<el-select v-model="input2" @change="optionData2" placeholder="请选择" style="width: 180px">
|
|
|
|
<el-select v-model="input2" @change="optionData2" placeholder="请选择" style="width: 180px">
|
|
|
|
<el-option
|
|
|
|
<el-option v-for="item in options2" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
|
v-for="item in options2"
|
|
|
|
|
|
|
|
:key="item.value"
|
|
|
|
|
|
|
|
:label="item.label"
|
|
|
|
|
|
|
|
:value="item.value"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</el-select>
|
|
|
|
</el-select>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="metrics" style="margin-top: 15px">
|
|
|
|
<div class="metrics" style="margin-top: 15px">
|
|
|
|
<el-select v-model="input3" @change="optionData2" placeholder="请选择" style="width: 180px">
|
|
|
|
<el-select v-model="input3" @change="optionData2" placeholder="请选择" style="width: 180px">
|
|
|
|
<el-option
|
|
|
|
<el-option v-for="item in options3" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
|
v-for="item in options3"
|
|
|
|
|
|
|
|
:key="item.value"
|
|
|
|
|
|
|
|
:label="item.label"
|
|
|
|
|
|
|
|
:value="item.value"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</el-select>
|
|
|
|
</el-select>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<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" style="margin-top: 10px">
|
|
|
|
<div class="metrics-table" style="margin-top: 10px">
|
|
|
|
<span style="font-weight: 400;font-size: 12px;color: #FFFFFF;">
|
|
|
|
<span style="font-weight: 400; font-size: 12px; color: #ffffff">聚类方法:</span>
|
|
|
|
聚类方法:
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
<div class="metrics" style="margin-top: 10px">
|
|
|
|
<div class="metrics" style="margin-top: 10px">
|
|
|
|
<el-select v-model="input4" placeholder="请选择" style="width: 180px">
|
|
|
|
<el-select v-model="input4" placeholder="请选择" style="width: 180px">
|
|
|
|
<el-option
|
|
|
|
<el-option v-for="item in options4" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
|
v-for="item in options4"
|
|
|
|
|
|
|
|
:key="item.value"
|
|
|
|
|
|
|
|
:label="item.label"
|
|
|
|
|
|
|
|
:value="item.value"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</el-select>
|
|
|
|
</el-select>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div style="margin-top: 10px">
|
|
|
|
<div style="margin-top: 10px">
|
|
|
|
<span style="font-weight: 400;font-size: 12px;color: #FFFFFF;">
|
|
|
|
<span style="font-weight: 400; font-size: 12px; color: #ffffff">设置簇数K值:</span>
|
|
|
|
设置簇数K值:
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
<el-input v-model="input5" style="width: 180px; margin-top: 5px" />
|
|
|
|
<el-input v-model="input5" style="width: 180px; margin-top: 5px" />
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div style="margin-top: 10px">
|
|
|
|
<div style="margin-top: 10px">
|
|
|
|
<span style="font-weight: 400;font-size: 12px;color: #FFFFFF;">
|
|
|
|
<span style="font-weight: 400; font-size: 12px; color: #ffffff">最大迭代次数:</span>
|
|
|
|
最大迭代次数:
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
<el-input v-model="input6" style="width: 180px; margin-top: 5px" />
|
|
|
|
<el-input v-model="input6" style="width: 180px; margin-top: 5px" />
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<el-button @click="computation">计算</el-button>
|
|
|
|
<el-button @click="computation">计算</el-button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div style="margin-top: auto;">
|
|
|
|
<div style="margin-top: auto">
|
|
|
|
<div class="startOver" @click="startOver()">
|
|
|
|
<div class="startOver" @click="startOver()">
|
|
|
|
<img src="../../../assets/images/重新开始.png" alt="">
|
|
|
|
<img src="../../../assets/images/重新开始.png" alt="" />
|
|
|
|
<span>重新开始</span>
|
|
|
|
<span>重新开始</span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="main-right">
|
|
|
|
<div class="main-right">
|
|
|
|
<div>
|
|
|
|
<div>
|
|
|
|
<span style="font-weight: bold;font-size: 18px;color: #3596EB;">分析数据:</span>
|
|
|
|
<span style="font-weight: bold; font-size: 18px; color: #3596eb">分析数据:</span>
|
|
|
|
<el-table ref="exportTableRef" :data="tableData2" style="width: 94%; margin-top: 10px" :header-cell-style="headerCellStyle" height="350">
|
|
|
|
<el-table ref="exportTableRef" :data="tableData2" style="width: 94%; 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-column v-for="column in tableLabel" :key="column.prop" :prop="column.prop" :label="column.label" align="center" />
|
|
|
|
</el-table>
|
|
|
|
</el-table>
|
|
|
|
<!-- <el-pagination style="margin-top:10px" background layout="prev, pager, next" :total="1000" /> -->
|
|
|
|
<!-- <el-pagination style="margin-top:10px" background layout="prev, pager, next" :total="1000" /> -->
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="analysisResults" style="margin-top: 20px">
|
|
|
|
<div class="analysisResults" style="margin-top: 20px">
|
|
|
|
<span style="font-weight: bold;font-size: 18px;color: #3596EB;display: block;">分析结果:</span>
|
|
|
|
<span style="font-weight: bold; font-size: 18px; color: #3596eb; display: block">分析结果:</span>
|
|
|
|
<el-button @click="upLoad" v-if="showChart">下载</el-button>
|
|
|
|
<el-button @click="upLoad" v-if="showChart">下载</el-button>
|
|
|
|
<el-table :data="tableData3" row-key="TSuid" style="width: 94%; margin-top: 10px" :header-cell-style="headerCellStyle" height="350">
|
|
|
|
<el-table :data="tableData3" row-key="TSuid" style="width: 94%; 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-column v-for="column in tableLabel" :key="column.prop" :prop="column.prop" :label="column.label" align="center" />
|
|
|
|
</el-table>
|
|
|
|
</el-table>
|
|
|
|
<!-- <el-pagination style="margin-top:10px" background layout="prev, pager, next" :total="1000" /> -->
|
|
|
|
<!-- <el-pagination style="margin-top:10px" background layout="prev, pager, next" :total="1000" /> -->
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="pdfRef" id="pdfRef" style="margin-top:20px;gap:25px;display: flex;" v-show="showChart">
|
|
|
|
<div class="pdfRef" id="pdfRef" style="margin-top: 20px; gap: 25px; display: flex" v-show="showChart">
|
|
|
|
<!-- <img src="../../../assets/images/图1.png" alt=""> -->
|
|
|
|
<!-- <img src="../../../assets/images/图1.png" alt=""> -->
|
|
|
|
<div style="background:#FFFFFF;">
|
|
|
|
<div style="background: #ffffff">
|
|
|
|
<div id="main" style="width: 500px;height: 500px;"></div>
|
|
|
|
<div id="main" style="width: 500px; height: 500px"></div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div style="background:#FFFFFF;">
|
|
|
|
<div style="background: #ffffff">
|
|
|
|
<div id="main2" style="width: 500px;height: 500px;"></div>
|
|
|
|
<div id="main2" style="width: 500px; height: 500px"></div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</el-scrollbar>
|
|
|
|
</el-scrollbar>
|
|
|
|
|
|
|
|
|
|
|
|
<el-dialog
|
|
|
|
<el-dialog v-model="dialogVisible" title="实训任务提交" width="600" custom-class="dialogClass" :show-close="false">
|
|
|
|
v-model="dialogVisible"
|
|
|
|
|
|
|
|
title="实训任务提交"
|
|
|
|
|
|
|
|
width="600"
|
|
|
|
|
|
|
|
custom-class="dialogClass"
|
|
|
|
|
|
|
|
:show-close="false"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<template #header="{ close, titleId, titleClass }">
|
|
|
|
<template #header="{ close, titleId, titleClass }">
|
|
|
|
<div class="my-header">
|
|
|
|
<div class="my-header">
|
|
|
|
<span :id="titleId" :class="titleClass">实训任务提交</span>
|
|
|
|
<span :id="titleId" :class="titleClass">实训任务提交</span>
|
|
|
|
<img class="gbImg" src="../../../assets/images/关闭.png" @click="close" alt="">
|
|
|
|
<img class="gbImg" src="../../../assets/images/关闭.png" @click="close" alt="" />
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<img class="xtImg" src="../../../assets/images/线条.png" alt="">
|
|
|
|
<img class="xtImg" src="../../../assets/images/线条.png" alt="" />
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
<div class="from-item">
|
|
|
|
<div class="from-item">
|
|
|
|
<el-form :inline="true" label-position="right" label-width="115px" :model="form" class="demo-form-inline">
|
|
|
|
<el-form :inline="true" label-position="right" label-width="115px" :model="form" class="demo-form-inline">
|
|
|
|
<el-form-item label="聚类个数:">
|
|
|
|
<el-form-item label="聚类个数:">
|
|
|
|
<el-input style="width: 120px;" v-model="formInline.user" clearable />
|
|
|
|
<el-input style="width: 120px" v-model="formInline.user" clearable />
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item label="最大迭代次数:">
|
|
|
|
<el-form-item label="最大迭代次数:">
|
|
|
|
<el-input style="width: 120px;" v-model="formInline.user" clearable />
|
|
|
|
<el-input style="width: 120px" v-model="formInline.user" clearable />
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form>
|
|
|
|
</el-form>
|
|
|
|
<span style="color:#FFFFFF;font-weight: 700;">各簇类特征描述:</span>
|
|
|
|
<span style="color: #ffffff; font-weight: 700">各簇类特征描述:</span>
|
|
|
|
<el-form :inline="true" label-position="right" style="margin: 15px 0" label-width="115px" :model="form" class="demo-form-inline">
|
|
|
|
<el-form :inline="true" label-position="right" style="margin: 15px 0" label-width="115px" :model="form" class="demo-form-inline">
|
|
|
|
<el-form-item label="簇类1:">
|
|
|
|
<el-form-item label="簇类1:">
|
|
|
|
<el-input style="width: 240px;" v-model="formInline.user" clearable />
|
|
|
|
<el-input style="width: 240px" v-model="formInline.user" clearable />
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item label="簇类2:">
|
|
|
|
<el-form-item label="簇类2:">
|
|
|
|
<el-input style="width: 240px;" v-model="formInline.user" clearable />
|
|
|
|
<el-input style="width: 240px" v-model="formInline.user" clearable />
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item label="簇类3:">
|
|
|
|
<el-form-item label="簇类3:">
|
|
|
|
<el-input style="width: 240px;" v-model="formInline.user" clearable />
|
|
|
|
<el-input style="width: 240px" v-model="formInline.user" clearable />
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item label="簇类4:">
|
|
|
|
<el-form-item label="簇类4:">
|
|
|
|
<el-input style="width: 240px;" v-model="formInline.user" clearable />
|
|
|
|
<el-input style="width: 240px" v-model="formInline.user" clearable />
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form>
|
|
|
|
</el-form>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<template #footer>
|
|
|
|
<template #footer>
|
|
|
|
<div class="dialog-footer">
|
|
|
|
<div class="dialog-footer">
|
|
|
|
<el-button @click="dialogVisible = false">确定</el-button>
|
|
|
|
<el-button @click="dialogVisible = false">确定</el-button>
|
|
|
|
<el-button type="primary" @click="dialogVisible = false">
|
|
|
|
<el-button type="primary" @click="dialogVisible = false">返回</el-button>
|
|
|
|
返回
|
|
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
</el-dialog>
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
|
|
|
|
<pop-model
|
|
|
|
<pop-model :showModel="runResultShow" title="聚类分析" @closePop="runResultShow = false">
|
|
|
|
:showModel="runResultShow"
|
|
|
|
|
|
|
|
title="聚类分析"
|
|
|
|
|
|
|
|
@closePop="runResultShow = false"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<template v-slot:content>
|
|
|
|
<template v-slot:content>
|
|
|
|
<div>
|
|
|
|
<div>
|
|
|
|
<p style="font-weight: 700;font-size:22px">聚类分析的定义及原理</p><p style="font-size:19px">1.定义</p><p> 所谓物以类聚、人以群分。聚类分析,即是基于研究对象的特征,将他们分门别类,以让同类别的个体之间差异相对小、相似度相对大,不同类别之间的个体差异大、相似度小。<br /> 聚类分析是一种探索性分析方法,与判别分析不同,聚类分析事先并不知道分类的标准,甚至不知道应该分成几类,而是会根据样本数据的特征,自动进行分类。</p><img src="@/assets/images/f1001.png" />
|
|
|
|
<p style="font-weight: 700; font-size: 22px">聚类分析的定义及原理</p>
|
|
|
|
<p>聚类与分类的不同在于,聚类所要求划分的类是未知的</p><img src="@/assets/images/f1002.png" /><img src="@/assets/images/f1003.png" /><img src="@/assets/images/f1005.png" /><p style="font-size:19px">2.原理</p><p> 假定研究对象均用所谓的“点”来表示。<br /> 在聚类分析中,一般的规则是将“距离”较小的点归为同一类,将“距离”较大的点归为不同的类。常见的是对个案分类,也可以对变量分类,但对于变量分类此时一般使用相似系数作为“距离”测量指标。<br/> 一般的规则:</p><img src="@/assets/images/f10010.png" /><br /><img src="@/assets/images/f10011.png" />
|
|
|
|
<p style="font-size: 19px">1.定义</p>
|
|
|
|
<br /><img src="@/assets/images/f10012.png" /><p style="font-weight: 700;font-size:22px">聚类方法及其在SPSS中的实现</p><p style="font-size:19px">1.主要的聚类方法:</p><img src="@/assets/images/f10013.png" /><p style="font-size:19px">2.方法详解:</p><p style="font-size:17px">(1):K-means聚类</p><p> 又称为快速聚类(K-Means Cluster),是在聚类的类别数已确定的情况下,快速将其他个案归类到相应的类别,适合大样本数据的聚类。<br /> 具体步骤如下:</p><img src="@/assets/images/f10014.png" /><img src="@/assets/images/f10015.png" /><p>距离计算规则(欧几里得距离公式):</p><img src="@/assets/images/f10016.png" /><p>图解:</p><img src="@/assets/images/f10017.png" /><img src="@/assets/images/f10018.png" />
|
|
|
|
<p>
|
|
|
|
<p>K-means的优缺点:<br />优势:<br /> (1)原理比较简单,实现也很容易,收敛速度快。<br /> (2)在对大规模数据集进行聚类分析时,算法聚类较高效且聚类效果较好。<br /> (3)簇与簇之间区别明显时,它的聚类效果很好。<br />不足:<br /> (1)分类数从初始分类开始就确定不变了,所以要求事先要对样本有足够的了解。<br />(2)仅限于个案间的聚类(Q型聚类),不能对变量进行聚类。<br /> (3)个案间的距离的测量方法使用的是欧式距离的平方,因此只能对连续变量进行聚类。<br />案例分析(SPSS):<br />通过查询整理出了2018年我国各省份的20项基本情况,根据这些指标把这31个省市或地区分成3类。</p><img src="@/assets/images/f10019.png" /><p> 分析步骤:分析>>分类>>K-均值聚类>>迭代>>次数>>选项>>勾选统计>>确认</p><img src="@/assets/images/f10020.png" /><img src="@/assets/images/f10021.png" /><p>结果分析:</p>
|
|
|
|
所谓物以类聚、人以群分。聚类分析,即是基于研究对象的特征,将他们分门别类,以让同类别的个体之间差异相对小、相似度相对大,不同类别之间的个体差异大、相似度小。
|
|
|
|
<img src="@/assets/images/f10022.png" /><img src="@/assets/images/f10023.png" /><p>若不收敛则调大迭代次数</p><img src="@/assets/images/f10024.png" /><p>方差分析表:</p><img src="@/assets/images/f10025.png" /><p> 其中聚类均方对应组间均方差,误差均方对应组内均方差,显著性p<0.05时说明此变量分类效果好。由表可知,大部分变量的p<0.05,且组间均方差大于组内均方差,说明各变量在三个类别中的差异大,分类结果可信度高。</p><img src="@/assets/images/f10026.png" /><br /><img src="@/assets/images/10027.png" /><p>聚类结果解读:</p>
|
|
|
|
<br />
|
|
|
|
<div class="table-box"><table cellspacing="0" style="width:355pt;"><tbody><tr><td style="text-align:center;vertical-align:middle;width:355pt;"> <p style="margin-left:0in;text-align:center;"><strong>第一类:</strong><strong>1</strong><strong>个省份(广东省,经济发达)</strong></p> </td></tr><tr><td style="background-color:#e7e7e7;text-align:center;vertical-align:middle;width:355pt;"> <p style="margin-left:0in;text-align:center;"><strong>第二类:</strong><strong>19</strong><strong>个省份(云南、西藏等地区,经济一般)</strong></p> </td></tr><tr><td style="text-align:center;vertical-align:middle;width:355pt;"> <p style="margin-left:0in;text-align:center;"><strong>第三类:</strong><strong>11</strong><strong>个省份(上海、北京等地区,经济较发达)</strong></p> </td></tr></tbody></table></div>
|
|
|
|
聚类分析是一种探索性分析方法,与判别分析不同,聚类分析事先并不知道分类的标准,甚至不知道应该分成几类,而是会根据样本数据的特征,自动进行分类。
|
|
|
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
<img src="@/assets/images/f1001.png" />
|
|
|
|
|
|
|
|
<p>聚类与分类的不同在于,聚类所要求划分的类是未知的</p>
|
|
|
|
|
|
|
|
<img src="@/assets/images/f1002.png" />
|
|
|
|
|
|
|
|
<img src="@/assets/images/f1003.png" />
|
|
|
|
|
|
|
|
<img src="@/assets/images/f1005.png" />
|
|
|
|
|
|
|
|
<p style="font-size: 19px">2.原理</p>
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
|
|
|
假定研究对象均用所谓的“点”来表示。
|
|
|
|
|
|
|
|
<br />
|
|
|
|
|
|
|
|
在聚类分析中,一般的规则是将“距离”较小的点归为同一类,将“距离”较大的点归为不同的类。常见的是对个案分类,也可以对变量分类,但对于变量分类此时一般使用相似系数作为“距离”测量指标。
|
|
|
|
|
|
|
|
<br />
|
|
|
|
|
|
|
|
一般的规则:
|
|
|
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
<img src="@/assets/images/f10010.png" />
|
|
|
|
|
|
|
|
<br />
|
|
|
|
|
|
|
|
<img src="@/assets/images/f10011.png" />
|
|
|
|
|
|
|
|
<br />
|
|
|
|
|
|
|
|
<img src="@/assets/images/f10012.png" />
|
|
|
|
|
|
|
|
<p style="font-weight: 700; font-size: 22px">聚类方法及其在SPSS中的实现</p>
|
|
|
|
|
|
|
|
<p style="font-size: 19px">1.主要的聚类方法:</p>
|
|
|
|
|
|
|
|
<img src="@/assets/images/f10013.png" />
|
|
|
|
|
|
|
|
<p style="font-size: 19px">2.方法详解:</p>
|
|
|
|
|
|
|
|
<p style="font-size: 17px">(1):K-means聚类</p>
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
|
|
|
又称为快速聚类(K-Means Cluster),是在聚类的类别数已确定的情况下,快速将其他个案归类到相应的类别,适合大样本数据的聚类。
|
|
|
|
|
|
|
|
<br />
|
|
|
|
|
|
|
|
具体步骤如下:
|
|
|
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
<img src="@/assets/images/f10014.png" />
|
|
|
|
|
|
|
|
<img src="@/assets/images/f10015.png" />
|
|
|
|
|
|
|
|
<p>距离计算规则(欧几里得距离公式):</p>
|
|
|
|
|
|
|
|
<img src="@/assets/images/f10016.png" />
|
|
|
|
|
|
|
|
<p>图解:</p>
|
|
|
|
|
|
|
|
<img src="@/assets/images/f10017.png" />
|
|
|
|
|
|
|
|
<img src="@/assets/images/f10018.png" />
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
|
|
|
K-means的优缺点:
|
|
|
|
|
|
|
|
<br />
|
|
|
|
|
|
|
|
优势:
|
|
|
|
|
|
|
|
<br />
|
|
|
|
|
|
|
|
(1)原理比较简单,实现也很容易,收敛速度快。
|
|
|
|
|
|
|
|
<br />
|
|
|
|
|
|
|
|
(2)在对大规模数据集进行聚类分析时,算法聚类较高效且聚类效果较好。
|
|
|
|
|
|
|
|
<br />
|
|
|
|
|
|
|
|
(3)簇与簇之间区别明显时,它的聚类效果很好。
|
|
|
|
|
|
|
|
<br />
|
|
|
|
|
|
|
|
不足:
|
|
|
|
|
|
|
|
<br />
|
|
|
|
|
|
|
|
(1)分类数从初始分类开始就确定不变了,所以要求事先要对样本有足够的了解。
|
|
|
|
|
|
|
|
<br />
|
|
|
|
|
|
|
|
(2)仅限于个案间的聚类(Q型聚类),不能对变量进行聚类。
|
|
|
|
|
|
|
|
<br />
|
|
|
|
|
|
|
|
(3)个案间的距离的测量方法使用的是欧式距离的平方,因此只能对连续变量进行聚类。
|
|
|
|
|
|
|
|
<br />
|
|
|
|
|
|
|
|
案例分析(SPSS):
|
|
|
|
|
|
|
|
<br />
|
|
|
|
|
|
|
|
通过查询整理出了2018年我国各省份的20项基本情况,根据这些指标把这31个省市或地区分成3类。
|
|
|
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
<img src="@/assets/images/f10019.png" />
|
|
|
|
|
|
|
|
<p>分析步骤:分析>>分类>>K-均值聚类>>迭代>>次数>>选项>>勾选统计>>确认</p>
|
|
|
|
|
|
|
|
<img src="@/assets/images/f10020.png" />
|
|
|
|
|
|
|
|
<img src="@/assets/images/f10021.png" />
|
|
|
|
|
|
|
|
<p>结果分析:</p>
|
|
|
|
|
|
|
|
<img src="@/assets/images/f10022.png" />
|
|
|
|
|
|
|
|
<img src="@/assets/images/f10023.png" />
|
|
|
|
|
|
|
|
<p>若不收敛则调大迭代次数</p>
|
|
|
|
|
|
|
|
<img src="@/assets/images/f10024.png" />
|
|
|
|
|
|
|
|
<p>方差分析表:</p>
|
|
|
|
|
|
|
|
<img src="@/assets/images/f10025.png" />
|
|
|
|
|
|
|
|
<p>其中聚类均方对应组间均方差,误差均方对应组内均方差,显著性p<0.05时说明此变量分类效果好。由表可知,大部分变量的p<0.05,且组间均方差大于组内均方差,说明各变量在三个类别中的差异大,分类结果可信度高。</p>
|
|
|
|
|
|
|
|
<img src="@/assets/images/f10026.png" />
|
|
|
|
|
|
|
|
<br />
|
|
|
|
|
|
|
|
<img src="@/assets/images/10027.png" />
|
|
|
|
|
|
|
|
<p>聚类结果解读:</p>
|
|
|
|
|
|
|
|
<div class="table-box">
|
|
|
|
|
|
|
|
<table cellspacing="0" style="width: 355pt">
|
|
|
|
|
|
|
|
<tbody>
|
|
|
|
|
|
|
|
<tr>
|
|
|
|
|
|
|
|
<td style="text-align: center; vertical-align: middle; width: 355pt">
|
|
|
|
|
|
|
|
<p style="margin-left: 0in; text-align: center">
|
|
|
|
|
|
|
|
<strong>第一类:</strong>
|
|
|
|
|
|
|
|
<strong>1</strong>
|
|
|
|
|
|
|
|
<strong>个省份(广东省,经济发达)</strong>
|
|
|
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
</td>
|
|
|
|
|
|
|
|
</tr>
|
|
|
|
|
|
|
|
<tr>
|
|
|
|
|
|
|
|
<td style="background-color: #e7e7e7; text-align: center; vertical-align: middle; width: 355pt">
|
|
|
|
|
|
|
|
<p style="margin-left: 0in; text-align: center">
|
|
|
|
|
|
|
|
<strong>第二类:</strong>
|
|
|
|
|
|
|
|
<strong>19</strong>
|
|
|
|
|
|
|
|
<strong>个省份(云南、西藏等地区,经济一般)</strong>
|
|
|
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
</td>
|
|
|
|
|
|
|
|
</tr>
|
|
|
|
|
|
|
|
<tr>
|
|
|
|
|
|
|
|
<td style="text-align: center; vertical-align: middle; width: 355pt">
|
|
|
|
|
|
|
|
<p style="margin-left: 0in; text-align: center">
|
|
|
|
|
|
|
|
<strong>第三类:</strong>
|
|
|
|
|
|
|
|
<strong>11</strong>
|
|
|
|
|
|
|
|
<strong>个省份(上海、北京等地区,经济较发达)</strong>
|
|
|
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
</td>
|
|
|
|
|
|
|
|
</tr>
|
|
|
|
|
|
|
|
</tbody>
|
|
|
|
|
|
|
|
</table>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
</pop-model>
|
|
|
|
</pop-model>
|
|
|
|
@ -194,40 +268,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
<script setup>
|
|
|
|
import popModel from "@/views/components/popModal.vue";
|
|
|
|
import popModel from "@/views/components/popModal.vue";
|
|
|
|
import {htmlPdf} from "@/utils/pdf.js"
|
|
|
|
import { htmlPdf } from "@/utils/pdf.js";
|
|
|
|
import * as echarts from 'echarts';
|
|
|
|
import * as echarts from "echarts";
|
|
|
|
import * as XLSX from 'xlsx'
|
|
|
|
import * as XLSX from "xlsx";
|
|
|
|
import JSZip from 'jszip';
|
|
|
|
import JSZip from "jszip";
|
|
|
|
import ecStat from 'echarts-stat';
|
|
|
|
import * as API from "@/api/AI.js";
|
|
|
|
import * as API from '@/api/AI.js'
|
|
|
|
|
|
|
|
import { getUserInfo } from "@/utils/auth";
|
|
|
|
import { getUserInfo } from "@/utils/auth";
|
|
|
|
import { onMounted } from 'vue';
|
|
|
|
import { onMounted } from "vue";
|
|
|
|
const runResultShow=ref(false)
|
|
|
|
const runResultShow = ref(false);
|
|
|
|
const { proxy } = getCurrentInstance()
|
|
|
|
const { proxy } = getCurrentInstance();
|
|
|
|
const dialogVisible=ref(false)
|
|
|
|
const dialogVisible = ref(false);
|
|
|
|
const tableLabel=reactive([
|
|
|
|
const tableLabel = reactive([{ prop: "date", label: "" }]);
|
|
|
|
{prop:'date',label:''},
|
|
|
|
const isFlag = ref(false);
|
|
|
|
])
|
|
|
|
|
|
|
|
const isFlag=ref(false)
|
|
|
|
|
|
|
|
const algorithmicKnowledge = () => {
|
|
|
|
const algorithmicKnowledge = () => {
|
|
|
|
runResultShow.value = true
|
|
|
|
runResultShow.value = true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
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) => {
|
|
|
|
options.value.push({
|
|
|
|
options.value.push({
|
|
|
|
value: element,
|
|
|
|
value: element,
|
|
|
|
label:element
|
|
|
|
label: element,
|
|
|
|
})
|
|
|
|
});
|
|
|
|
})
|
|
|
|
});
|
|
|
|
})
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
const scrollbar = ref(null);
|
|
|
|
const scrollbar = ref(null);
|
|
|
|
const fileList=ref([])
|
|
|
|
const fileList = ref([]);
|
|
|
|
const handleChange = (info) => {
|
|
|
|
const handleChange = (info) => {
|
|
|
|
fileList.value.push(info);
|
|
|
|
fileList.value.push(info);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
const flag=ref(false)
|
|
|
|
const flag = ref(false);
|
|
|
|
let myChart;
|
|
|
|
let myChart;
|
|
|
|
let myChart2;
|
|
|
|
let myChart2;
|
|
|
|
const getRandomColorHex = () => {
|
|
|
|
const getRandomColorHex = () => {
|
|
|
|
@ -235,7 +306,7 @@ const algorithmicKnowledge=()=>{
|
|
|
|
// 生成 min 到 max 之间的随机整数
|
|
|
|
// 生成 min 到 max 之间的随机整数
|
|
|
|
const value = Math.floor(Math.random() * (max - min + 1)) + min;
|
|
|
|
const value = Math.floor(Math.random() * (max - min + 1)) + min;
|
|
|
|
// 将整数转换为两位十六进制形式
|
|
|
|
// 将整数转换为两位十六进制形式
|
|
|
|
return value.toString(16).padStart(2, '0');
|
|
|
|
return value.toString(16).padStart(2, "0");
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 限制红色通道较低,绿色和蓝色通道较高
|
|
|
|
// 限制红色通道较低,绿色和蓝色通道较高
|
|
|
|
@ -250,10 +321,10 @@ const algorithmicKnowledge=()=>{
|
|
|
|
// 获取当前的数据
|
|
|
|
// 获取当前的数据
|
|
|
|
let currentData = myChart.getOption().series[0].data || [];
|
|
|
|
let currentData = myChart.getOption().series[0].data || [];
|
|
|
|
// 添加新数据集,并为每个数据点单独设置颜色
|
|
|
|
// 添加新数据集,并为每个数据点单独设置颜色
|
|
|
|
newData.forEach(dataPoint => {
|
|
|
|
newData.forEach((dataPoint) => {
|
|
|
|
currentData.push({
|
|
|
|
currentData.push({
|
|
|
|
value: [dataPoint.x, dataPoint.y],
|
|
|
|
value: [dataPoint.x, dataPoint.y],
|
|
|
|
itemStyle: { color: color }
|
|
|
|
itemStyle: { color: color },
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
@ -261,226 +332,227 @@ const algorithmicKnowledge=()=>{
|
|
|
|
myChart.setOption({
|
|
|
|
myChart.setOption({
|
|
|
|
series: [
|
|
|
|
series: [
|
|
|
|
{
|
|
|
|
{
|
|
|
|
data: currentData
|
|
|
|
data: currentData,
|
|
|
|
}
|
|
|
|
},
|
|
|
|
]
|
|
|
|
],
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
onMounted(() => {
|
|
|
|
getList()
|
|
|
|
getList();
|
|
|
|
var chartDom = document.getElementById('main');
|
|
|
|
var chartDom = document.getElementById("main");
|
|
|
|
var chartDom2 = document.getElementById('main2');
|
|
|
|
var chartDom2 = document.getElementById("main2");
|
|
|
|
myChart = echarts.init(chartDom);
|
|
|
|
myChart = echarts.init(chartDom);
|
|
|
|
myChart2 = echarts.init(chartDom2);
|
|
|
|
myChart2 = echarts.init(chartDom2);
|
|
|
|
// 初始化图表配置
|
|
|
|
// 初始化图表配置
|
|
|
|
var option = {
|
|
|
|
var option = {
|
|
|
|
dataset: [
|
|
|
|
dataset: [
|
|
|
|
{
|
|
|
|
{
|
|
|
|
source: [] // 初始时数据为空
|
|
|
|
source: [], // 初始时数据为空
|
|
|
|
}
|
|
|
|
},
|
|
|
|
],
|
|
|
|
],
|
|
|
|
tooltip: {
|
|
|
|
tooltip: {
|
|
|
|
position: 'top'
|
|
|
|
position: "top",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
xAxis: {},
|
|
|
|
xAxis: {},
|
|
|
|
yAxis: {},
|
|
|
|
yAxis: {},
|
|
|
|
series: [
|
|
|
|
series: [
|
|
|
|
{
|
|
|
|
{
|
|
|
|
type: 'scatter',
|
|
|
|
type: "scatter",
|
|
|
|
encode: { tooltip: [0, 1] },
|
|
|
|
encode: { tooltip: [0, 1] },
|
|
|
|
symbolSize: 15,
|
|
|
|
symbolSize: 15,
|
|
|
|
itemStyle: {
|
|
|
|
itemStyle: {
|
|
|
|
borderColor: '#555'
|
|
|
|
borderColor: "#555",
|
|
|
|
}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
},
|
|
|
|
]
|
|
|
|
],
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 设置初始的配置
|
|
|
|
// 设置初始的配置
|
|
|
|
myChart.setOption(option);
|
|
|
|
myChart.setOption(option);
|
|
|
|
myChart2.setOption(option);
|
|
|
|
myChart2.setOption(option);
|
|
|
|
})
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const optionData = () => {
|
|
|
|
const optionData = () => {
|
|
|
|
API.viewingMetrics({userId:JSON.parse(getUserInfo()).userId,tableName:input.value,algorithmName:'聚类分析'}).then((res)=>{
|
|
|
|
API.viewingMetrics({ userId: JSON.parse(getUserInfo()).userId, tableName: input.value, algorithmName: "聚类分析" }).then((res) => {
|
|
|
|
tableData.value=[]
|
|
|
|
tableData.value = [];
|
|
|
|
res.data.forEach(element => {
|
|
|
|
res.data.forEach((element) => {
|
|
|
|
tableData.value.push({
|
|
|
|
tableData.value.push({
|
|
|
|
text:element
|
|
|
|
text: element,
|
|
|
|
})
|
|
|
|
});
|
|
|
|
})
|
|
|
|
});
|
|
|
|
})
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
const selectedRows = ref([]);
|
|
|
|
const selectedRows = ref([]);
|
|
|
|
const handleSelectionChange = (selection) => {
|
|
|
|
const handleSelectionChange = (selection) => {
|
|
|
|
selectedRows.value = selection;
|
|
|
|
selectedRows.value = selection;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
const tableData2=ref([])
|
|
|
|
const tableData2 = ref([]);
|
|
|
|
const tableData3=ref([])
|
|
|
|
const tableData3 = ref([]);
|
|
|
|
const resTable2=ref()
|
|
|
|
const resTable2 = ref();
|
|
|
|
const taskZB = () => {
|
|
|
|
const taskZB = () => {
|
|
|
|
flag.value=true
|
|
|
|
flag.value = true;
|
|
|
|
if (selectedRows.value.length === 0) {
|
|
|
|
if (selectedRows.value.length === 0) {
|
|
|
|
return
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const sendData = {
|
|
|
|
const sendData = {
|
|
|
|
tableName: input.value,
|
|
|
|
tableName: input.value,
|
|
|
|
userId: JSON.parse(getUserInfo()).userId,
|
|
|
|
userId: JSON.parse(getUserInfo()).userId,
|
|
|
|
fieldList:selectedRows.value.map(item=>item.text)
|
|
|
|
fieldList: selectedRows.value.map((item) => item.text),
|
|
|
|
}
|
|
|
|
};
|
|
|
|
API.analysisDataDisplay(sendData).then((res) => {
|
|
|
|
API.analysisDataDisplay(sendData).then((res) => {
|
|
|
|
tableLabel.length=0
|
|
|
|
tableLabel.length = 0;
|
|
|
|
for (const key in res.data[0]) {
|
|
|
|
for (const key in res.data[0]) {
|
|
|
|
tableLabel.push({
|
|
|
|
tableLabel.push({
|
|
|
|
label: key,
|
|
|
|
label: key,
|
|
|
|
prop:key
|
|
|
|
prop: key,
|
|
|
|
})
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
tableData2.value=res.data
|
|
|
|
|
|
|
|
flag.value=true
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tableData2.value = res.data;
|
|
|
|
|
|
|
|
flag.value = true;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
};
|
|
|
|
const formInline = reactive({
|
|
|
|
const formInline = reactive({
|
|
|
|
user:'',
|
|
|
|
user: "",
|
|
|
|
region:''
|
|
|
|
region: "",
|
|
|
|
})
|
|
|
|
});
|
|
|
|
const input=ref()
|
|
|
|
const input = ref();
|
|
|
|
const options = ref([])
|
|
|
|
const options = ref([]);
|
|
|
|
const input2=ref()
|
|
|
|
const input2 = ref();
|
|
|
|
const options2 = ref([
|
|
|
|
const options2 = ref([
|
|
|
|
{
|
|
|
|
{
|
|
|
|
value:'数据区重',
|
|
|
|
value: "数据区重",
|
|
|
|
label:'数据去重'
|
|
|
|
label: "数据去重",
|
|
|
|
}
|
|
|
|
},
|
|
|
|
])
|
|
|
|
]);
|
|
|
|
const input3=ref()
|
|
|
|
const input3 = ref();
|
|
|
|
const options3 = ref([
|
|
|
|
const options3 = ref([
|
|
|
|
{
|
|
|
|
{
|
|
|
|
value:'缺失值处理--剔除数据',
|
|
|
|
value: "缺失值处理--剔除数据",
|
|
|
|
label:'缺失值处理--剔除数据'
|
|
|
|
label: "缺失值处理--剔除数据",
|
|
|
|
},{
|
|
|
|
},
|
|
|
|
value:'缺失值处理--均值替换',
|
|
|
|
{
|
|
|
|
label:'缺失值处理--均值替换'
|
|
|
|
value: "缺失值处理--均值替换",
|
|
|
|
|
|
|
|
label: "缺失值处理--均值替换",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
])
|
|
|
|
]);
|
|
|
|
const input4=ref()
|
|
|
|
const input4 = ref();
|
|
|
|
const options4 = ref([
|
|
|
|
const options4 = ref([
|
|
|
|
{
|
|
|
|
{
|
|
|
|
value:'K-means',
|
|
|
|
value: "K-means",
|
|
|
|
label:'K-means'
|
|
|
|
label: "K-means",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
])
|
|
|
|
]);
|
|
|
|
const input5=ref()
|
|
|
|
const input5 = ref();
|
|
|
|
const input6=ref()
|
|
|
|
const input6 = ref();
|
|
|
|
const taskSubmit = () => {
|
|
|
|
const taskSubmit = () => {
|
|
|
|
dialogVisible.value=true
|
|
|
|
dialogVisible.value = true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
const tableData = ref([
|
|
|
|
const tableData = ref([]);
|
|
|
|
|
|
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
const headerCellStyle = () => {
|
|
|
|
const headerCellStyle = () => {
|
|
|
|
return {
|
|
|
|
return {
|
|
|
|
backgroundColor: "#1882DE !important", // 设置表头背景颜色
|
|
|
|
backgroundColor: "#1882DE !important", // 设置表头背景颜色
|
|
|
|
color: "#ffffff !important",
|
|
|
|
color: "#ffffff !important",
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
};
|
|
|
|
const optionData2 = () => {
|
|
|
|
const optionData2 = () => {
|
|
|
|
if (input2.value && input3.value) {
|
|
|
|
if (input2.value && input3.value) {
|
|
|
|
const sendData = ref({
|
|
|
|
const sendData = ref({
|
|
|
|
mapList: tableData2.value,
|
|
|
|
mapList: tableData2.value,
|
|
|
|
method: input3.value,
|
|
|
|
method: input3.value,
|
|
|
|
userId:JSON.parse(getUserInfo()).userId
|
|
|
|
userId: JSON.parse(getUserInfo()).userId,
|
|
|
|
})
|
|
|
|
});
|
|
|
|
API.dataPreprocessing(sendData.value).then((res) => {
|
|
|
|
API.dataPreprocessing(sendData.value).then((res) => {
|
|
|
|
resTable2.value=res.data
|
|
|
|
resTable2.value = res.data;
|
|
|
|
tableData2.value=[]
|
|
|
|
tableData2.value = [];
|
|
|
|
tableData2.value=res.data
|
|
|
|
tableData2.value = res.data;
|
|
|
|
proxy.$modal.msgSuccess("预处理成功!");
|
|
|
|
proxy.$modal.msgSuccess("预处理成功!");
|
|
|
|
})
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const showChart=ref(false)
|
|
|
|
const showChart = ref(false);
|
|
|
|
//生产表格
|
|
|
|
//生产表格
|
|
|
|
const nowData=ref([])
|
|
|
|
const nowData = ref([]);
|
|
|
|
const computation = () => {
|
|
|
|
const computation = () => {
|
|
|
|
if (input5.value && input6.value && input4.value) {
|
|
|
|
if (input5.value && input6.value && input4.value) {
|
|
|
|
const sendData = {
|
|
|
|
const sendData = {
|
|
|
|
k: input5.value,
|
|
|
|
k: input5.value,
|
|
|
|
t: input6.value,
|
|
|
|
t: input6.value,
|
|
|
|
userId: JSON.parse(getUserInfo()).userId,
|
|
|
|
userId: JSON.parse(getUserInfo()).userId,
|
|
|
|
deduplicatedDataList:resTable2.value
|
|
|
|
deduplicatedDataList: resTable2.value,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
API.clusterAnalysisPlot(sendData).then((res)=>{
|
|
|
|
API.clusterAnalysisPlot(sendData)
|
|
|
|
showChart.value=true
|
|
|
|
.then((res) => {
|
|
|
|
let sex=1
|
|
|
|
showChart.value = true;
|
|
|
|
tableData3.value=[]
|
|
|
|
let sex = 1;
|
|
|
|
nowData.value=res.data
|
|
|
|
tableData3.value = [];
|
|
|
|
|
|
|
|
nowData.value = res.data;
|
|
|
|
res.data.forEach((item, index) => {
|
|
|
|
res.data.forEach((item, index) => {
|
|
|
|
const newItem = {};
|
|
|
|
const newItem = {};
|
|
|
|
tableLabel.forEach((label, index) => {
|
|
|
|
tableLabel.forEach((label, index) => {
|
|
|
|
if (index === 0) {
|
|
|
|
if (index === 0) {
|
|
|
|
newItem[label.prop] = '簇'+sex; // 动态设置字段名
|
|
|
|
newItem[label.prop] = "簇" + sex; // 动态设置字段名
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
newItem[label.prop] =''
|
|
|
|
newItem[label.prop] = "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
newItem['TSuid']=sex
|
|
|
|
newItem["TSuid"] = sex;
|
|
|
|
sex++
|
|
|
|
sex++;
|
|
|
|
tableData3.value.push(newItem);
|
|
|
|
tableData3.value.push(newItem);
|
|
|
|
tableData3.value[index].children=[]
|
|
|
|
tableData3.value[index].children = [];
|
|
|
|
const children=ref([])
|
|
|
|
const children = ref([]);
|
|
|
|
item.forEach((item2, sexx) => {
|
|
|
|
item.forEach((item2, sexx) => {
|
|
|
|
const newItem2 = {};
|
|
|
|
const newItem2 = {};
|
|
|
|
tableLabel.forEach((label, index2) => {
|
|
|
|
tableLabel.forEach((label, index2) => {
|
|
|
|
newItem2[label.prop] = item2[index2]; // 动态设置字段名
|
|
|
|
newItem2[label.prop] = item2[index2]; // 动态设置字段名
|
|
|
|
});
|
|
|
|
});
|
|
|
|
newItem2['TSuid']=''+sex+sexx
|
|
|
|
newItem2["TSuid"] = "" + sex + sexx;
|
|
|
|
children.value.push(newItem2)
|
|
|
|
children.value.push(newItem2);
|
|
|
|
})
|
|
|
|
});
|
|
|
|
tableData3.value[index].children=children.value
|
|
|
|
tableData3.value[index].children = children.value;
|
|
|
|
console.log(tableData3.value);
|
|
|
|
console.log(tableData3.value);
|
|
|
|
|
|
|
|
});
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}).then(()=>{
|
|
|
|
.then(() => {
|
|
|
|
API.clusterAnalysis(sendData).then((res) => {
|
|
|
|
API.clusterAnalysis(sendData).then((res) => {
|
|
|
|
myChart.setOption({
|
|
|
|
myChart.setOption({
|
|
|
|
series: [
|
|
|
|
series: [
|
|
|
|
{
|
|
|
|
{
|
|
|
|
data: [] // 清空数据
|
|
|
|
data: [], // 清空数据
|
|
|
|
}
|
|
|
|
},
|
|
|
|
]
|
|
|
|
],
|
|
|
|
});
|
|
|
|
});
|
|
|
|
myChart2.setOption({
|
|
|
|
myChart2.setOption({
|
|
|
|
series: [
|
|
|
|
series: [
|
|
|
|
{
|
|
|
|
{
|
|
|
|
data: [] // 清空数据
|
|
|
|
data: [], // 清空数据
|
|
|
|
}
|
|
|
|
},
|
|
|
|
]
|
|
|
|
],
|
|
|
|
});
|
|
|
|
});
|
|
|
|
Object.keys(res.data.dataSet).forEach(key => {
|
|
|
|
Object.keys(res.data.dataSet).forEach((key) => {
|
|
|
|
const bgColor=getRandomColorHex()
|
|
|
|
const bgColor = getRandomColorHex();
|
|
|
|
addData(myChart, res.data.dataSet[key], bgColor);
|
|
|
|
addData(myChart, res.data.dataSet[key], bgColor);
|
|
|
|
addData(myChart2, res.data.dataSet[key], bgColor);
|
|
|
|
addData(myChart2, res.data.dataSet[key], bgColor);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
Object.keys(res.data.centroid).forEach(key => {
|
|
|
|
Object.keys(res.data.centroid).forEach((key) => {
|
|
|
|
addData(myChart2, res.data.centroid[key],'red');
|
|
|
|
addData(myChart2, res.data.centroid[key], "red");
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
})
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
nextTick(() => {
|
|
|
|
nextTick(() => {
|
|
|
|
setTimeout(() => {
|
|
|
|
setTimeout(() => {
|
|
|
|
const scrollContainer = scrollbar.value?.$el.querySelector('.el-scrollbar__wrap');
|
|
|
|
const scrollContainer = scrollbar.value?.$el.querySelector(".el-scrollbar__wrap");
|
|
|
|
if (scrollContainer) {
|
|
|
|
if (scrollContainer) {
|
|
|
|
scrollContainer.scrollTo({
|
|
|
|
scrollContainer.scrollTo({
|
|
|
|
top: scrollContainer.scrollHeight,
|
|
|
|
top: scrollContainer.scrollHeight,
|
|
|
|
behavior: 'smooth' // 平滑滚动
|
|
|
|
behavior: "smooth", // 平滑滚动
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, 100);
|
|
|
|
}, 100);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
const exportTableRef = ref(null);
|
|
|
|
const exportTableRef = ref(null);
|
|
|
|
const upLoad = () => {
|
|
|
|
const upLoad = () => {
|
|
|
|
const tableDom = exportTableRef.value?.$el;
|
|
|
|
const tableDom = exportTableRef.value?.$el;
|
|
|
|
@ -490,49 +562,49 @@ const nowData=ref([])
|
|
|
|
const wb = XLSX.utils.table_to_book(tableDom);
|
|
|
|
const wb = XLSX.utils.table_to_book(tableDom);
|
|
|
|
// XLSX.writeFile(wb, '聚类分析.xlsx');
|
|
|
|
// XLSX.writeFile(wb, '聚类分析.xlsx');
|
|
|
|
const zip = new JSZip();
|
|
|
|
const zip = new JSZip();
|
|
|
|
const excelBlob = XLSX.write(wb, { bookType: 'xlsx', type: 'array' });
|
|
|
|
const excelBlob = XLSX.write(wb, { bookType: "xlsx", type: "array" });
|
|
|
|
zip.file('聚类分析.xlsx', new Blob([excelBlob], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }));
|
|
|
|
zip.file("聚类分析.xlsx", new Blob([excelBlob], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }));
|
|
|
|
zip.file('聚类分析图表.pdf', handleExport());
|
|
|
|
zip.file("聚类分析图表.pdf", handleExport());
|
|
|
|
zip.generateAsync({ type: 'blob' }).then((content) => {
|
|
|
|
zip.generateAsync({ type: "blob" }).then((content) => {
|
|
|
|
saveAs(content, '聚类分析.zip');
|
|
|
|
saveAs(content, "聚类分析.zip");
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const startOver = () => {
|
|
|
|
const startOver = () => {
|
|
|
|
myChart.setOption({
|
|
|
|
myChart.setOption({
|
|
|
|
series: [
|
|
|
|
series: [
|
|
|
|
{
|
|
|
|
{
|
|
|
|
data: [] // 清空数据
|
|
|
|
data: [], // 清空数据
|
|
|
|
}
|
|
|
|
},
|
|
|
|
]
|
|
|
|
],
|
|
|
|
});
|
|
|
|
});
|
|
|
|
myChart2.setOption({
|
|
|
|
myChart2.setOption({
|
|
|
|
series: [
|
|
|
|
series: [
|
|
|
|
{
|
|
|
|
{
|
|
|
|
data: [] // 清空数据
|
|
|
|
data: [], // 清空数据
|
|
|
|
}
|
|
|
|
},
|
|
|
|
]
|
|
|
|
],
|
|
|
|
});
|
|
|
|
});
|
|
|
|
input.value=''
|
|
|
|
input.value = "";
|
|
|
|
tableData.value=[]
|
|
|
|
tableData.value = [];
|
|
|
|
tableData2.value=[]
|
|
|
|
tableData2.value = [];
|
|
|
|
tableData3.value=[]
|
|
|
|
tableData3.value = [];
|
|
|
|
input2.value=''
|
|
|
|
input2.value = "";
|
|
|
|
input3.value=''
|
|
|
|
input3.value = "";
|
|
|
|
input4.value=''
|
|
|
|
input4.value = "";
|
|
|
|
input5.value=''
|
|
|
|
input5.value = "";
|
|
|
|
input6.value=''
|
|
|
|
input6.value = "";
|
|
|
|
showChart.value=false
|
|
|
|
showChart.value = false;
|
|
|
|
tableLabel.length=0
|
|
|
|
tableLabel.length = 0;
|
|
|
|
nowData.value=[]
|
|
|
|
nowData.value = [];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
//图表导出pdf
|
|
|
|
//图表导出pdf
|
|
|
|
const handleExport = async (name) => {
|
|
|
|
const handleExport = async (name) => {
|
|
|
|
var fileName= '聚类分析图表'
|
|
|
|
var fileName = "聚类分析图表";
|
|
|
|
const fileList = document.getElementsByClassName('pdfRef') // 很重要
|
|
|
|
const fileList = document.getElementsByClassName("pdfRef"); // 很重要
|
|
|
|
const pdfBlob = await htmlPdf(fileName, document.querySelector('#pdfRef'), fileList,true)
|
|
|
|
const pdfBlob = await htmlPdf(fileName, document.querySelector("#pdfRef"), fileList, true);
|
|
|
|
return pdfBlob
|
|
|
|
return pdfBlob;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
</script>
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
@ -550,16 +622,16 @@ const handleExport = async(name) => {
|
|
|
|
.el-button:nth-child(1) {
|
|
|
|
.el-button:nth-child(1) {
|
|
|
|
width: 180px;
|
|
|
|
width: 180px;
|
|
|
|
height: 56px;
|
|
|
|
height: 56px;
|
|
|
|
background: url('../../../assets/images/011.png');
|
|
|
|
background: url("../../../assets/images/011.png");
|
|
|
|
color:#FFFFFF;
|
|
|
|
color: #ffffff;
|
|
|
|
border-color:#FFFFFF00;
|
|
|
|
border-color: #ffffff00;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.el-button:nth-child(2) {
|
|
|
|
.el-button:nth-child(2) {
|
|
|
|
width: 180px;
|
|
|
|
width: 180px;
|
|
|
|
height: 56px;
|
|
|
|
height: 56px;
|
|
|
|
background: url('../../../assets/images/022.png');
|
|
|
|
background: url("../../../assets/images/022.png");
|
|
|
|
color:#FFFFFF;
|
|
|
|
color: #ffffff;
|
|
|
|
border-color:#FFFFFF00;
|
|
|
|
border-color: #ffffff00;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.app-main {
|
|
|
|
.app-main {
|
|
|
|
@ -590,23 +662,23 @@ const handleExport = async(name) => {
|
|
|
|
.el-button {
|
|
|
|
.el-button {
|
|
|
|
width: 149px;
|
|
|
|
width: 149px;
|
|
|
|
height: 48px;
|
|
|
|
height: 48px;
|
|
|
|
background: url('../../../assets/images/确定.png');
|
|
|
|
background: url("../../../assets/images/确定.png");
|
|
|
|
color:#FFFFFF;
|
|
|
|
color: #ffffff;
|
|
|
|
border-color:#FFFFFF00;
|
|
|
|
border-color: #ffffff00;
|
|
|
|
background-size: 100% 100%;
|
|
|
|
background-size: 100% 100%;
|
|
|
|
margin: 15px;
|
|
|
|
margin: 15px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.el-input {
|
|
|
|
.el-input {
|
|
|
|
--el-input-text-color:#FFFFFF;
|
|
|
|
--el-input-text-color: #ffffff;
|
|
|
|
--el-input-bg-color: #002651;
|
|
|
|
--el-input-bg-color: #002651;
|
|
|
|
--el-input-border-color:#67B3D6;
|
|
|
|
--el-input-border-color: #67b3d6;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.startOver {
|
|
|
|
.startOver {
|
|
|
|
margin-left: -10px;
|
|
|
|
margin-left: -10px;
|
|
|
|
width: 205px;
|
|
|
|
width: 205px;
|
|
|
|
height: 55px;
|
|
|
|
height: 55px;
|
|
|
|
background: #00F4FF;
|
|
|
|
background: #00f4ff;
|
|
|
|
//水平居中
|
|
|
|
//水平居中
|
|
|
|
display: flex;
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
align-items: center;
|
|
|
|
@ -615,10 +687,10 @@ const handleExport = async(name) => {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
:deep(.el-table) {
|
|
|
|
:deep(.el-table) {
|
|
|
|
--el-table-row-hover-bg-color: #002651 !important;
|
|
|
|
--el-table-row-hover-bg-color: #002651 !important;
|
|
|
|
--el-table-border-color: #7AC1FF;
|
|
|
|
--el-table-border-color: #7ac1ff;
|
|
|
|
.el-table__row {
|
|
|
|
.el-table__row {
|
|
|
|
background-color: #002652 !important;
|
|
|
|
background-color: #002652 !important;
|
|
|
|
color: #E6E6E6;
|
|
|
|
color: #e6e6e6;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -629,35 +701,35 @@ const handleExport = async(name) => {
|
|
|
|
border: 1px solid #0452c6;
|
|
|
|
border: 1px solid #0452c6;
|
|
|
|
:deep(.el-table__header) {
|
|
|
|
:deep(.el-table__header) {
|
|
|
|
.el-table__cell {
|
|
|
|
.el-table__cell {
|
|
|
|
background:linear-gradient(0deg, #5304BE 0%, #9126FE 100%) !important;
|
|
|
|
background: linear-gradient(0deg, #5304be 0%, #9126fe 100%) !important;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
:deep(.el-table) {
|
|
|
|
:deep(.el-table) {
|
|
|
|
--el-table-row-hover-bg-color: #002651 !important;
|
|
|
|
--el-table-row-hover-bg-color: #002651 !important;
|
|
|
|
--el-table-border-color: #002651;
|
|
|
|
--el-table-border-color: #002651;
|
|
|
|
--el-table-bg-color:#FFFFFF00;
|
|
|
|
--el-table-bg-color: #ffffff00;
|
|
|
|
.el-table__row {
|
|
|
|
.el-table__row {
|
|
|
|
background-color: #002652 !important;
|
|
|
|
background-color: #002652 !important;
|
|
|
|
color: #E6E6E6;
|
|
|
|
color: #e6e6e6;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.metrics {
|
|
|
|
.metrics {
|
|
|
|
:deep(.el-input) {
|
|
|
|
:deep(.el-input) {
|
|
|
|
.el-input__wrapper {
|
|
|
|
.el-input__wrapper {
|
|
|
|
background-color:#FFFFFF00;
|
|
|
|
background-color: #ffffff00;
|
|
|
|
background-image:url('../../../assets/images/下拉框.png');
|
|
|
|
background-image: url("../../../assets/images/下拉框.png");
|
|
|
|
background-size: 100% 100%;
|
|
|
|
background-size: 100% 100%;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
--el-input-text-color:#FFFFFF;
|
|
|
|
--el-input-text-color: #ffffff;
|
|
|
|
--el-input-border-color:#FFFFFF00;
|
|
|
|
--el-input-border-color: #ffffff00;
|
|
|
|
--el-input-hover-border-color:#FFFFFF00;
|
|
|
|
--el-input-hover-border-color: #ffffff00;
|
|
|
|
--el-input-hover-border:#FFFFFF00;
|
|
|
|
--el-input-hover-border: #ffffff00;
|
|
|
|
--el-select-border-color-hover:#FFFFFF00;
|
|
|
|
--el-select-border-color-hover: #ffffff00;
|
|
|
|
--el-select-input-focus-border-color:#FFFFFF00;
|
|
|
|
--el-select-input-focus-border-color: #ffffff00;
|
|
|
|
--el-input-placeholder-color:#FFFFFF;
|
|
|
|
--el-input-placeholder-color: #ffffff;
|
|
|
|
.el-input__inner {
|
|
|
|
.el-input__inner {
|
|
|
|
color:#FFFFFF;
|
|
|
|
color: #ffffff;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -666,29 +738,29 @@ const handleExport = async(name) => {
|
|
|
|
.el-button {
|
|
|
|
.el-button {
|
|
|
|
width: 89px;
|
|
|
|
width: 89px;
|
|
|
|
height: 31px;
|
|
|
|
height: 31px;
|
|
|
|
background: url('../../../assets/images/下载.png');
|
|
|
|
background: url("../../../assets/images/下载.png");
|
|
|
|
color: black;
|
|
|
|
color: black;
|
|
|
|
border-color:#FFFFFF00;
|
|
|
|
border-color: #ffffff00;
|
|
|
|
// background-size: 100% 100%;
|
|
|
|
// background-size: 100% 100%;
|
|
|
|
margin: 15px 0px 5px;
|
|
|
|
margin: 15px 0px 5px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
:deep(.el-form-item__label) {
|
|
|
|
:deep(.el-form-item__label) {
|
|
|
|
color: #FFFFFF;;
|
|
|
|
color: #ffffff;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.from-item {
|
|
|
|
.from-item {
|
|
|
|
padding: 20px;
|
|
|
|
padding: 20px;
|
|
|
|
.el-input {
|
|
|
|
.el-input {
|
|
|
|
--el-input-text-color:#FFFFFF;
|
|
|
|
--el-input-text-color: #ffffff;
|
|
|
|
--el-input-bg-color: #002651;
|
|
|
|
--el-input-bg-color: #002651;
|
|
|
|
--el-input-border-color:#67B3D6;
|
|
|
|
--el-input-border-color: #67b3d6;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.dialog-footer {
|
|
|
|
.dialog-footer {
|
|
|
|
margin-bottom: 20px;
|
|
|
|
margin-bottom: 20px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
:deep(.el-table__expand-icon) {
|
|
|
|
:deep(.el-table__expand-icon) {
|
|
|
|
color: #9126FE;
|
|
|
|
color: #9126fe;
|
|
|
|
.el-icon {
|
|
|
|
.el-icon {
|
|
|
|
font-size: 16px;
|
|
|
|
font-size: 16px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|