AI数学基础(三):概率与统计,Java实现均值/方差/协方差计算
本文介绍了概率统计在AI系统中的重要性,重点讲解了如何用Java实现基础统计量的计算及其应用场景。主要内容包括: 统计量的重要性:均值、方差、标准差和协方差是感知数据变化的关键指标,能帮助发现模型漂移、特征异常等问题。 Java实现: 单变量统计:实现了均值、方差和标准差的计算方法 双变量统计:实现了协方差计算,用于分析特征相关性 实战应用: 从KES数据库读取特征指标数据 构建简单的统计过程控制
AI数学基础(三):概率与统计 —— Java 实现均值/方差/协方差计算
——别让“平均值”掩盖了数据的真实波动
大家好,我是那个总在监控图表里看标准差、又在 A/B 测试报告里算 p 值的老架构。今天不聊神经网络,也不谈梯度下降——我们回到 AI 的另一块基石:
当你从电科金仓 KingbaseES(KES)中读出一组用户点击率、响应延迟或 embedding 范数,除了看“平均值”,你还该看什么?
很多人汇报:“本周平均点击率 5.2%”,然后结束。
但如果你不知道这组数据的方差有多大,就不知道这个“5.2%”是稳定表现,还是由少数极端值拉高的假象。
在 AI 工程中,概率与统计不是理论课,而是决策的依据。模型是否漂移?特征是否有效?实验是否显著?答案都在数据的分布里。
今天我们就用 Java,手写均值、方差、协方差的实现,并展示如何用它们构建一个实时特征健康度监控系统。
一、为什么统计量对 AI 至关重要?
AI 系统不是静态的,它活在动态数据流中。而统计量,是你感知“变化”的眼睛:
- 均值(Mean):中心趋势;
- 方差(Variance):波动程度;
- 协方差(Covariance):特征间关联性;
- 标准差(StdDev):异常检测阈值。
举个真实场景:某银行用 KES 存储用户交易 embedding。某天模型效果突降,排查发现:embedding 的 L2 范数均值未变,但方差飙升——说明新数据分布混乱,可能因埋点 bug 引入噪声。
而这一切,只需几行统计代码就能预警。
二、Java 实现:从单变量到多变量
1. 单变量统计:均值与方差
public class UnivariateStats {
public static double mean(double[] data) {
return Arrays.stream(data).average().orElse(0.0);
}
// 样本方差(分母 n-1)
public static double variance(double[] data) {
if (data.length < 2) return 0.0;
double mean = mean(data);
double sum = Arrays.stream(data)
.map(x -> (x - mean) * (x - mean))
.sum();
return sum / (data.length - 1);
}
public static double stdDev(double[] data) {
return Math.sqrt(variance(data));
}
}
✅ 使用
double而非float,避免精度损失(尤其在方差计算中)。
2. 双变量统计:协方差
协方差衡量两个变量是否“同向变化”。正值表示正相关,负值表示负相关。
public class BivariateStats {
public static double covariance(double[] x, double[] y) {
if (x.length != y.length || x.length < 2) {
throw new IllegalArgumentException("维度不匹配");
}
double meanX = UnivariateStats.mean(x);
double meanY = UnivariateStats.mean(y);
double sum = 0.0;
for (int i = 0; i < x.length; i++) {
sum += (x[i] - meanX) * (y[i] - meanY);
}
return sum / (x.length - 1); // 样本协方差
}
}
📌 应用:判断“用户活跃度”与“embedding 范数”是否相关。若协方差接近 0,说明范数无信息量,可考虑归一化。
三、实战:从 KES 读取特征指标,计算健康度
假设我们在 KES 中有一张表,记录每日用户 embedding 的统计信息:
CREATE TABLE ai_monitor.embedding_stats (
dt DATE PRIMARY KEY,
user_count INT,
mean_norm REAL,
std_norm REAL,
min_norm REAL,
max_norm REAL
);
步骤 1:用 Java 拉取最近 30 天数据
public List<EmbeddingStat> loadRecentStats() {
String sql = """
SELECT dt, mean_norm, std_norm
FROM ai_monitor.embedding_stats
WHERE dt >= CURRENT_DATE - INTERVAL '30 days'
ORDER BY dt
""";
List<EmbeddingStat> stats = new ArrayList<>();
try (Connection conn = KESDataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
stats.add(new EmbeddingStat(
rs.getDate("dt").toLocalDate(),
rs.getDouble("mean_norm"),
rs.getDouble("std_norm")
));
}
} catch (SQLException e) {
throw new RuntimeException("加载统计失败", e);
}
return stats;
}
🔗 驱动请从 电科金仓官网下载,确保兼容
REAL类型。
步骤 2:检测异常波动
public void checkAnomaly() {
List<EmbeddingStat> stats = loadRecentStats();
if (stats.size() < 7) return;
// 提取最近 7 天的标准差
double[] recentStd = stats.stream()
.skip(stats.size() - 7)
.mapToDouble(EmbeddingStat::stdNorm)
.toArray();
// 计算历史(前23天)标准差的均值和标准差
double[] historyStd = stats.stream()
.limit(stats.size() - 7)
.mapToDouble(EmbeddingStat::stdNorm)
.toArray();
double histMean = UnivariateStats.mean(historyStd);
double histStdDev = UnivariateStats.stdDev(historyStd);
// 当前均值(最近7天)
double currentMean = UnivariateStats.mean(recentStd);
// Z-Score > 2 视为异常
double zScore = (currentMean - histMean) / histStdDev;
if (Math.abs(zScore) > 2.0) {
alertService.sendAlert(
"Embedding 范数波动异常!Z-Score = " + String.format("%.2f", zScore)
);
}
}
✅ 这就是一个简单的 统计过程控制(SPC) 系统,无需机器学习,仅靠基础统计即可实现。
四、进阶:协方差矩阵与特征相关性分析
在多维特征场景中,我们常需计算协方差矩阵,用于 PCA 降维或特征选择。
// 输入:n 个样本,每个样本 m 维
// 输出:m x m 协方差矩阵
public static double[][] covarianceMatrix(double[][] data) {
int n = data.length; // 样本数
int m = data[0].length; // 特征数
// 计算每列均值
double[] means = new double[m];
for (int j = 0; j < m; j++) {
double sum = 0;
for (int i = 0; i < n; i++) {
sum += data[i][j];
}
means[j] = sum / n;
}
// 计算协方差矩阵
double[][] cov = new double[m][m];
for (int i = 0; i < m; i++) {
for (int j = 0; j <= i; j++) {
double sum = 0;
for (int k = 0; k < n; k++) {
sum += (data[k][i] - means[i]) * (data[k][j] - means[j]);
}
cov[i][j] = cov[j][i] = sum / (n - 1);
}
}
return cov;
}
💡 应用:若两个特征协方差接近 0,可考虑删除其一,降低模型复杂度。
五、与 KES 协同:用 SQL 预聚合,减少 Java 负载
其实,很多统计量 KES 本身就能高效计算:
-- 直接在数据库计算均值、方差
SELECT
AVG(l2_norm) AS mean_norm,
STDDEV_SAMP(l2_norm) AS std_norm
FROM ai_features.user_embedding;
这样,Java 只需处理聚合结果,而非原始百万级数据。
合理分工:
- KES:做大规模聚合(AVG, STDDEV, CORR);
- Java:做逻辑判断、告警、模型集成。
结语:统计思维,是 AI 工程师的第二直觉
AI 不只是“预测未来”,更是“理解现在”。
而理解现在的工具,就是概率与统计。
当你能从 KES 的一行 SQL 或 Java 的一段统计代码中,看出数据的健康与否、特征的有效与否——你就拥有了比模型更底层的洞察力。
下一期,我们会讲:AI数学基础(四):优化理论入门 —— 梯度下降的 Java 实现与收敛分析。
敬请期待。
—— 一位相信“不懂统计的 AI 工程师,就像不会看仪表盘的飞行员”的架构师
更多推荐


所有评论(0)