# encoding: utf-8
'''created on 2017-8-7
根據李航《統計學習方法》實現
'''from collections import defaultdict
import math
class maxent(object):
def __init__(self):
self.feats = defaultdict(int)
self.trainset =
self.labels = set()
def load_data(self, file):
for line in open(file):
fields = line.strip().split()
# 資料共3列。第一列為標籤,二三列為特徵
if len(fields) < 2: continue
label = fields[0]
self.labels.add(label)
for f in set(fields[1:]):
# (label,f) tuple is feature
self.feats[(label, f)] += 1
def _initparams(self):
self.size = len(self.trainset)
self.m = max([len(record) - 1 for record in self.trainset]) # p91中的m
# 計算p82頁最下面的期望
self.ep_ = [0.0] * len(self.feats) # 儲存期望值
for i, f in enumerate(self.feats):
self.ep_[i] = float(self.feats[f]) / float(self.size)
# each feature function correspond to id
self.feats[f] = i
# 初始化需要學習的引數的值
self.w = [0.0] * len(self.feats)
self.lastw = self.w
def probwgt(self, features, label):
'''輔助函式:計算p85中的公式6.22中的分子
'''wgt = 0.0
for f in features:
print (self.feats[(label, f)])
if (label, f)in self.feats:
wgt += self.w[self.feats[(label, f)]]
return math.exp(wgt)
def calprob(self, features):
'''計算p85中的公式6.22的條件概率p(y|x)
'''wgts = [(self.probwgt(features, label), label) for label in self.labels]
z = sum([ w for w, label in wgts])
prob = [ (w / z, label) for w, label in wgts]
return prob
def ep(self):
'''計算p83頁最上面的期望
'''eps = [0.0] * len(self.feats)
for record in self.trainset:
features = record[1:]
# 計算 p(y|x)
probs = self.calprob(features)
for f in features:
for prob, label in probs:
if (label, f) in self.feats: # only focus on features from training data.
idx = self.feats[(label, f)]
eps[idx] += prob * (1.0 / self.size) # 計算期望 sum(p(x) * p(y|x) * f(x,y))。 其中p(x) = 1 / n
return eps
def _convergence(self, lastw, w):
for w1, w2 in zip(lastw, w):
if abs(w1 - w2) >= 0.01:
return false
return true
def train(self, max_iter=1000):
self._initparams()
for i in range(max_iter):
print ('iter %d ...' % (i + 1))
self.ep = self.ep()
self.lastw = self.w[:]
for i, w in enumerate(self.w):
delta = 1.0 / self.m * math.log(self.ep_[i] / self.ep[i]) # p91 公式6.34
self.w[i] += delta
# 是否滿足收斂條件
if self._convergence(self.lastw, self.w):
break
def predict(self, input):
features = input.strip().split()
prob = self.calprob(features)
prob.sort(reverse=true)
return prob
if __name__ == "__main__":
maxent = maxent()
maxent.load_data("input.data")
maxent.train(100)
prob = maxent.predict("sunny sad")
print (prob)
github上發現的乙份最大熵模型實現**。具體鏈結找不到了。
最大熵模型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實現最大熵模型
本文參考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,...
最大熵模型及Python實現
熵的概念源自於熱力學,在熱力學中,熵為所有可能狀態數的對數值,可以表示分子的混亂程度。將熱力學中熵的概念引入到隨機變數的分布中,則隨機變數的熵度量了其不確定性的程度。數學表達如下 最大熵原理指在滿足約束的條件下,熵最大的模型是最優的模型。可以這樣理解,滿足約束 說明該模型體現了所有已知資訊,熵最大 ...