Tôi đã theo giấy here và mã here (nó được thực hiện bằng cách sử dụng kld đối xứng và mô hình lùi được đề xuất trong bài trong liên kết 1) để tính toán KLD giữa hai tập dữ liệu văn bản. Tôi đã thay đổi cho vòng cuối cùng để trả lại phân bố xác suất của hai bộ dữ liệu để kiểm tra nếu cả hai tổng đến 1:Tính toán phân kỳ đối xứng Kullback-Leibler giữa hai tài liệu
import re, math, collections
def tokenize(_str):
stopwords = ['and', 'for', 'if', 'the', 'then', 'be', 'is', \
'are', 'will', 'in', 'it', 'to', 'that']
tokens = collections.defaultdict(lambda: 0.)
for m in re.finditer(r"(\w+)", _str, re.UNICODE):
m = m.group(1).lower()
if len(m) < 2: continue
if m in stopwords: continue
tokens[m] += 1
return tokens
#end of tokenize
def kldiv(_s, _t):
if (len(_s) == 0):
return 1e33
if (len(_t) == 0):
return 1e33
ssum = 0. + sum(_s.values())
slen = len(_s)
tsum = 0. + sum(_t.values())
tlen = len(_t)
vocabdiff = set(_s.keys()).difference(set(_t.keys()))
lenvocabdiff = len(vocabdiff)
""" epsilon """
epsilon = min(min(_s.values())/ssum, min(_t.values())/tsum) * 0.001
""" gamma """
gamma = 1 - lenvocabdiff * epsilon
""" Check if distribution probabilities sum to 1"""
sc = sum([v/ssum for v in _s.itervalues()])
st = sum([v/tsum for v in _t.itervalues()])
ps=[]
pt = []
for t, v in _s.iteritems():
pts = v/ssum
ptt = epsilon
if t in _t:
ptt = gamma * (_t[t]/tsum)
ps.append(pts)
pt.append(ptt)
return ps, pt
tôi đã thử nghiệm với
d1 = """Many research publications want you to use BibTeX, which better organizes the whole process. Suppose for concreteness your source file is x.tex. Basically, you create a file x.bib containing the bibliography, and run bibtex on that file.""" d2 = """In this case you must supply both a \left and a \right because the delimiter height are made to match whatever is contained between the two commands. But, the \left doesn't have to be an actual 'left delimiter', that is you can use '\left)' if there were some reason to do it."""
sum(ps)
= 1 nhưng sum(pt)
là cách nhỏ hơn 1 khi:
là ther e cái gì đó là không chính xác trong mã hoặc người nào khác? Cảm ơn!
Cập nhật:
Để làm cho cả pt và ps sum tới 1, tôi đã phải thay đổi mã để:
vocab = Counter(_s)+Counter(_t)
ps=[]
pt = []
for t, v in vocab.iteritems():
if t in _s:
pts = gamma * (_s[t]/ssum)
else:
pts = epsilon
if t in _t:
ptt = gamma * (_t[t]/tsum)
else:
ptt = epsilon
ps.append(pts)
pt.append(ptt)
return ps, pt
Không liên quan đến câu hỏi của bạn, trong chuỗi thử nghiệm (d1 và d2), bạn nên sử dụng hai dấu gạch chéo ngược liên tiếp. Ký tự dấu gạch chéo ngược được sử dụng để thoát trong python. Ví dụ: 'x =" \\ left "' thay vì 'x =" \ left "'. –