夏農熵-互資訊-entropy

辰令發表於2024-10-09

概念

 資訊熵--單個隨機變數的資訊量
    夏農熵又稱資訊熵,反映了一條資訊的資訊量大小和它的不確定性之間的關係,是資訊量的度量,單位為 bit
 互資訊--兩個隨機變數間相關資訊的多少 
 
  互資訊不假設資料的分佈,可以應用於各種型別的資料。
   依賴樣本量:互資訊的估計依賴於樣本量,樣本量不足可能導致估計不準確。
 熵可以用來計算一個系統中的失序現象,即混亂程度 熵、聯合熵、條件熵以及互資訊之間的關係是
    條件熵(Conditional Entropy)
	聯合熵(Joint Entropy) 
 方差度量一個數值集合或數值分佈的離散程度。不確定性與離散程度有關
    聯合機率是指在機率論中,兩個或多個隨機變數同時取特定值的機率

步驟

聯合熵,需要進行以下步驟:
    確定多個隨機變數的取值和機率分佈。
    計算每個隨機變數的熵。
    計算多個隨機變數的條件熵。
    計算聯合熵

程式碼

def counter(list):
	c_dict = {}
	for i in list:
		if i in c_dict:
			c_dict[i] += 1
		else:
			c_dict[i] = 1
	return c_dict
def count_prob(X,Y):
    # 使用字典統計每一個(x,y)元素出現的次數
    d_xy = dict()  # x的字典
    for i in range(X.size):
        if (X[i], Y[i]) in d_xy:
            d_xy[X[i], Y[i]] += 1
        else:
            d_xy[X[i], Y[i]] = 1
    # 計算每個元素出現的機率
    p_xy = dict()
    for xy in d_xy.keys():
        p_xy[xy] = d_xy[xy] / X.size
    return p_xy
    

### ( H(X) ) 是單個變數的熵
def entropy(x):
	counts = counter(x) #每個變數出現的次數
	prob = [i/len(x) for i in counts.values()] # 每個變數發生的機率
	return -sum([p*math.log(p) for p in prob if p > 0 ]) # 計算資訊熵
	
def entropy(prob):
    return -np.sum([p * np.log2(p) for p in prob if p > 0])
	
	
import math
def joint_entropy(joint_prob):
    """
    計算給定聯合機率分佈的聯合熵 joint_prob = {(0, 0): 0.25, (0, 1): 0.25, (1, 0): 0.5, (1, 1): 0}
    :param joint_prob: 一個字典,鍵為一對元素,值為它們同時發生的機率
    :return: 聯合熵
    """
    entropy = 0.0
    for pair, prob in joint_prob.items():
        if prob > 0:
            entropy -= prob * math.log(prob, 2)
    return entropy
 
# 示例使用
joint_prob = {(0, 0): 0.25, (0, 1): 0.25, (1, 0): 0.5, (1, 1): 0}
print(joint_entropy(joint_prob))  # 輸出聯合熵的值

### np.bincount()	
### joint_prob = {(0, 0): 0.25, (0, 1): 0.25, (1, 0): 0.5, (1, 1): 0}
def joint_entropy(joint_prob):
    #### joint_prob = {(0, 0): 0.25, (0, 1): 0.25, (1, 0): 0.5, (1, 1): 0}
    return -np.sum([p * np.log2(p) for row in joint_prob for p in row if p > 0])
	
def mutual_information(x, y):
    joint_prob, x_prob, y_prob = calculate_probabilities(x, y)
    return entropy(x_prob) + entropy(y_prob) - joint_entropy(joint_prob)

x = np.array([2,3,4,1,1,3,4,5,6,2,1,3,4,5,5,6,7,3,2,4,4,2])
print(entropy(x))

方法

scikit-learn庫中的函式
     scikit-learn提供了mutual_info_classif函式
	 scikit-learn提供了mutual_info_regression函式
使用`scipy.stats`的`entropy`函式計算聯合機率和條件機率,進而得到互資訊

程式碼示例2

from scipy.stats import entropy
import numpy as np

def calculate_probabilities(x, y):
#### 計算histogram2d兩個變數的聯合頻數,然後透過除以總樣本數得到聯合機率
#### 計算頻次直方圖(就是計算每段區間的樣本數),而並不想畫圖顯示它們,那麼可以直接用 np.histogram()。
### bins : int or array_like or [int, int] or [array, array], optional
    x_bins,x_bins =20,20
    joint_prob = np.histogram2d(x, y, bins=(x_bins,y_bins))[0] / len(x)
    x_prob = np.histogram(x, bins=x_bins)[0] / len(x)
    y_prob = np.histogram(y, bins=x_bins)[0] / len(y)
    return joint_prob, x_prob, y_prob
	
def mutual_information(x, y):
    joint_prob, x_prob, y_prob = calculate_probabilities(x, y)
    mi = entropy(x_prob) + entropy(y_prob) - entropy(joint_prob.flatten())
    return mi
	
p和q是兩個離散隨機變數的機率分佈列表。joint_probability函式透過將每個元素的機率相乘來計算聯合機率	
# 定義一個函式來計算聯合機率
def joint_probability(p, q):
    # 計算兩個隨機變數的聯合機率
    joint_prob = [p[i]*q[i] for i in range(len(p))]
    return joint_prob
 
# 示例:計算兩個離散隨機變數的聯合機率
# 機率分佈p和q
p = [0.1, 0.2, 0.3, 0.4]
q = [0.4, 0.3, 0.2, 0.1]
 
# 呼叫函式計算聯合機率
joint_prob = joint_probability(p, q)
print(joint_prob)

計算

 # 獲取不重複的(x,y,z)
data_xyz = data.drop_duplicates(subset=None, keep='first', inplace=False)

參考

 https://blog.csdn.net/FFXNFFXN/article/details/124713431

相關文章