2、互信息(Mutual Information)
文章目录
- 1、简介
- 2、互信息及其测量内容
- 3、解读互信息得分
- 4、例子 - 1985年的汽车
1、简介
首次接触新数据集的人可能会感到困惑。你可能需要处理数百到数千个特征,并且这些特征可能缺乏详细描述。那么从何入手才是明智的选择?
作为第一步之一,在构建基于特征效用度量的排名时,请您注意这一关键步骤的功能定位。这代表了衡量特征与目标之间关联程度的方法;随后,请您聚焦于选取少量最具价值的特征进行深入分析;这样能够让你更加自信地投入所需的时间。
我们应用所采用的度量标准命名为"互信息"。该度量指标类似于相关指标,由于它评估了两个变量之间的相互影响。其优势在于能够识别所有形式的关系类型,并非仅限于线性的相互作用。
互信息是一种强大的通用评估标准;尤其适合于在特征开发初期应用;尤其是你在尚不确定应该采用哪种模型的时候
便于操作与理解,
计算性能优越,
具有坚实的理论支撑,
具有较强的泛化能力,
对于各类复杂关系都能进行有效分析
2、互信息及其测量内容
互信息通常以不确定性为视角来表征它们之间的关联。其度量了在一个变量中获得关于另一个变量的信息所减少的不确定性水平。已知某个特征的具体取值时,在多大程度上能提升我们对该目标事件发生可能性的认知?
基于Ames Housing数据的一个实例。该图表揭示了房屋外部质量与销售价格之间的关系。每个标记代表一栋 house.

了解房屋的外观质量可以减少其售价的不确定性。
根据经验法则,在大多数情况下,
当数据服从正态分布时,
约有68%的数据落在第一标准差范围内,
95%的数据落在第二标准差范围内,
而99.7%的数据则集中在第三标准差区间内。
(技术说明:在信息理论领域中所指的不确定性是一个量可以用'熵'这一指标来衡量。具体而言,在描述单个变量时:‘你需要提出多少个是或否的问题’这一指标可以帮助评估其不确定程度。相应地,在处理多个变量时:所需提问数量越多也就意味着相应的不确定性程度也就越高。此外,在特征选择过程中:互信息则表示你能通过特征提取从目标中获取的信息量)。
3、解读互信息得分
两个变量之间的最小可能互信息量为零。当两变量间的互信息 MI 为零时,则表明它们相互独立:这些变量无法提供关于彼此的信息。理论上而言,互信息 MI 的取值范围不受限制。然而,在实际应用中发现其数值通常不会超出此范围。(因为互信息的增长速度较为缓慢。)
该图表将展示MI值如何反映特征与目标之间关系的分类及其强度。

