本文參考nltk maxentclassifier實現了乙個簡單的最大熵模型,主要用於理解最大熵模型中一些數學公式的實際含義。
最大熵模型:
pw(y|x)zw(x)=1zw(x)exp(∑i=1nwifi(x,y))=∑yexp(∑i=1nwifi(x,y))
pw(y|x)=1zw(x)exp(∑i=1nwifi(x,y))zw(x)=∑yexp(∑i=1nwifi(x,y))
這裡fi(x,y)fi(x,y)代表特徵函式,wiwi代表每個特徵函式對於的權值。
如何計算測試資料x被分為類別y的概率呢?
總結成一句話:我們把x和y傳給每個特徵函式得到相應的特徵值(0或者1),然後乘上相應的權值,最後通過softmax得到。
現在面臨兩個問題。
1.這裡的fi(x,y)fi(x,y)究竟是什麼鬼,如何得到?
2.wiwi又如何求得?
先來看看第乙個問題。
fi(x,y)fi(x,y)反映的是x和y的特徵,也就是說它是對輸入和輸出同時抽取特徵的
它的定義是
f(x,y)=
wi(0)=0,i∈
這裡的下標表示第ii個特徵對於的ww,上標表示第t輪迭代。
2.重複以下更新直至收斂:
w(t+1)i=w(t)i+1clogep^(fi)ep(n)(fi),i∈
wi(t+1)=wi(t)+1clogep^(fi)ep(n)(fi),i∈
其中c一般取樣本的最大特徵數,反應了ww更新速度。
ep^(f)=∑x,yp^(x,y)f(x,y)
ep^(f)=∑x,yp^(x,y)f(x,y)
表示的是某乙個特徵函式關於經驗分布p^(x,y)p^(x,y)的期望值
ep(f)=∑x,yp^(x)p(y|x)f(x,y)
ep(f)=∑x,yp^(x)p(y|x)f(x,y)
表示的是某乙個特徵函式關於模型p(y|x)p(y|x)與經驗分布p^(x)p^(x)的期望值
先來看p^(x,y)p^(x,y)和p^(x)p^(x)
p^(x=x,y=y)=v(x=x,y=y)n
p^(x=x,y=y)=v(x=x,y=y)n
p^(x=x)=v(x=x)n
p^(x=x)=v(x=x)n
其中v(x=x,y=y)v(x=x,y=y)表示樣本(x,y)(x,y)出現的頻率,v(x=x)v(x=x)表示樣本xx出現的頻率,nn表示樣本個數。
由於我們在訓練時,樣本資料存在唯一性,因此:
p^(x=x,y=y)=p^(x=x)=1n
p^(x=x,y=y)=p^(x=x)=1n
所以有:
ep^(f)=1n∑x,yf(x,y)
ep^(f)=1n∑x,yf(x,y)
ep(f)=1n∑x,yp(y|x)f(x,y)
ep(f)=1n∑x,yp(y|x)f(x,y)
ep^(fi)ep(n)(fi)=∑x,yfi(x,y)∑x,yp(y|x)fi(x,y)
ep^(fi)ep(n)(fi)=∑x,yfi(x,y)∑x,yp(y|x)fi(x,y)
∑x,yfi(x,y)∑x,yfi(x,y)表示的所有樣本在被某乙個特徵函式抽取的特徵值之和,**實現如下:
for tok, label in train_toks:
fcount[index] += val
return fcount
fcount結構為
求p(y|x)p(y|x)的實現如下:
prob_dict = {}
for label in labels:
total = 0.0
total += weights[index]*val
prob_dict[label] = np.exp(total)
value_sum = sum(list(prob_dict.values()))
for(label, value) in prob_dict.items():
prob_dict[label] = prob_dict[label]/value_sum
return prob_dict
∑x,yp(y|x)fi(x,y)∑x,yp(y|x)fi(x,y)的實現:
for tok, label in train_toks:
for label, p in prob_dict.items():
fcount[index] += p*val
return fcount
完整**如下:
import numpy as np
encoding =
for (fname, fval) in featureset.items():
return encoding
for tok, label in train_toks:
fcount[index] += val
return fcount
prob_dict = {}
for label in labels:
total = 0.0
total += weights[index]*val
prob_dict[label] = np.exp(total)
value_sum = sum(list(prob_dict.values()))
for(label, value) in prob_dict.items():
prob_dict[label] = prob_dict[label]/value_sum
return prob_dict
for tok, label in train_toks:
for label, p in prob_dict.items():
fcount[index] += p*val
return fcount
def maxent_train(train_toks):
labels = set()
feature_name = set()
for(tok, label) in train_toks:
for(fname, fval) in tok.items():
feature_name.add(fname)
labels.add(label)
c = len(feature_name)+1
cinv = 1/c
weights = np.zeros(len(empirical_fcount))
iter = 1
while true:
if iter == 100:
break
weights += (empirical_fcount / estimated_fcount) * cinv
iter+=1
if __name__ == '__main__':
train_data = [
(dict(a=1, b=1, c=1), '1'),
(dict(a=1, b=1, c=0), '0'),
(dict(a=0, b=1, c=1), '1')]
maxent_train(train_data)
python實現最大熵模型
encoding utf 8 created on 2017 8 7 根據李航 統計學習方法 實現 from collections import defaultdict import math class maxent object def init self self.feats default...
最大熵模型python實現
本文參考nltk maxentclassifier實現了乙個簡單的最大熵模型,主要用於理解最大熵模型中一些數學公式的實際含義。最大熵模型 pw y x zw x 1 zw x exp i 1nwi fi x y ye xp i 1n wifi x,y 這裡fi x,y 代表特徵函式,wi 代表每個特...
最大熵模型及Python實現
熵的概念源自於熱力學,在熱力學中,熵為所有可能狀態數的對數值,可以表示分子的混亂程度。將熱力學中熵的概念引入到隨機變數的分布中,則隨機變數的熵度量了其不確定性的程度。數學表達如下 最大熵原理指在滿足約束的條件下,熵最大的模型是最優的模型。可以這樣理解,滿足約束 說明該模型體現了所有已知資訊,熵最大 ...