Matlab计算非整数向量互信息结果为负的问题排查
互信息计算结果为负的代码错误排查
你的代码得到负的互信息结果,核心是两个关键错误:
联合概率计算逻辑错误
互信息公式里的联合概率p(x,y)是联合分箱频次除以总样本数,而非样本数的平方。原代码中pxy = NXY(ii,jj)/(length(X) * length(Y))的分母错误,正确分母应为总样本数length(X)(X和Y样本量一致)。分箱边界不匹配
单独调用histcounts计算X、Y的边缘频次时,分箱边界是各自独立生成的,和histcounts2的联合分箱边界不一致,导致边缘概率与联合概率的分箱不对应,计算逻辑混乱。正确做法是直接从histcounts2的联合频次矩阵中求和得到边缘频次,保证分箱完全对齐。
修正后的代码
clear, clc, close all % 获取数据 Data = uiimport('SMatrices6.mat'); X = real(Data.data(:,1,1)); Y = real(Data.data(:,2,1)); % 归一化至0-1区间 mx = min(X); my = min(Y); X = X - mx; % 修正归一化逻辑,避免原代码中mx为正数时的错误 Y = Y - my; MX = max(X); MY = max(Y); X = X./MX; Y = Y./MY; % 遍历不同分箱数计算互信息 for B = 20:300 [NXY, ~, ~] = histcounts2(X,Y,B); % 从联合频次计算边缘频次,保证分箱对齐 NX = sum(NXY, 2); % 对列求和,得到X各分箱的频次 NY = sum(NXY, 1); % 对行求和,得到Y各分箱的频次 N = length(X); % 总样本数 I = 0; for ii = 1:size(NXY,1) for jj = 1:size(NXY,2) px = NX(ii)/N; py = NY(jj)/N; pxy = NXY(ii,jj)/N; % 处理0概率的特殊情况,避免log2出错 if pxy == 0 || px == 0 || py == 0 continue; % 直接跳过无贡献的项 end I = I + pxy * log2(pxy/(px * py)); end end disp(I) end
额外说明:原代码的归一化步骤中,X = X + abs(mx)在mx为正数时会错误放大X的值,修正为X = X - mx可直接将最小值置为0,再除以最大值就能得到标准的0-1区间结果。
内容的提问来源于stack exchange,提问作者ScatRes
相关产品推荐
相关产品推荐