左图:随着特征与目标之间依赖关系的增强或紧密程度提升, 互信息数值上升. 右图: 互信息是一种衡量各种关联类型的方法(不仅包括线性关系, 如相关系数一样).
在应用互信息时,有一些事情需要记住:
- 互信息(Mutual Information, MI)是一种衡量单个特征对目标变量预测能力强弱的有效指标。
- 尽管一个特征在与其他变量相互作用时可能携带大量信息量,但单独使用时往往无法充分揭示其潜在价值。互信息方法仅能评估各个特征对目标变量的独立作用。
- 具体而言,在进行初步筛选后结合其他统计方法或领域知识进一步优化和验证结果。
- 某个特征求取的效果不仅依赖于所选择的具体模型架构和训练方法(如深度神经网络或线性回归),还受到该特征求取目标和可用数据类型的具体关系所限制。
- 每个特征求取的效果都受限于其与目标变量之间的可学习关系类型。
- 仅仅因为一个特征有一个高的MI得分并不意味着你的模型就能够利用这个信息。
- 建议在进行初步筛选后结合其他统计方法或领域知识进一步优化和验证结果。
4、例子 - 1985年的汽车
该汽车数据集包含了1985年份生产的193辆不同车型。该数据集旨在从23个不同的属性(包括制造商、车身类型和发动机功率)中推断出车辆价格。在这一案例中,我们计划利用互信息对各属性的重要性进行排序,并通过数据分析可视化来深入探讨这些结果。
In [1]:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
plt.style.use("seaborn-whitegrid")
df = pd.read_csv("../input/fe-course-data/autos.csv")
df.head()
Out[1]:
| symboling | make | fuel_type | aspiration | num_of_doors | body_style | drive_wheels | engine_location | wheel_base | length | … | engine_size | fuel_system | bore | stroke | compression_ratio | horsepower | peak_rpm | city_mpg | highway_mpg | price | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 3 | alfa-romero | gas | std | 2 | convertible | rwd | front | 88.6 | 168.8 | … | 130 | mpfi | 3.47 | 2.68 | 9 | 111 | 5000 | 21 | 27 | 13495 |
| 1 | 3 | alfa-romero | gas | std | 2 | convertible | rwd | front | 88.6 | 168.8 | … | 130 | mpfi | 3.47 | 2.68 | 9 | 111 | 5000 | 21 | 27 | 16500 |
| 2 | 1 | alfa-romero | gas | std | 2 | hatchback | rwd | front | 94.5 | 171.2 | … | 152 | mpfi | 2.68 | 3.47 | 9 | 154 | 5000 | 19 | 26 | 16500 |
| 3 | 2 | audi | gas | std | 4 | sedan | fwd | front | 99.8 | 176.6 | … | 109 | mpfi | 3.19 | 3.40 | 10 | 102 | 5500 | 24 | 30 | 13950 |
| 4 | 2 | audi | gas | std | 4 | sedan | 4wd | front | 99.4 | 176.6 | … | 136 | mpfi | 3.19 | 3.40 | 8 | 115 | 5500 | 18 | 22 | 17450 |
5 rows × 25 columns
该算法通过区分处理离散型和连续型特征来实现其功能。因此,请您告知该算法哪些属性应视为离散型、哪些视为连续型。根据经验判断,默认情况下那些具有浮点数数据类型的特征被认为是连续型而非离散型。对于那些类型为分类型或具有分类dtype的数据(如类别标签),通常需要进行标签编码处理以便被识别为离散属性。(建议您参考我们的《分类变量处理》课程内容以了解如何进行标签编码。)
In [2]:
X = df.copy()
y = X.pop("price")
# Label encoding for categoricals
for colname in X.select_dtypes("object"):
X[colname], _ = X[colname].factorize()
# All discrete features should now have integer dtypes (double-check this before using MI!)
discrete_features = X.dtypes == int
Scikit-learn在其特征选择模块中提供了两种互信息度量:一种专门针对实值目标(即mutual_info_regression),另一种则适用于分类问题(即mutual_info_classif)。我们的目标变量是连续型数据。在下一个单元格中,我们计算了这些特征的互信息得分,并将它们整理成一个美观的数据表格形式。
In [3]:
from sklearn.feature_selection import mutual_info_regression
def make_mi_scores(X, y, discrete_features):
mi_scores = mutual_info_regression(X, y, discrete_features=discrete_features)
mi_scores = pd.Series(mi_scores, name="MI Scores", index=X.columns)
mi_scores = mi_scores.sort_values(ascending=False)
return mi_scores
mi_scores = make_mi_scores(X, y, discrete_features)
mi_scores[::3] # show a few features with their MI scores
Out[3]:
curb_weight 1.540126
highway_mpg 0.951700
length 0.621566
fuel_system 0.485085
stroke 0.389321
num_of_cylinders 0.330988
compression_ratio 0.133927
fuel_type 0.048139
Name: MI Scores, dtype: float64
现在是一个条形图,可以使比较更容易:
In [4]:
def plot_mi_scores(scores):
scores = scores.sort_values(ascending=True)
width = np.arange(len(scores))
ticks = list(scores.index)
plt.barh(width, scores)
plt.yticks(width, ticks)
plt.title("Mutual Information Scores")
plt.figure(dpi=100, figsize=(8, 5))
plot_mi_scores(mi_scores)

数据可视化是效用排名的一个很好的后续。 让我们仔细看看其中的几个。
如我们所预期的,较高的分数'curb_weight'特征与目标'price'显示出显著的关系
In [5]:
sns.relplot(x="curb_weight", y="price", data=df);

该特征的互信息(MI)得分相对较低;然而,在分析结果展示的图形中可以看出该特征能够有效地将数据划分为两个价格类别;这两个类别呈现出明显趋势变化并且分别对应于不同的 horsepower 特征表现;这表明该特征与其他变量之间存在显著关联关系;在决定某个变量的重要性时之前最好进一步研究这些潜在的关系——因为领域的专业知识可以帮助我们更好地理解数据
In [6]:
sns.lmplot(x="horsepower", y="price", hue="fuel_type", data=df);

数据可视化是对特征工程工具箱的一种重要补充。 通过这种可视化手段,您可以深入探索数据间的内在关联性。 除了常用的度量手段如互信息外,在实际应用中这种可视化的辅助作用尤为显著。
