|
@@ -1,335 +1,41 @@
|
|
|
<template>
|
|
|
- <div class="container">
|
|
|
- <div class="chart-container">
|
|
|
- <VueEcharts :option="ecLineOption" ref="ecLineOptionRef" />
|
|
|
- </div>
|
|
|
- <p class="sub-title">初代散点图</p>
|
|
|
- <div class="chart-container">
|
|
|
- <VueEcharts :option="ecInitScatterOption" ref="ecInitScatterOptionRef" />
|
|
|
- </div>
|
|
|
- <p class="sub-title">中间代散点图</p>
|
|
|
- <div class="chart-container">
|
|
|
- <VueEcharts :option="ecMidScatterOption" ref="ecMidScatterOptionRef" />
|
|
|
- </div>
|
|
|
- <p class="sub-title">最终代散点图</p>
|
|
|
- <div class="chart-container">
|
|
|
- <VueEcharts :option="ecFinalScatterOption" ref="ecFinalScatterOptionRef" />
|
|
|
- </div>
|
|
|
+ <div id="app">
|
|
|
+ <ModelIterationVisualization
|
|
|
+ :showLineChart="showLineChart"
|
|
|
+ :showInitScatterChart="showInitScatterChart"
|
|
|
+ :showMidScatterChart="showMidScatterChart"
|
|
|
+ :showFinalScatterChart="showFinalScatterChart"
|
|
|
+ :lineChartPathParam="lineChartPathParam"
|
|
|
+ :initScatterModelId="initScatterModelId"
|
|
|
+ :midScatterModelId="midScatterModelId"
|
|
|
+ :finalScatterModelId="finalScatterModelId"
|
|
|
+ />
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
-<script setup lang='ts' name=''>
|
|
|
-import {ref} from 'vue'
|
|
|
-import VueEcharts from 'vue-echarts';
|
|
|
-import 'echarts';
|
|
|
-
|
|
|
-const ecLineOptionRef = ref<InstanceType<typeof VueEcharts> | null>(null);
|
|
|
-const ecInitScatterOptionRef = ref<InstanceType<typeof VueEcharts> | null>(null);
|
|
|
-const ecMidScatterOptionRef = ref<InstanceType<typeof VueEcharts> | null>(null);
|
|
|
-const ecFinalScatterOptionRef = ref<InstanceType<typeof VueEcharts> | null>(null);
|
|
|
-
|
|
|
-// 计算数据范围的函数
|
|
|
-const calculateDataRange = (data) => {
|
|
|
- const xValues = data.map(item => item[0]);
|
|
|
- const yValues = data.map(item => item[1]);
|
|
|
- return {
|
|
|
- xMin: Math.min(...xValues),
|
|
|
- xMax: Math.max(...xValues),
|
|
|
- yMin: Math.min(...yValues),
|
|
|
- yMax: Math.max(...yValues)
|
|
|
- };
|
|
|
-};
|
|
|
-
|
|
|
-// 反酸模型 初代 散点图
|
|
|
-const getInitScatterOption=()=>{
|
|
|
-
|
|
|
- const scatterData = [[-0.003333333333333854, -0.4181333333333324], [-0.1733333333333329, -0.26733333333333265], [-0.6233333333333331, -0.3718666666666661], [-0.7088888888888892, -0.3854666666666661], [-0.3366666666666669, -0.3998666666666657], [-0.8888888888888887, -0.36439999999999934], [-0.5633333333333326, -0.6207999999999997], [-0.7333333333333325, -0.36026666666666607], [-0.3366666666666663, -0.29213333333333275], [-1.176666666666666, -0.6095999999999993], [-0.7122222222222225, -0.3807999999999989], [-0.7699999999999996, -0.3718666666666661]];
|
|
|
-
|
|
|
- const range = calculateDataRange(scatterData);
|
|
|
- const padding = 0.1;
|
|
|
- const xMin = range.xMin - Math.abs(range.xMin * padding);
|
|
|
- const xMax = range.xMax + Math.abs(range.xMax * padding);
|
|
|
- const yMin = range.yMin - Math.abs(range.yMin * padding);
|
|
|
- const yMax = range.yMax + Math.abs(range.yMax * padding);
|
|
|
- const min = Math.min(xMin, yMin)
|
|
|
- const max = Math.max(xMax, yMax)
|
|
|
-
|
|
|
- return {
|
|
|
- tooltip: {
|
|
|
- trigger: 'axis',
|
|
|
- axisPointer: {
|
|
|
- type: 'cross'
|
|
|
- }
|
|
|
- },
|
|
|
- legend: {
|
|
|
- data: ['True vs Predicted']
|
|
|
- },
|
|
|
- grid: {
|
|
|
- left: '3%',
|
|
|
- right: '22%',
|
|
|
- bottom: '3%',
|
|
|
- containLabel: true
|
|
|
- },
|
|
|
- xAxis: {
|
|
|
- name: 'True Values',
|
|
|
- type: 'value',
|
|
|
- min: min,
|
|
|
- max: max
|
|
|
- },
|
|
|
- yAxis: {
|
|
|
- name: 'Predicted Values',
|
|
|
- type: 'value',
|
|
|
- min: parseFloat(min.toFixed(2)),
|
|
|
- max: parseFloat(max.toFixed(2))
|
|
|
- },
|
|
|
- series: [
|
|
|
- {
|
|
|
- name: 'True vs Predicted',
|
|
|
- type: 'scatter',
|
|
|
- data: scatterData,
|
|
|
- symbolSize: 10,
|
|
|
- itemStyle: {
|
|
|
- color: '#1f77b4',
|
|
|
- opacity: 0.7
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- name: 'Trendline',
|
|
|
- type: 'line',
|
|
|
- data: [
|
|
|
- [min, min],
|
|
|
- [max, max]
|
|
|
- ],
|
|
|
- lineStyle: {
|
|
|
- type: 'dashed',
|
|
|
- color: '#ff7f0e',
|
|
|
- width: 2
|
|
|
- }
|
|
|
- }
|
|
|
- ]
|
|
|
- };
|
|
|
-}
|
|
|
-// 反酸模型 中间代 散点图
|
|
|
-const getMidScatterOption=()=>{
|
|
|
- const scatterData = [[-0.003333333333333854, -0.5483999999999993], [-0.1733333333333329, -0.2093333333333331], [-0.6233333333333331, -0.5090000000000002], [-0.7088888888888892, -0.4281333333333331], [-0.3366666666666669, -0.4691333333333336], [-0.8888888888888887, -0.49643333333333267], [-0.5633333333333326, -0.7191999999999996], [-0.7333333333333325, -0.5024666666666666], [-0.3366666666666663, -0.37796666666666623], [-1.176666666666666, -0.6415666666666656], [-0.7122222222222225, -0.43299999999999966], [-0.7699999999999996, -0.499966666666667]];
|
|
|
-
|
|
|
- const range = calculateDataRange(scatterData);
|
|
|
- const padding = 0.1;
|
|
|
- const xMin = range.xMin - Math.abs(range.xMin * padding);
|
|
|
- const xMax = range.xMax + Math.abs(range.xMax * padding);
|
|
|
- const yMin = range.yMin - Math.abs(range.yMin * padding);
|
|
|
- const yMax = range.yMax + Math.abs(range.yMax * padding);
|
|
|
- const min = Math.min(xMin, yMin)
|
|
|
- const max = Math.max(xMax, yMax)
|
|
|
- return {
|
|
|
- tooltip: {
|
|
|
- trigger: 'axis',
|
|
|
- axisPointer: {
|
|
|
- type: 'cross'
|
|
|
- }
|
|
|
- },
|
|
|
- legend: {
|
|
|
- data: ['True vs Predicted']
|
|
|
- },
|
|
|
- grid: {
|
|
|
- left: '3%',
|
|
|
- right: '22%',
|
|
|
- bottom: '3%',
|
|
|
- containLabel: true
|
|
|
- },
|
|
|
- xAxis: {
|
|
|
- name: 'True Values',
|
|
|
- type: 'value',
|
|
|
- min: min,
|
|
|
- max: max
|
|
|
- },
|
|
|
- yAxis: {
|
|
|
- name: 'Predicted Values',
|
|
|
- type: 'value',
|
|
|
- min: parseFloat(min.toFixed(2)),
|
|
|
- max: parseFloat(max.toFixed(2))
|
|
|
- },
|
|
|
- series: [
|
|
|
- {
|
|
|
- name: 'True vs Predicted',
|
|
|
- type: 'scatter',
|
|
|
- data: scatterData,
|
|
|
- symbolSize: 10,
|
|
|
- itemStyle: {
|
|
|
- color: '#1f77b4',
|
|
|
- opacity: 0.7
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- name: 'Trendline',
|
|
|
- type: 'line',
|
|
|
- data: [
|
|
|
- [min, min],
|
|
|
- [max, max]
|
|
|
- ],
|
|
|
- lineStyle: {
|
|
|
- type: 'dashed',
|
|
|
- color: '#ff7f0e',
|
|
|
- width: 2
|
|
|
- }
|
|
|
- }
|
|
|
- ]
|
|
|
- };
|
|
|
-}
|
|
|
-// 反酸模型 最终代 散点图
|
|
|
-const getFinalScatterOption=() => {
|
|
|
-
|
|
|
- const scatterData = [[-0.003333333333333854, -0.45726666666666654], [-0.1733333333333329, -0.1726333333333331],
|
|
|
- [-0.6233333333333331, -0.5226666666666667], [-0.7088888888888892, -0.4791888888888889],
|
|
|
- [-0.3366666666666669, -0.3630666666666673], [-0.8888888888888887, -0.48272222222222183],
|
|
|
- [-0.5633333333333326, -0.7492444444444444], [-0.7333333333333325, -0.5572666666666672],
|
|
|
- [-0.3366666666666663, -0.29379999999999984], [-1.176666666666666, -0.8544111111111106],
|
|
|
- [-0.7122222222222225, -0.4959777777777775], [-0.7699999999999996, -0.6149666666666669]];
|
|
|
-
|
|
|
- const range = calculateDataRange(scatterData);
|
|
|
- const padding = 0.1;
|
|
|
- const xMin = range.xMin - Math.abs(range.xMin * padding);
|
|
|
- const xMax = range.xMax + Math.abs(range.xMax * padding);
|
|
|
- const yMin = range.yMin - Math.abs(range.yMin * padding);
|
|
|
- const yMax = range.yMax + Math.abs(range.yMax * padding);
|
|
|
- const min = Math.min(xMin, yMin)
|
|
|
- const max = Math.max(xMax, yMax)
|
|
|
-
|
|
|
- return {
|
|
|
- tooltip: {
|
|
|
- trigger: 'axis',
|
|
|
- axisPointer: {
|
|
|
- type: 'cross'
|
|
|
- }
|
|
|
- },
|
|
|
- legend: {
|
|
|
- data: ['True vs Predicted']
|
|
|
- },
|
|
|
- grid: {
|
|
|
- left: '3%',
|
|
|
- right: '22%',
|
|
|
- bottom: '3%',
|
|
|
- containLabel: true
|
|
|
- },
|
|
|
- xAxis: {
|
|
|
- name: 'True Values',
|
|
|
- type: 'value',
|
|
|
- min: min,
|
|
|
- max: max
|
|
|
- },
|
|
|
- yAxis: {
|
|
|
- name: 'Predicted Values',
|
|
|
- type: 'value',
|
|
|
- min: parseFloat(min.toFixed(2)),
|
|
|
- max: parseFloat(max.toFixed(2))
|
|
|
- },
|
|
|
- series: [
|
|
|
- {
|
|
|
- name: 'True vs Predicted',
|
|
|
- type: 'scatter',
|
|
|
- data: scatterData,
|
|
|
- symbolSize: 10,
|
|
|
- itemStyle: {
|
|
|
- color: '#1f77b4',
|
|
|
- opacity: 0.7
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- name: 'Trendline',
|
|
|
- type: 'line',
|
|
|
- data: [
|
|
|
- [min, min],
|
|
|
- [max, max]
|
|
|
- ],
|
|
|
- lineStyle: {
|
|
|
- type: 'dashed',
|
|
|
- color: '#ff7f0e',
|
|
|
- width: 2
|
|
|
- }
|
|
|
- }
|
|
|
- ]
|
|
|
- };
|
|
|
-}
|
|
|
-
|
|
|
-//获取折线图配置
|
|
|
-const getLineOption=()=>{
|
|
|
- return{
|
|
|
- tooltip:{
|
|
|
- trigger:'axis'
|
|
|
- },
|
|
|
- legend:{
|
|
|
- data:['Random Forest', 'XGBoost', 'Gradient Boosting'] // 模型名称
|
|
|
- },
|
|
|
- grid: {
|
|
|
- left: '3%',
|
|
|
- right: '17%',
|
|
|
- bottom: '3%',
|
|
|
- containLabel: true
|
|
|
- },
|
|
|
- xAxis: {
|
|
|
- name: '模型迭代',
|
|
|
- type: 'category',
|
|
|
- boundaryGap: false,
|
|
|
- data: ['1代','2代','3代','4代','5代','6代','7代','8代','9代'] // train_sizes按10%递增
|
|
|
- },
|
|
|
- yAxis: {
|
|
|
- name: 'Score (R^2)',
|
|
|
- type: 'value'
|
|
|
- },
|
|
|
- series: [
|
|
|
- {
|
|
|
- name: 'Random Forest',
|
|
|
- type: 'line',
|
|
|
- data: [-0.17101591951095463, -0.556719360354051, -0.04083550751401055, -0.20858221504075436, 0.07297292282221035, 0.19857845644421734, 0.28407131176770184, 0.27979356883596496, 0.36904808817286416, 0.4183018571701477] // 使用您的实际R2分数数据
|
|
|
- },
|
|
|
- {
|
|
|
- name: 'XGBoost',
|
|
|
- type: 'line',
|
|
|
- data: [-1.1811781145886937, -1.5645641005612534, -0.12619079632263497, 0.03324096120721032, 0.06969290639267578, 0.12375262461601955, 0.5331670468884062, 0.49454793164801647, 0.31904329339597803, 0.2712670704381914]
|
|
|
- },
|
|
|
- {
|
|
|
- name: 'Gradient Boosting',
|
|
|
- type: 'line',
|
|
|
- data: [-0.8583039298789095, -1.073316171952042, 0.09659300885027666, 0.06097833957434784, 0.191975498544109, 0.3718334600546489, 0.3948098332187753, 0.4398778520728397, 0.452609022210963, 0.41484634172723023]
|
|
|
- }
|
|
|
- ]
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-const ecLineOption=ref(getLineOption());
|
|
|
-const ecInitScatterOption = ref(getInitScatterOption());
|
|
|
-const ecMidScatterOption = ref(getMidScatterOption());
|
|
|
-const ecFinalScatterOption = ref(getFinalScatterOption());
|
|
|
+<script setup lang='ts'>
|
|
|
+import { ref } from 'vue';
|
|
|
+import ModelIterationVisualization from './ModelIterationVisualization.vue';
|
|
|
|
|
|
+const showLineChart = ref(true);
|
|
|
+const showInitScatterChart = ref(true);
|
|
|
+const showMidScatterChart = ref(true);
|
|
|
+const showFinalScatterChart = ref(true);
|
|
|
|
|
|
+// 直接在代码里定义好参数
|
|
|
+const lineChartPathParam = ref('reflux');
|
|
|
+const initScatterModelId = ref(17);
|
|
|
+const midScatterModelId = ref(18);
|
|
|
+const finalScatterModelId = ref(19);
|
|
|
</script>
|
|
|
|
|
|
-
|
|
|
<style scoped>
|
|
|
-.container {
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- gap: 20px;
|
|
|
-}
|
|
|
-
|
|
|
-.sub-title {
|
|
|
- font-size: 14px;
|
|
|
- font-weight: 700;
|
|
|
-}
|
|
|
-
|
|
|
-.chart-container {
|
|
|
- width: 75%;
|
|
|
- height: 450px;
|
|
|
- margin-bottom: 20px;
|
|
|
-}
|
|
|
-
|
|
|
-.VueEcharts {
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- margin: 0 10px;
|
|
|
-}
|
|
|
-</style>
|
|
|
+#app {
|
|
|
+ font-family: Avenir, Helvetica, Arial, sans-serif;
|
|
|
+ -webkit-font-smoothing: antialiased;
|
|
|
+ -moz-osx-font-smoothing: grayscale;
|
|
|
+ text-align: center;
|
|
|
+ color: #2c3e50;
|
|
|
+ margin-top: 60px;
|
|
|
+}
|
|
|
+</style>
|