利用numpy 计算互信息
时间: 2023-09-02 11:04:34 浏览: 201
利用numpy计算互信息是一种常见的数据分析方法。对于给定的两个变量,互信息可以衡量它们之间的关联程度。
首先,我们需要导入numpy库。通过使用numpy的函数,我们可以轻松地计算互信息。假设我们有两个变量X和Y,它们分别存储在numpy数组x和y中。
接下来,我们需要计算变量X和变量Y的联合分布。我们可以使用numpy的histogram2d函数创建一个二维直方图来表示两个变量的联合分布。这个函数会将x和y作为输入,并返回两个数组,分别表示x和y在各个区间的频数。
然后,我们可以使用计算得到的联合分布数组计算互信息。互信息的计算公式为MI(X,Y) = ΣΣp(x,y) * log(p(x,y) / (p(x) * p(y))),其中p(x,y),p(x)和p(y)分别表示联合概率、边缘概率和条件概率。我们可以使用numpy的log函数和sum函数来计算互信息。
最后,我们可以将计算得到的互信息进行输出或者进一步的分析。
总之,利用numpy计算互信息是一种简单而实用的方法。通过使用numpy的函数,我们可以方便地计算互信息,并为数据分析提供有价值的指导。
相关问题
用python导入excel数据,对14列数值型数据利用互信息计算每两个特征之间的互信息值并输出所有互信息值
在Python中,我们可以使用pandas库处理Excel文件,NumPy库进行数值计算以及scikit-learn库中的mutual_info_score函数来计算互信息。首先,你需要安装必要的库,可以使用pip进行安装:
```bash
pip install pandas numpy scikit-learn openpyxl
```
然后,你可以按照以下步骤操作:
1. 导入所需库:
```python
import pandas as pd
import numpy as np
from sklearn.feature_selection import mutual_info_classif, mutual_info_regression
```
2. 加载Excel数据:
```python
# 假设你的Excel文件名为"data.xlsx",并且数据位于Sheet1
df = pd.read_excel('data.xlsx', sheet_name='Sheet1')
```
3. 确保数据的前14列为数值型数据:
```python
# 如果不确定列的数据类型,可以用isnumeric检查
num_cols = df.columns[:14] # 假设前14列是数值型
df[num_cols] = df[num_cols].astype(float) # 将非数值转换为浮点数
```
4. 计算互信息值(假设这里是两个连续变量之间的互信息):
```python
def calculate_mutual_info(df, cols):
mi_values = []
for i in range(len(cols)):
for j in range(i + 1, len(cols)):
X = df[cols[i]]
Y = df[cols[j]]
mi = mutual_info_regression(X, Y)
mi_values.append((cols[i], cols[j], mi))
return mi_values
column_pairs = list(combinations(num_cols, 2)) # 获取所有组合的列对
mi_results = calculate_mutual_info(df, column_pairs)
```
5. 输出所有互信息值:
```python
for pair, value in mi_results:
print(f"Mutual Information between {pair[0]} and {pair[1]}: {value}")
```
NGMI互信息的计算
### NGMI(Normalized Google Mutual Information)互信息公式及实现
#### 定义与背景
归一化互信息 (NMI) 是衡量两个随机变量之间依赖关系的一种度量方式。对于图像处理领域,通常用于评估两幅图像之间的相似性。而NGMI则是一种特定形式的归一化互信息,在某些应用场景下更为适用。
#### 计算公式
NGMI 的计算基于原始互信息 \(I(X;Y)\),并通过各自熵 \(H(X), H(Y)\) 进行标准化:
\[ \text{NGMI}(X,Y)=\frac{\sum_{i,j}p(x_i,y_j)\log_2\left(\frac{p(x_i,y_j)}{p(x_i)p(y_j)}\right)}{\sqrt{\sum_ip(x_i)\log_2(p(x_i))}\cdot\sqrt{\sum_jp(y_j)\log_2(p(y_j))}} \]
其中,
- \( p(x_i, y_j) \) 表示联合概率分布函数;
- \( p(x_i) \) 和 \( p(y_j) \) 分别表示边缘概率分布函数;
为了提高效率并简化操作,可以采用 `accumarray` 函数快速构建直方图矩阵从而得到上述所需的各种概率值[^1]。
#### Python 实现代码
下面给出一段Python代码用来展示如何利用NumPy库中的功能以及MATLAB风格的`accumarray`模拟来高效地完成这一过程:
```python
import numpy as np
def ngmi(image1, image2):
# 将输入图片转换成向量形式
vec1 = image1.flatten()
vec2 = image2.flatten()
# 创建索引数组以便于后续统计频率
idxs = np.arange(len(vec1))
# 使用 accumarray 来累积计数形成联立频次表
joint_counts = np.zeros((256, 256))
for i in range(256):
mask = (vec1 == i)
if not any(mask): continue
temp = np.bincount(idxs[mask], minlength=256)
joint_counts[i,:len(temp)] += temp
# 转换成概率分布
px_py = joint_counts / float(joint_counts.sum())
px = px_py.sum(axis=1)
py = px_py.sum(axis=0)
# 防止除零错误
eps = np.finfo(float).eps
mi = ((px_py * np.log(px_py/(np.outer(px,py)+eps))).sum() /
np.sqrt((-px*np.log(px)).sum()*(-py*np.log(py)).sum()))
return mi
# 测试数据集
img1 = np.random.randint(0, high=256, size=(100, 100), dtype='uint8')
img2 = img1.copy().astype('float') + np.random.normal(scale=30., size=img1.shape)
img2 = img2.clip(min=0,max=255).astype('uint8')
print(f'NGMI between two images is {ngmi(img1,img2):.4f}')
```
此段程序首先通过flatten方法将两张灰度级图像转化为一维向量序列,接着借助accumarray的思想创建了一个256×256大小的联合频次表格joint_counts,最后按照定义完成了整个NGMI公式的运算。
阅读全文