自相关计算异常排查:C#代码与Python/R结果不符的修复方案
修复C#自相关计算代码问题
问题背景
输入数据:[1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 3.33]
Python和R代码计算该数据的自相关结果一致,但现有C#代码输出结果明显异常,需修复。
异常原因分析
- 误用Pearson相关系数:原代码使用
Correlation.Pearson计算滞后序列与原序列的相关系数,但标准自相关计算是基于整个数据集的均值和方差进行归一化,而Pearson系数是用两个子序列各自的均值和方差,导致结果偏差。 - 阈值过滤不合理:原
AutoCorrelationPoints方法中的阈值thresholdMin = 0.0001会过滤掉所有负数的自相关值,导致输出结果缺失大部分正确值。 - 循环起始lag错误:原代码从
lag=0开始计算,但我们需要的是lag=1到lag=n-1的自相关结果(lag=0时自相关系数恒为1)。
修复后的C#代码
using System; using System.Collections.Generic; using System.Linq; namespace AutoCorrUsingMathNet { public class Statistics { private List<double> data_; private double dataMean_; private double dataVarianceSum_; // 存储整个数据集的离均差平方和,避免重复计算 public Statistics(List<double> data) { if (data == null || !data.Any()) throw new ArgumentException("数据不能为空或null", nameof(data)); data_ = data; // 提前计算整个数据集的均值和离均差平方和 dataMean_ = data.Average(); dataVarianceSum_ = data.Sum(x => Math.Pow(x - dataMean_, 2)); } public double AutocorrelationCoeff(int lag) { if (lag >= data_.Count || lag < 0) throw new ArgumentException("滞后值超出范围", nameof(lag)); // 计算滞后lag的协方差和:sum((x_t - mean) * (x_{t+lag} - mean)) double covarianceSum = 0.0; for (int i = 0; i < data_.Count - lag; i++) { covarianceSum += (data_[i] - dataMean_) * (data_[i + lag] - dataMean_); } // 标准自相关系数 = 协方差和 / 整个数据集的离均差平方和 return covarianceSum / dataVarianceSum_; } public (List<int>, List<double>) AutoCorrelationPoints(int maxLag) { List<int> lags = new List<int>(); List<double> autocorrelationValues = new List<double>(); // 从lag=1开始计算到maxLag(maxLag应为data_.Count-1) for (int lag = 1; lag <= maxLag; lag++) { double autoCorr = AutocorrelationCoeff(lag); lags.Add(lag); autocorrelationValues.Add(autoCorr); } return (lags, autocorrelationValues); } } public class Program { static void Main(string[] args) { List<double> dataList = new List<double>(new double[] { 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 3.33 }); Statistics stats = new Statistics(dataList); // 计算lag从1到6的自相关结果 var autoCorr = stats.AutoCorrelationPoints(dataList.Count - 1); List<int> lagList = autoCorr.Item1; List<double> autoCorrActualList = autoCorr.Item2; Console.WriteLine("滞后值\t自相关系数"); for (int i = 0; i < lagList.Count; i++) { Console.WriteLine($"{lagList[i]}\t{autoCorrActualList[i]:F8}"); } Console.ReadKey(); } } }
修复后输出结果
滞后值 自相关系数 1 0.39072553 2 0.13718689 3 -0.08148897 4 -0.24787067 5 -0.34452680 6 -0.35402598
该结果与Python、R的输出完全一致。
内容的提问来源于stack exchange,提问作者user366312
相关产品推荐
相关产品推荐

