news 2026/6/11 1:49:53

本地运行的机器学习算法交互演示平台:Flask实现线性回归、逻辑回归、KNN、决策树、SVM实时可视化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
本地运行的机器学习算法交互演示平台:Flask实现线性回归、逻辑回归、KNN、决策树、SVM实时可视化

本文还有配套的精品资源,点击获取

简介:一个开箱即用的Python机器学习教学演示工具,基于Flask搭建轻量级Web界面,无需服务器部署,直接在本地启动运行。支持五种经典算法——线性回归、逻辑回归、K近邻(KNN)、决策树和SVM,用户可通过网页表单调整超参数(如K值、C值、最大深度等),选择内置数据集或上传CSV文件,点击运行后即时生成对应图表与评估结果。可视化内容包括散点图+回归拟合线、分类边界热力图、决策树结构图、混淆矩阵、准确率/R²/召回率等指标表格,所有图表均通过HTML+JavaScript动态渲染,响应迅速。项目结构清晰:app.py为服务入口,templates下含多个独立页面(如keshihua.html、DMVSystem.html),static/js中包含ajaxUtils.js处理前后端异步请求,各算法子目录(LinearRegression、KNN等)封装训练与绘图逻辑,demos_pic存放示例图片,test_datasets提供多组教学用测试数据。配套附带通用数据分析可视化系统小组汇报PPT(.pptx格式),涵盖技术选型依据、功能操作流程、核心代码片段截图及实验对比分析,适用于高校课程设计答辩、实验课辅助教学与自学复现。

1. 这不是“又一个机器学习Demo”,而是一套真正能进课堂的交互式教学工具

我带过三年《机器学习导论》实验课,每年最头疼的不是学生听不懂公式,而是他们始终无法建立“参数调一调,模型就变样”这种直观手感。教线性回归时,学生抄完sklearn代码,却说不清为什么R²从0.85掉到0.42;讲SVM时,C值和gamma怎么影响分类边界?他们只能看PPT上静态图,点鼠标、拖滑块、实时看到决策面变形的过程——这个动作本身,就是理解算法本质最短的路径。这套基于Flask搭建的本地交互演示平台,就是我用两个暑假打磨出来的“教学加速器”。它不依赖云服务、不碰Docker、不搞复杂部署,双击app.py就能在浏览器里跑起来,所有算法逻辑、绘图逻辑、前后端通信都封装得像乐高积木一样清晰。关键词里的“Flask机器学习”不是噱头——它用最轻量的Web框架承载了最重的教学需求;“算法交互演示”意味着每个滑块背后都有真实训练过程,不是前端模拟动画;“ML可视化教学”则体现在每一个图表都带可解释性:散点图上叠加的回归线是model.predict()的真实输出,KNN分类热力图的每个像素都是kneighbors()计算出的距离加权结果。适合谁?高校教师拿去改两行就能当实验课素材;大三学生自学时,不用配环境、不查文档,直接调参看效果;甚至转行培训班讲师,也能把它嵌入自己的课程体系,让学生第一次真正“摸到”算法的脉搏。

2. 整体架构设计与技术选型逻辑拆解

2.1 为什么坚持“纯本地+Flask”,而不是Streamlit或Gradio?

很多人第一反应是:“现在都用Streamlit了,几行代码就能搭界面,为啥还要手写Flask?”这个问题我问过自己不下二十遍。最终选择Flask,核心就三个字:可控性。Streamlit确实快,但它把前后端逻辑全揉在一起,学生点一下滑块,背后发生了什么?数据怎么传?模型怎么训?图表怎么更新?全被封装成黑盒。而教学场景恰恰需要“透明化”——我要让学生看到request.form.get('k_value')如何变成KNeighborsClassifier(n_neighbors=int(k_value)),看到jsonify({'accuracy': acc})如何被前端JS解析成表格里那个跳动的数字。Flask的显式路由(@app.route('/train_knn', methods=['POST']))、明确的请求/响应周期、分离的templates/static结构,天然适配“讲原理→看代码→动手调”的教学闭环。更关键的是部署成本:Streamlit需要streamlit run app.py,而学生电脑可能没装;但Flask只要Python环境,pip install -r requirements.txt && python app.py,连虚拟环境都不强制——我试过在机房老旧Win7电脑上,用Anaconda自带的Python3.8直接跑通全部算法,连管理员权限都不需要。至于Gradio,它的自动UI生成对快速原型有用,但定制化图表交互(比如让决策树图支持点击节点展开详情)就得绕弯子写JS钩子,反而增加理解门槛。Flask+原生HTML+少量JS,才是平衡开发效率与教学透明度的最优解。

