我正试图找到一种方法,使用python和numpy为给定文本使用单图、双图和三元图来生成转换矩阵。每行的概率应等于一。我先用bigrams做了这件事,效果很好:
distinct_words = list(word_dict.keys())
dwc = len(distinct_words)
matrix = np.zeros((dwc, dwc), dtype=np.float)
for i in range(len(distinct_words)):
word = distinct_words[i]
first_word_idx = i
total = 0
for bigram, count in ngrams.items():
word_1, word_2 = bigram.split(" ")
if word_1 == word:
total += count
for bigram, count in ngrams.items():
word_1, word_2 = bigram.split(" ")
if word_1 == word:
second_word_idx = index_dict[word_2]
matrix[first_word_idx,second_word_idx] = count / total
但现在我想加上单格图和三角形图,并对它们的概率(三角形图*.6,双格图*.2,单格图*.2)进行加权。我不认为我的python非常简洁,这是一个问题,但我也不知道如何使用多个n-gram(和权重,尽管诚实地说权重是次要的),这样我仍然可以得到任何给定行的所有概率加起来为一
distinct_words = list(word_dict.keys())
dwc = len(distinct_words)
matrix = np.zeros((dwc, dwc), dtype=np.float)
for i in range(len(distinct_words)):
word = distinct_words[i]
first_word_index = i
bi_total = 0
tri_total=0
tri_prob = 0
bi_prob = 0
uni_prob = word_dict[word] / len(distinct_words)
if i < len(distinct_words)-1:
for trigram, count in trigrams.items():
word_1, word_2, word_3 = trigram.split()
if word_1 + word_2 == word + distinct_words[i+1]:
tri_total += count
for trigram, count in trigrams.items():
word_1, word_2, word_3 = trigram.split()
if word_1 + word_2 == word + distinct_words[i+1]:
second_word_index = index_dict[word_2]
tri_prob = count/bigrams[word_1 + " " + word_2]
for bigram, count in bigrams.items():
word_1, word_2 = bigram.split(" ")
if word_1 == word:
bi_total += count
for bigram, count in bigrams.items():
word_1, word_2 = bigram.split(" ")
if word_1 == word:
second_word_index = index_dict[word_2]
bi_prob = count / bi_total
matrix[first_word_index,second_word_index] = (tri_prob * .4) + (bi_prob * .2) + (word_dict[word]/len(word_dict) *.2)
我正在阅读this lecture中关于如何设置概率矩阵的内容,这似乎是有意义的,但我不确定我错在哪里
如果有帮助的话,我的n_图就是从这里来的——它只是生成一个n_图作为字符串及其计数的字典
def get_ngram(words, n):
word_dict = {}
for i, word in enumerate(words):
if i > (n-2):
n_gram = []
for num in range(n):
index = i - num
n_gram.append(words[index])
if len(n_gram) > 1:
formatted_gram = ""
for word in reversed(n_gram):
formatted_gram += word + " "
else:
formatted_gram = n_gram[0]
stripped = formatted_gram.strip() if formatted_gram else n_gram[0]
if stripped in word_dict:
word_dict[stripped] += 1
else:
word_dict[stripped] = 1
return word_dict
我已经实现了一个用于计算单图、双图和三元图的示例。您可以使用
zip
轻松地加入项目。此外,Counter
用于计算项目,而defaultdict
用于项目的概率defaultdict
在密钥未映射到集合中时非常重要,返回零。否则,您必须添加if子句以避免None
输出:
让我们尝试以最有效的方式在纯Python中实现它,只依赖于列表和字典理解
假设我们有一个由3个单词“a”、“b”和“c”组成的玩具文本:
然后,要制作单格图、双格图和三叉图,您可以按照以下步骤进行:
要合并权重并标准化:
我们得到的是:
最后,健全性检查:
此代码可以进一步定制以合并您的标记化规则,例如,或者通过一次循环不同的gram来缩短代码
相关问题 更多 >
编程相关推荐