dev-QQq
方佳 博 2 years ago
parent f0b65e114c
commit ae79ca7201

Binary file not shown.

@ -36,7 +36,7 @@
"md-editor-v3": "^4.18.1",
"nprogress": "0.2.0",
"pinia": "2.0.22",
"video.js": "^8.17.3",
"video.js": "7.x",
"vue": "^3.2.47",
"vue-cropper": "1.0.3",
"vue-router": "4.1.4",

@ -120,4 +120,12 @@ export function knowledgeProfileScore(data) {
method: "post",
data: data,
});
}
//聚类分析
export function clusterAnalysis2(data) {
return request({
url: "/api/python/clusterAnalysis",
method: "post",
data: data,
});
}

@ -146,3 +146,11 @@ export function timeCountSubmit(data) {
data: data,
});
}
//聚类分析
export function clusterAnalysis(data) {
return request({
url: "/api/python/clusterAnalysis",
method: "post",
data: data,
});
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

@ -0,0 +1,211 @@
<!--
* @Author: qinzhenpen qzp1807@126.com
* @Date: 2024-11-12 16:24:01
* @LastEditors: qinzhenpen qzp1807@126.com
* @LastEditTime: 2024-12-10 14:07:23
* @FilePath: \corporate-finance\src\components\codemirror\index.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
<div class="codemirror">
<pre>
<code id="answer" ref="answer" class="python">
</code>
</pre>
<div class="output" v-if="Result">
<span v-html="Result"></span>
</div>
<!-- <el-button @click="Execution" type="primary">运行</el-button> -->
<!-- <el-button @click="loadTaskInfo" type="primary">清除</el-button> -->
</div>
</template>
<script setup>
import { ref } from "vue"
// import * as caseTraining from "@/api/caseTraining"
const props = defineProps({
code: {
type: String,
default: ""
}
})
const code = ref("")
const Result = ref("")
const answer = ref(null)
const text = ref("")
onMounted(() => {
setTimeout(() => {
loadTaskInfo()
}, 500)
})
function formatPythonCode(code) {
// 使```python
const trimmedCode = code
.replace(/```python\s*/, "")
.replace(/```Python\s*/, "")
.replace(/```/, "")
// 使
const lines = trimmedCode.split("\n")
//
const highlightWords = [
{ word: "print", className: "highlight" },
{ word: "import", className: "highlight" },
{ word: "as", className: "highlight" },
{ word: "from", className: "highlight" },
{ word: "num", className: "highlight-green" },
{ word: "if", className: "highlight-blue" },
{ word: "else", className: "highlight-blue" },
{ word: "str", className: "highlight-blue" }
]
//
const style = document.createElement("style")
style.textContent = `
.highlight {
color: yellow;
}
.highlight-green {
color: lightgreen;
}
.highlight-blue {
color: lightblue;
}
.comment-highlight {
color: #d4d0ab;
font-weight: bold;
}
`
document.head.append(style)
// <li>
const formattedLines = lines
.map((line) => {
let codePart = line
let commentPart = ""
//
const commentIndex = line.indexOf("#")
if (commentIndex !== -1) {
codePart = line.slice(0, commentIndex)
commentPart = line.slice(commentIndex)
}
//
highlightWords.forEach(({ word, className }) => {
const regex = new RegExp(`\\b${word}\\b`, "g")
codePart = codePart.replace(regex, `<span class="${className}">${word}</span>`)
})
if (codePart.includes("___")) {
// ___使<input>
const parts = codePart.split("___")
const inputs = parts
.map((part, index) => {
if (index < parts.length - 1) {
return `${part}<input type="text" style="text-align: center;line-height: 20px;margin: 0 10px;border: none;border-bottom: 1px solid #1e9fff;border-radius: 5px;padding: 0 10px;width: 80px;font-family: inherit;font-size: inherit;font-style: inherit;font-weight: inherit;outline: 0;background:transparent;color:#FF6100">`
}
return part
})
.join("")
return `<li style="white-space: pre-wrap;">${inputs}<span class="comment-highlight">${commentPart}</span></li>`
} else if (commentPart) {
//
return `<li style="white-space: pre-wrap;"><span style="white-space: pre-wrap;">${codePart}</span><span class="comment-highlight">${commentPart}</span></li>`
} else {
if (codePart !== "") {
return `<li style="white-space: pre-wrap;"><span style="white-space: pre-wrap;">${codePart}</span></li>`
}
}
})
.filter(Boolean) // undefined
//
return `<ol style="min-height:100%px;padding: 5px 0;list-style: none; padding-left: 0;width:100%">${formattedLines.join("\n")}</ol>`
}
//
// function Execution() {
// answer.value.querySelectorAll("input").forEach((inputElement, index) => {
// const spanElement = document.createElement("span")
// spanElement.style.color = "#FF6100"
// spanElement.textContent = inputElement.value
// inputElement.replaceWith(spanElement)
// })
// text.value = answer.value.textContent
// caseTraining
// .pythonRun({ code: text.value })
// .then((res) => {
// if (res.data !== null) {
// res.data.forEach((item) => {
// Result.value += `<img src="data:image/png;base64,${item}"/>`
// })
// } else {
// Result.value = res.msg
// }
// })
// .catch((err) => {})
// }
function filterStringWithCommaPrefix(str) {
// split
const parts = str.split(",")
// 使 slice(-1)
return parts.slice(-1)[0]
}
function loadTaskInfo() {
nextTick(() => {
Result.value = ""
answer.value.innerHTML = formatPythonCode(props.code)
})
}
watch(
() => props.code,
(newVal) => {
loadTaskInfo()
}
)
</script>
<style lang='scss' scoped>
.codemirror {
margin-bottom: 20px;
pre{
margin-bottom: -32px;
}
:deep(#answer) {
display: block;
margin: -41px 0px 0px 0px;
font-size: 14px;
ol {
line-height: 10px;
li,
span {
font-family: Source Han Sans CN;
font-weight: 400;
font-size: 14px;
color: #666666;
line-height: 14px;
}
}
}
#answer span {
white-space: pre-wrap;
}
.output {
width: calc(100% - 300px);
padding: 10px;
min-height: 100px;
margin-left: 5px;
box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.1);
margin-bottom: 10px;
//
}
.el-button {
background: url("../../assets/images/xz按钮.png") no-repeat !important;
background-size: 100% 100% !important;
border: none;
min-width: 135px;
min-height: 25px;
}
.el-button:nth-child(3) {
background: url("../../assets/images/xz按钮2.png") no-repeat !important;
background-size: 100% 100% !important;
}
}
</style>

@ -16,8 +16,9 @@ axios.defaults.headers["Content-Type"] = "application/json;charset=utf-8";
const service = axios.create({
// axios中请求配置有baseURL选项表示请求URL公共部分
// baseURL: import.meta.env.VITE_APP_BASE_API,
baseURL: "https://szyx.sztzjy.com:9868/",
// baseURL:'http://192.168.2.13:9868/',
// baseURL: "https://szyx.sztzjy.com:9868/",
baseURL: "http://118.31.7.2:9868/",
// baseURL:'http://192.168.2.2:9868/',
// 超时
timeout: 100000,
});

@ -49,6 +49,9 @@
<div class="left-top" style="margin-top: 50px">
<span>模型参数设置</span>
</div>
<div class="metrics-table">
<el-button @click="codeSetting"></el-button>
</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">
@ -274,9 +277,18 @@
</div>
</template>
</pop-model>
<pop-model :showModel="runResultShow2" title="设置代码" @closePop="closeCode">
<template v-slot:content>
<div>
<codemirror :code="code"></codemirror>
</div>
</template>
</pop-model>
</template>
<script setup>
import codemirror from "@/components/codemirror/index.vue"
import * as portraitModel from "@/api/portraitModel";
import useAlgorithmStore from "@/store/modules/algorithm.js";
const algorithmStore = useAlgorithmStore();
@ -288,6 +300,10 @@ import JSZip from "jszip";
import * as API from "@/api/AI.js";
import { getUserInfo } from "@/utils/auth";
import { onMounted, reactive } from "vue";
const age=ref('')
const income=ref('')
const runResultShow2=ref(false)
const code=ref()
const loading1 = ref(false);
const loading2 = ref(false);
const loading3 = ref(false);
@ -374,7 +390,7 @@ const addData = (myChart, newData, color) => {
//
newData.forEach((dataPoint) => {
currentData.push({
value: [dataPoint.x, dataPoint.y],
value: [dataPoint.age, dataPoint.income],
itemStyle: { color: color },
});
});
@ -388,7 +404,27 @@ const addData = (myChart, newData, color) => {
],
});
};
//
const addData2 = (myChart, newData, color) => {
//
let currentData = myChart.getOption().series[0].data || [];
//
// newData.forEach((dataPoint) => {
currentData.push({
value: [newData[0], newData[1]],
itemStyle: { color: color },
});
// });
//
myChart.setOption({
series: [
{
data: currentData,
},
],
});
};
onMounted(() => {
getList();
optionData()
@ -517,6 +553,10 @@ const headerCellStyle = () => {
color: "#ffffff !important",
};
};
const codeSetting=()=>{
runResultShow2.value=true
console.log(runResultShow2.value);
}
const optionData2 = () => {
if (tableData2.value.length === 0) {
input2.value = "";
@ -540,12 +580,116 @@ const optionData2 = () => {
setTimeout(() => {
loading2.value = false;
}, 500);
}).then(()=>{
age.value=resTable2.value.map(item=>item.age).join(',')
income.value=resTable2.value.map(item=>item.annual_income).join(',')
code.value=`
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
import json
# 模拟输入数据可以根据实际输入动态更改
data = {
'age': [${age.value}],
'income': [${income.value}]
}
# 将字典转换为 DataFrame
df = pd.DataFrame(data)
# 提取特征数组
X = df.values
# 选择聚类的数量和设置最大迭代次数
num_clusters = ___
max_iter = ___ # 设置最大迭代次数
n_init = 10 # 初始化次数
kmeans = KMeans(n_clusters=num_clusters, n_init=n_init, max_iter=max_iter, random_state=0)
# 拟合模型
kmeans.fit(X)
# 获取聚类结果
labels = kmeans.labels_
centroids = kmeans.cluster_centers_
# 记录每次的迭代结果
iterations_per_init = []
for _ in range(n_init):
kmeans = KMeans(n_clusters=num_clusters, n_init=1, max_iter=max_iter, random_state=None) # 随机化每次初始化
kmeans.fit(X)
iterations_per_init.append(kmeans.n_iter_)
# 计算总体迭代次数
total_iterations = sum(iterations_per_init)
# 构建输出每个簇的成员并生成 JSON 格式
clusters_output = {
"data": {} # 初始化一个 Members 字典
}
for i in range(num_clusters):
cluster_members = X[labels == i] # 获取所有成员
member_dicts = [{col: int(member[j]) if isinstance(member[j], np.int64) else member[j] for j, col in enumerate(df.columns)} for member in cluster_members]
# 添加到数据字典中
clusters_output["data"][f"Cluster_{i + 1}"] = {
"Members": member_dicts, # 添加簇的所有成员
"Centroid": [float(c) for c in centroids[i]] # 转换质心为 float以避免可能的整数问题
}
# 添加最大迭代次数和总体迭代次数
clusters_output["maxIterations"] = int(max_iter)
clusters_output["totalIterations"] = int(total_iterations)
# 输出最终结果
output_json = json.dumps(clusters_output, ensure_ascii=False, separators=(',', ': '))
# 按照需求进行格式化输出
formatted_output = output_json.replace('},{', '},\n{') # 簇之间换行
print(formatted_output)
# 可视化聚类结果
plt.figure(figsize=(10, 6))
for i in range(num_clusters):
plt.scatter(X[labels == i, 0], X[labels == i, 1], label=f'Cluster {i + 1}')
# 显示聚类中心并标记坐标
for i, centroid in enumerate(centroids):
plt.scatter(centroid[0], centroid[1], s=300, c='red', label='Centroid ' + str(i + 1), marker='X')
plt.text(centroid[0], centroid[1], f'C{i + 1}: ({centroid[0]:.1f}, {centroid[1]:.1f})', fontsize=12, ha='right')
# 在每个点旁边显示坐标
for idx, point in enumerate(X):
plt.text(point[0], point[1], f'({point[0]}, {point[1]})', fontsize=9, ha='right')
plt.title('K-Means Clustering')
plt.xlabel('Age')
plt.ylabel('Income')
plt.legend()
plt.grid()
plt.show()`
})
.catch(() => {
loading2.value = 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]
input6.value=values[1]
input4.value='K-means'
}
const showChart = ref(false);
//
const iterations=ref(0)
@ -558,10 +702,10 @@ const clusterAnalysisCalculation = () => {
if (input5.value && input6.value && input4.value) {
loading3.value = true;
const sendData = {
k: input5.value,
t: input6.value,
k: input5.value,
userId: JSON.parse(getUserInfo()).userId,
deduplicatedDataList: resTable2.value,
deduplicatedDataList: resTable2.value
};
API.clusterAnalysisPlot(sendData)
.then((res) => {
@ -593,11 +737,19 @@ const clusterAnalysisCalculation = () => {
children.value.push(newItem2);
});
tableData3.value[index].children = children.value;
console.log(tableData3.value);
});
})
.then(() => {
API.clusterAnalysis(sendData).then((res) => {
const sendData2 = {
maxIterations: input6.value,
clusteringFrequency: input5.value,
// userId: JSON.parse(getUserInfo()).userId,
data: {
age: resTable2.value.map(item => item.age),
income: resTable2.value.map(item => item.annual_income)
},
};
API.clusterAnalysis2(sendData2).then((res) => {
myChart.setOption({
series: [
{
@ -612,14 +764,19 @@ const clusterAnalysisCalculation = () => {
},
],
});
Object.keys(res.data.dataSet).forEach((key) => {
const bgColor = getRandomColorHex();
addData(myChart, res.data.dataSet[key], bgColor);
addData(myChart2, res.data.dataSet[key], bgColor);
});
Object.keys(res.data.centroid).forEach((key) => {
addData(myChart2, res.data.centroid[key], "red");
});
const bgColor = getRandomColorHex();
addData(myChart, res.data.data.Cluster_1.members, bgColor)
addData(myChart2, res.data.data.Cluster_2.members, bgColor)
addData2(myChart, res.data.data.Cluster_1.centroid, "red")
addData2(myChart2, res.data.data.Cluster_2.centroid, "red")
// Object.keys(res.data.dataSet).forEach((key) => {
// const bgColor = getRandomColorHex();
// addData(myChart, res.data.dataSet[key], bgColor);
// addData(myChart2, res.data.dataSet[key], bgColor);
// });
// Object.keys(res.data.centroid).forEach((key) => {
// addData(myChart2, res.data.centroid[key], "red");
// });
setTimeout(() => {
loading3.value = false;
}, 500);

Loading…
Cancel
Save