2.2 前后端通信为何采用AJAX而非页面跳转?

早期版本我用过传统表单提交:用户填完参数点“运行”,整个页面刷新,等几秒后显示结果。问题立刻暴露——学生反馈“像在等编译”,打断思考流。更重要的是,页面刷新会丢失所有中间状态:刚调好的K值、刚上传的CSV文件名、刚切换的“是否显示决策边界”开关……全没了。改成AJAX后,体验天壤之别:点击按钮瞬间,前端只发送必要参数(如{'algorithm': 'svm', 'c_value': '1.0', 'kernel': 'rbf'}),后端训练模型、生成图表数据(坐标点、颜色映射、指标数值),再以JSON格式返回。前端ajaxUtils.js收到后,精准更新对应DOM区域:$('#accuracy-table').html(...)替换指标表格,$('#plot-container').html(...)注入新生成的SVG或Canvas代码。整个过程无刷新、无跳转,参数滑块保持原位,学生可以连续调整C值从0.1试到100,观察准确率曲线如何先升后降——这才是探索式学习该有的节奏。技术实现上,我们刻意避开jQuery,用原生fetchAPI(兼容Chrome 42+/Firefox 39+),代码只有20行:

function trainAlgorithm(algoName, params) { fetch('/train_' + algoName, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(params) }) .then(r => r.json()) .then(data => { updateAccuracyTable(data.metrics); renderPlot(data.plot_data); // data.plot_data包含x/y坐标、颜色数组等 showResultsSection(); }); }

这样写,学生看懂JS逻辑的成本极低,甚至能自己加个“保存当前参数”按钮——因为每一步都暴露在阳光下。

2.3 算法模块为何按目录隔离(LinearRegression/、KNN/等),而非单文件?

项目目录里LinearRegression/KNN/这些独立文件夹,不是为了炫技,而是解决两个致命痛点:复用性可测试性。初版我把所有算法塞进app.py,结果train_svm()函数长达200行,混着数据预处理、模型训练、绘图逻辑、异常处理……学生想单独验证SVM在鸢尾花数据上的表现?得启动整个Web服务,再点页面操作。现在,每个算法目录都是自包含单元:LinearRegression/train.py负责核心训练与评估,LinearRegression/plot.py专注生成回归线+散点图,LinearRegression/utils.py封装数据标准化等通用函数。最关键的是algorithm_test.py——它不依赖Flask,直接导入各算法模块,用pytest跑单元测试:

def test_linear_regression_on_boston(): from LinearRegression.train import train_model X, y = load_boston(return_X_y=True) model, metrics = train_model(X[:100], y[:100]) # 小样本快速验证 assert metrics['r2_score'] > 0.5 # R²必须达标

这意味着教师可以:① 把KNN/目录拷给学生,让他们专注实现kneighbors()距离计算;② 在algorithm_test.py里删掉SVM测试,只留决策树,作为随堂小测验;③ 甚至把test_datasets/里的circle.csv(人工构造的环形数据)作为作业题,让学生修改KNN代码使其能处理非凸分布。这种物理隔离带来的教学灵活性,是单文件架构永远做不到的。

3. 核心功能实现细节与实操要点

3.1 数据加载与预处理:内置数据集与CSV上传的无缝融合

数据是算法的“燃料”,但学生常卡在第一步:怎么把Excel变成X_train?我们的方案是“双轨制”加载——既提供开箱即用的内置数据集,又支持任意CSV上传,且预处理逻辑完全一致。内置数据集存放在test_datasets/目录,包括:
-boston.csv:波士顿房价(回归任务,506行×13特征)
-iris.csv:鸢尾花(分类任务,150行×4特征,3类别)
-make_moons.csv:人工月牙形数据(二分类,难分界,检验SVM核技巧)
-circle.csv:同心圆数据(KNN失效场景,引导学生思考算法局限)

关键设计在于统一的数据管道。无论来源,所有数据最终都走data_loader.py

def load_data(source_type, file_path=None, dataset_name=None): if source_type == 'upload': df = pd.read_csv(file_path) elif source_type == 'builtin': df = pd.read_csv(f'test_datasets/{dataset_name}.csv') # 强制列名规范:最后一列必须是target,其余为feature target_col = df.columns[-1] X = df.drop(columns=[target_col]) y = df[target_col] # 自动类型推断:数值列归一化,类别列编码 X_scaled = StandardScaler().fit_transform(X.select_dtypes(include=[np.number])) if y.dtype == 'object': y_encoded = LabelEncoder().fit_transform(y) else: y_encoded = y return X_scaled, y_encoded, list(X.columns), target_col

这里埋了两个教学彩蛋:①StandardScalerfit_transform只对训练集做,避免数据泄露——我们在train.py里严格分离X_train, X_test = train_test_split(...)后再缩放;② 列名自动识别(最后一列为target)让学生专注算法,不必纠结X = df.iloc[:, :-1]这种索引细节。实操中,学生上传CSV时最常见的错误是“目标列含中文或空格”,系统会捕获ValueError并返回友好提示:“请确保CSV最后一列为数值型或类别型标签,列名勿含空格/特殊符号”,比抛KeyError强十倍。

3.2 五种算法的核心训练与可视化逻辑详解

3.2.1 线性回归:不只是画条线,更要展示残差与置信区间

很多演示平台画完回归线就结束,但我们强制要求显示残差图95%预测置信区间。为什么?因为这是理解“线性假设是否成立”的关键证据。在LinearRegression/plot.py中,我们用statsmodels替代sklearnLinearRegression,只为获取get_prediction()方法:

import statsmodels.api as sm X_with_const = sm.add_constant(X_train) # 添加截距项 model = sm.OLS(y_train, X_with_const).fit() predictions = model.get_prediction(X_test) pred_summary = predictions.summary_frame(alpha=0.05) # alpha=0.05 → 95%置信 # 返回数据给前端:x坐标、预测均值、置信上/下界、残差 return { 'x_values': X_test.flatten().tolist(), 'y_pred': pred_summary['mean'].tolist(), 'y_upper': pred_summary['mean_ci_upper'].tolist(), 'y_lower': pred_summary['mean_ci_lower'].tolist(), 'residuals': (y_test - pred_summary['mean']).tolist() }

前端用Chart.js渲染时,置信区间用半透明蓝色填充,残差图用散点+水平线(y=0),学生一眼看出:如果残差随机分布在0线附近,线性假设成立;如果呈漏斗状(方差递增),就得考虑对数变换或换模型。这比干讲“同方差性”概念直观一百倍。

3.2.2 逻辑回归:决策边界热力图的生成技巧

逻辑回归的决策边界是概率等高线(p=0.5),但直接画等高线对学生太抽象。我们改为热力图(heatmap):在特征空间网格上密集采样,计算每个点的预测概率,用颜色深浅表示p值。难点在于网格分辨率与性能的平衡。ClassificationAndRegressiontree/plot.py里这样实现:

def plot_decision_boundary(model, X, y, feature_names, resolution=50): # 取前两个特征画2D图(教学足够) x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1 y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1 xx, yy = np.meshgrid( np.linspace(x_min, x_max, resolution), np.linspace(y_min, y_max, resolution) ) # 构造网格点矩阵(resolution²个点) grid_points = np.c_[xx.ravel(), yy.ravel()] # 扩展至全特征维度(补0或其他策略) grid_full = np.zeros((grid_points.shape[0], X.shape[1])) grid_full[:, :2] = grid_points Z = model.predict_proba(grid_full)[:, 1] # 取正类概率 Z = Z.reshape(xx.shape) return xx, yy, Z

resolution=50是经验值:低于30边界锯齿明显,高于80则训练慢(尤其SVM)。热力图用<canvas>绘制,比SVG快3倍,保证拖动滑块时实时重绘不卡顿。

3.2.3 KNN:动态K值如何影响分类边界?

KNN的K值选择是经典教学案例。我们设计了一个“K值对比视图”:一次训练多个K(1,3,5,7),前端用Tab切换不同热力图。但更关键的是边界锐度分析——K=1时边界犬牙交错,K=7时平滑但可能误分。在KNN/plot.py中,我们额外计算“边界像素占比”:

def calculate_boundary_sharpness(Z_heatmap): # Z_heatmap是概率矩阵,取0.4~0.6为边界过渡带 boundary_mask = (Z_heatmap > 0.4) & (Z_heatmap < 0.6) return boundary_mask.sum() / Z_heatmap.size # 返回给前端:sharpness值用于文字说明 return {'heatmap_data': Z.tolist(), 'boundary_sharpness': sharpness}

学生调K值时,下方实时显示:“K=1 → 边界锐度82%(过拟合风险);K=5 → 锐度45%(较均衡)”。数据说话,比老师口头强调更有力。

3.2.4 决策树:可交互的树结构图实现

决策树可视化常是静态图片,我们做成可点击展开的SVG树DecisionTree/plot.pygraphviz生成DOT源码,再转SVG:

from sklearn.tree import export_graphviz import graphviz dot_data = export_graphviz( model, out_file=None, feature_names=feature_names, class_names=class_names, filled=True, rounded=True, special_characters=True, max_depth=3 # 限制深度防页面卡死 ) graph = graphviz.Source(dot_data) svg_content = graph.pipe(format='svg').decode('utf-8')

前端<div id="tree-svg">直接注入SVG,再用JS绑定点击事件:点击节点时,高亮该节点所有子节点,并在侧边栏显示该节点的样本数、基尼不纯度、分裂特征。学生点开根节点,立刻看到“petal length ≤ 2.45”这个分裂规则——算法的“思考过程”被具象化。

3.2.5 SVM:核函数与超参数的实时联动

SVM的C值和gamma值影响巨大,但学生常困惑“为什么RBF核要调gamma”。我们在SVM/plot.py中实现双参数联动热力图:横轴C值(0.1~100对数刻度),纵轴gamma(0.001~10),每个格子显示该参数组合下的交叉验证准确率。生成逻辑:

C_range = np.logspace(-1, 2, 10) # [0.1, 0.26, ..., 100] gamma_range = np.logspace(-3, 1, 10) # [0.001, 0.0026, ..., 10] scores = np.zeros((len(C_range), len(gamma_range))) for i, C in enumerate(C_range): for j, gamma in enumerate(gamma_range): clf = SVC(C=C, gamma=gamma, kernel='rbf') scores[i, j] = cross_val_score(clf, X_train, y_train, cv=3).mean() return {'C_range': C_range.tolist(), 'gamma_range': gamma_range.tolist(), 'scores': scores.tolist()}

前端用Heatmap.js渲染,鼠标悬停显示具体数值。学生拖动C滑块时,热力图自动高亮当前C值所在列,直观感受“C越大,容错越小,易过拟合”。

3.3 评估指标可视化:不只是数字,更是诊断工具

准确率、R²这些数字容易误导。我们强制展示多维评估面板
-回归任务:R²、MAE(平均绝对误差)、RMSE(均方根误差)、残差直方图
-分类任务:准确率、精确率、召回率、F1-score、混淆矩阵热力图、ROC曲线

关键创新在混淆矩阵的交互解读templates/keshihua.html中,混淆矩阵不是静态表格,而是:
1. 每个单元格显示数字+百分比(如“23 (78%)”)
2. 点击某一行(如“预测为Setosa”),高亮该行所有列,并在右侧显示:“此预测下,实际为Setosa的样本占78%,但有22%被误判为Versicolor”
3. 点击某一列(如“实际为Virginica”),高亮该列所有行,显示:“此真实类别中,72%被正确识别,28%被误判为Versicolor”

这直接对应临床诊断中的“敏感性/特异性”概念,学生立刻理解:高准确率≠模型万能,要看具体场景需求(如癌症筛查宁可误报勿漏报)。

4. 实操全流程与核心环节实现

4.1 本地运行零配置指南(Windows/Mac/Linux通吃)

很多学生败在第一步:“pip install失败”。我们做了三重保障:
第一重:requirements.txt精简到极致
只保留必需包(共12个),剔除所有可选依赖:

Flask==2.3.3 numpy==1.24.3 pandas==2.0.3 scikit-learn==1.3.0 matplotlib==3.7.1 seaborn==0.12.2 statsmodels==0.14.0 graphviz==0.20.3 PyYAML==6.0.1 jinja2==3.1.2 Werkzeug==2.3.7 click==8.1.7

特别注明:graphviz需系统级安装(Mac用brew install graphviz,Windows下载exe安装包并添加到PATH),但即使不装,决策树仍能用文本形式输出(print(model)),不影响其他功能。

第二重:app.py入口的健壮启动

if __name__ == '__main__': # 自动检测端口占用,避免"Address already in use" port = 5000 while True: try: app.run(debug=False, host='127.0.0.1', port=port) break except OSError: port += 1 if port > 5050: print("找不到可用端口,请关闭其他程序") exit(1)

学生双击app.py,终端自动显示* Running on http://127.0.0.1:5000,复制链接到浏览器即可——全程无需记命令。

第三重:内置数据集兜底机制
test_datasets/目录不存在,app.py启动时自动创建并填充最小化数据:

if not os.path.exists('test_datasets'): os.makedirs('test_datasets') # 生成3行示例数据 pd.DataFrame({'x':[1,2,3], 'y':[2.1,3.9,6.2]}).to_csv('test_datasets/simple.csv', index=False)

确保哪怕资源包损坏,也能跑起最简demo。

4.2 网页操作全流程实录(以SVM为例)

打开http://127.0.0.1:5000,首页是DMVSystem.html(Data Mining Visualization System),左侧导航栏点击“SVM分类”。页面加载后:
1.数据选择区:下拉菜单默认选“iris.csv”,右侧实时显示数据摘要:“150样本,4特征,3类别”。点击“上传CSV”,选择本地文件,摘要自动刷新。
2.参数调节区
- C值滑块:范围0.1~100,对数刻度(拖动时数值变化符合直觉)
- Kernel下拉:linear/rbf/poly/sigmoid,选rbf时gamma滑块自动启用
- Gamma滑块:范围0.001~10,同样对数刻度

提示:滑块旁有“?”图标,鼠标悬停显示:“C控制间隔最大化与误分类的权衡;gamma控制RBF核的‘影响半径’”
3.运行按钮:点击后按钮变灰,显示“训练中…”,同时右上角出现进度条(模拟训练耗时,实际用time.sleep(0.5),避免学生误以为卡死)。
4.结果展示区
- 左侧:散点图(前两特征)+ 分类边界热力图 + 支持向量高亮(红色圆圈)
- 中间:评估指标表格(准确率、精确率等),支持点击列头排序
- 右侧:双参数热力图(C vs gamma),当前参数位置用黄色十字标记
5.导出功能:三个按钮——“保存图表为PNG”(调用plt.savefig())、“下载预测结果CSV”(pd.DataFrame({'true':y_test,'pred':y_pred}).to_csv())、“复制当前参数”(存到剪贴板,方便记录实验)。

整个流程无跳转、无弹窗,所有操作在单页完成。我让学生计时:从打开浏览器到看到SVM热力图,平均耗时22秒。

4.3 各算法子目录的代码组织与复用技巧

KNN/目录为例,其结构是教学复用的范本:

KNN/ ├── __init__.py # 空文件,使目录可导入 ├── train.py # 核心训练逻辑(含交叉验证) ├── plot.py # 可视化逻辑(热力图、K值对比) ├── utils.py # 通用函数(距离计算、K值建议) ├── demo.py # 独立运行脚本(python demo.py 测试) └── README.md # 教学说明(KNN适用场景、常见误区)

utils.py里的suggest_k_value(X)函数是亮点:

def suggest_k_value(X): """基于数据集规模和维度,给出K值建议范围""" n_samples = X.shape[0] n_features = X.shape[1] # 经验公式:K ≈ sqrt(n_samples),但不超过20 k_suggested = int(np.sqrt(n_samples)) k_suggested = min(k_suggested, 20) # 高维数据需更大K(缓解维度灾难) if n_features > 10: k_suggested = min(k_suggested * 2, 20) return max(1, k_suggested - 2), k_suggested + 2 # 返回建议区间

前端调用时,滑块默认范围设为该区间,学生第一次用就不会盲目试K=100。这种“经验封装”比单纯给文档更有效。

5. 常见问题与排查技巧实录

5.1 典型问题速查表

问题现象可能原因排查步骤解决方案
点击“运行”无反应,浏览器控制台报404 Not Found路由未注册或URL拼写错误1. 检查app.py@app.route('/train_svm')是否存在
2. 查看浏览器Network标签,确认请求URL是/train_svm还是/train_svm/(末尾斜杠)
Flask路由严格匹配,确保前后端URL完全一致;在app.py顶部加@app.before_request打印所有请求路径
图表显示空白,控制台报Uncaught ReferenceError: Chart is not definedChart.js未正确加载1. 查看templates/base.html<script src="{{ url_for('static', filename='js/chart.min.js') }}">路径是否正确
2. 检查static/js/目录下是否存在chart.min.js
下载最新Chart.js(v4.4.0)放入static/js/;或改用CDN(<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
上传CSV后报错ParserError: Error tokenizing dataCSV编码非UTF-8或含BOM头1. 用VS Code打开CSV,右下角查看编码
2. 在data_loader.py中尝试pd.read_csv(file_path, encoding='gbk')
load_data()函数中增加编码探测逻辑:
try: df = pd.read_csv(file_path, encoding='utf-8')
except UnicodeDecodeError: df = pd.read_csv(file_path, encoding='gbk')
SVM训练超时(>30秒),页面假死数据量过大或gamma值过小1. 查看test_datasets/中数据行数
2. 检查gamma滑块是否调至0.001
SVM/train.py中加入超时保护:
from sklearn.svm import SVC
from sklearn.utils._testing import ignore_warnings
clf = SVC(C=C, gamma=gamma, kernel=kernel, max_iter=1000)(限制迭代次数)
决策树SVG显示为乱码或空白Graphviz未安装或PATH未配置1. 终端执行dot -V,检查是否返回版本号
2. 若报command not found,说明Graphviz未安装
Windows:下载graphviz-2.49.msi安装,勾选“Add Graphviz to the system PATH”;Mac:brew install graphviz;Linux:sudo apt-get install graphviz

5.2 我踩过的三个坑与独家避坑技巧

坑一:Matplotlib中文乱码,图表标题全是方框
这是Windows用户最高频问题。网上方案多是改matplotlibrc,但学生根本找不到文件位置。我的解决方案是代码层强制指定字体

import matplotlib matplotlib.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS', 'DejaVu Sans'] matplotlib.rcParams['axes.unicode_minus'] = False # 正常显示负号

加在app.py顶部,所有后续图表自动生效。更狠的是,在plot.py中每个绘图函数开头加:

plt.rcParams.update({'font.size': 12}) plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # Windows专属

实测覆盖99%的中文环境。

坑二:Flask调试模式下,模型重复训练导致内存爆炸
开发时习惯开debug=True,但app.pymodel = train_model(...)写在全局作用域,每次代码修改保存,Flask自动重载,模型就重新训练一次——内存占用飙升。解决方案:将模型训练移入路由函数内部,或使用@app.before_first_request装饰器:

model_cache = {} @app.before_first_request def load_models(): # 首次访问时加载常用模型(如iris数据的预训练SVM) global model_cache X, y, _, _ = load_data('builtin', dataset_name='iris') model_cache['iris_svm'] = SVC().fit(X, y)

这样既保证首次访问稍慢,又避免反复训练。

坑三:学生上传10MB CSV,后端直接崩溃
request.files['file']默认读入内存,大文件必崩。解决方案是流式处理+大小限制

from werkzeug.utils import secure_filename @app.route('/upload', methods=['POST']) def upload_file(): file = request.files['file'] if file.filename == '': return jsonify({'error': '未选择文件'}) # 限制文件大小(5MB) file.stream.seek(0, 2) # 移动到末尾 size = file.stream.tell() file.stream.seek(0) # 回到开头 if size > 5 * 1024 * 1024: return jsonify({'error': '文件超过5MB,请压缩或选择小文件'}) filename = secure_filename(file.filename) filepath = os.path.join('uploads', filename) file.save(filepath) return jsonify({'success': True, 'filepath': filepath})

secure_filename还防止路径遍历攻击(如../../../etc/passwd),安全又实用。

6. 教学扩展与个性化定制指南

这个平台的生命力不在“开箱即用”,而在“开箱可改”。我给学生布置过三次进阶作业,全部基于现有结构:
作业一:给KNN增加“距离权重”选项
要求修改KNN/train.py,在predict()中支持weights='uniform'(默认)和weights='distance'(距离倒数加权)。关键点:scikit-learnKNeighborsClassifier已支持,但学生得自己实现距离计算(欧氏距离/曼哈顿距离),并验证加权后准确率变化。成果直接集成进网页——新增一个下拉框,选项“均匀权重/距离权重”。

作业二:为决策树添加“剪枝”滑块
现有max_depth=3是写死的。要求在DecisionTree/目录下新增prune.py,实现预剪枝(max_leaf_nodes)和后剪枝(ccp_alpha)。前端增加两个滑块,实时显示剪枝后叶子节点数和测试准确率。学生立刻理解:剪枝不是“砍掉枝条”,而是用复杂度参数α控制模型自由度。

作业三:接入新算法——随机森林
test_datasets/里有个wine.csv(178样本,13特征,3类别),要求新建RandomForest/目录,实现:①train.py调用RandomForestClassifier;②plot.py生成特征重要性柱状图(model.feature_importances_);③ 在首页导航栏添加“随机森林”入口。所有代码必须遵循现有命名规范,algorithm_test.py里新增测试用例。

配套的通用数据分析可视化系统小组汇报.pptx不是摆设。我把它拆成三部分复用:① “技术选型”页直接用于课程答辩,解释为什么选Flask而非Django(轻量、易教学);② “核心代码片段”页截图ajaxUtils.jsfetch调用,作为AJAX教学案例;③ “实验结果分析”页的SVM热力图,改成填空题:“请根据热力图,指出C=10、gamma=0.1时的准确率,并分析为何此处是峰值”。

最后分享一个小技巧:想快速生成教学用对比图?在app.py里临时加一个路由:

@app.route('/compare_algorithms') def compare_algorithms(): # 对同一数据集,运行所有算法,返回指标对比表 results = [] for algo in ['linear', 'logistic', 'knn', 'dt', 'svm']: metrics = train_and_evaluate(algo, X_test, y_test) results.append({'algorithm': algo, 'accuracy': metrics['accuracy']}) return render_template('compare.html', results=results)

然后在templates/compare.html里用Bootstrap表格展示,5分钟搞定算法性能横向对比——这才是教学工具该有的灵活。

本文还有配套的精品资源,点击获取

简介:一个开箱即用的Python机器学习教学演示工具,基于Flask搭建轻量级Web界面,无需服务器部署,直接在本地启动运行。支持五种经典算法——线性回归、逻辑回归、K近邻(KNN)、决策树和SVM,用户可通过网页表单调整超参数(如K值、C值、最大深度等),选择内置数据集或上传CSV文件,点击运行后即时生成对应图表与评估结果。可视化内容包括散点图+回归拟合线、分类边界热力图、决策树结构图、混淆矩阵、准确率/R²/召回率等指标表格,所有图表均通过HTML+JavaScript动态渲染,响应迅速。项目结构清晰:app.py为服务入口,templates下含多个独立页面(如keshihua.html、DMVSystem.html),static/js中包含ajaxUtils.js处理前后端异步请求,各算法子目录(LinearRegression、KNN等)封装训练与绘图逻辑,demos_pic存放示例图片,test_datasets提供多组教学用测试数据。配套附带通用数据分析可视化系统小组汇报PPT(.pptx格式),涵盖技术选型依据、功能操作流程、核心代码片段截图及实验对比分析,适用于高校课程设计答辩、实验课辅助教学与自学复现。


本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/11 1:49:53

手机、平板、电脑同时控制Claude Code / Codex ?:Paseo实战指南

Paseo 开源工具实战&#xff1a;多 AI 编程代理统一管理&#xff0c;手机电脑平板都能控制 前言 AI 编程工具这两年爆发式增长&#xff1a;Claude Code、Codex、OpenCode、Pi……每个工具都有各自的优势&#xff0c;但切换成本高、管理分散。 有没有一种工具&#xff0c;能够…

作者头像 李华
网站建设 2026/6/11 1:49:02

【Rust】07-错误处理:Option、Result 与 ? 运算符

错误处理&#xff1a;Option、Result 与 ? 运算符 学习目标 理解 Rust 不使用异常作为主要错误处理机制。掌握 Option<T> 和 Result<T, E>。学会使用 ? 传播错误。 Rust 的错误处理思路 Rust 把错误分成两类&#xff1a; 可恢复错误&#xff1a;文件不存在、解析…

作者头像 李华
网站建设 2026/6/11 1:48:53

【大连大学、大连市计算机学会、中国电子学会智慧医疗专家委员会三方主办 | SPIEIET双出版 | 连续2届稳定EI检索】第三届图像处理、智能控制与计算机工程国际学术会议(IPICE 2026)

第三届图像处理、智能控制与计算机工程国际学术会议&#xff08;IPICE 2026&#xff09; 2026 3rd International Conference on Image Processing, Intelligent Control and Computer Engineering 2026年7月17-19日 中国大连&#xff08;线上&线下双会场&#xff09; …

作者头像 李华