首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >计算表示马尔可夫链规则的字典中值的总频率和相对频率

计算表示马尔可夫链规则的字典中值的总频率和相对频率
EN

Stack Overflow用户
提问于 2019-04-16 00:37:18
回答 2查看 187关注 0票数 0

我制作了一个函数make_rule(text, scope=1),它简单地遍历一个字符串并生成一个字典,作为马尔可夫文本生成器的规则(其作用域是链接字符的数量,而不是单词)。

代码语言:javascript
复制
>>> rule = make_rule("abbcad", 1)
>>> rule
{'a': ['b', 'd'], 'b': ['b', 'c'], 'c': ['a']}

我的任务是计算这个系统的熵。为了做到这一点,我想我需要知道:

  1. 值在字典中出现的总频率,即其总频率。
  2. 在字典中给定关键字的情况下,值出现的频率,即其相对频率。

对于字典中的每个值,有没有一种快速获取这两个数字的方法?

对于上面的示例,我需要以下输出:

代码语言:javascript
复制
'a' total: 1, 'a'|'a': 0, 'a'|'b': 0, 'a'|'c': 1
'b' total: 2, 'b'|'a': 1, 'b'|'b': 1, 'b'|'c': 0
'c' total: 1, 'c'|'a': 0, 'c'|'b': 1, 'c'|'c': 0
'd' total: 1, 'd'|'a': 1, 'a'|'b': 1, 'a'|'c': 1

我猜'a'总数很容易推断,所以可能只需要为字典中出现的每个唯一项输出一个三元组列表:

代码语言:javascript
复制
[[('a', 'a', 0), ('a', 'b', 0), ('a', 'c', 1)], [('b', 'a', 1), ('b', 'b', 1), ('b', 'c', 0)], ...]
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-04-17 00:55:39

我只讨论“一个值在字典中出现的频率”,因为您已经说过“一个值在字典中出现的总频率”很容易推断出来。

如果您只希望能够查找给定键的值的相对频率,那么使用Counter对象的dict很容易实现:

代码语言:javascript
复制
from collections import Counter

rule = {'a': ['b', 'd'], 'b': ['b', 'c'], 'c': ['a']}

freq = {k: Counter(v) for k, v in rule.items()}

…它会给你一个类似这样的freq

代码语言:javascript
复制
{
    'a': Counter({'b': 1, 'd': 1}),
    'b': Counter({'b': 1, 'c': 1}),
    'c': Counter({'a': 1})
}

…这样,在给定关键'c'的情况下,您可以获得'a'的相对频率:

代码语言:javascript
复制
>>> freq['c']['a']
1

因为对于不存在的键,Counter对象返回0,所以您也会像预期的那样获得零频率:

代码语言:javascript
复制
>>> freq['a']['c']
0

如果你需要问题中指定的3元组列表,你可以通过一些额外的工作来获得它。这里有一个函数可以做到这一点:

代码语言:javascript
复制
def triples(rule):               
    freq = {k: Counter(v) for k, v in rule.items()}
    all_values = sorted(set().union(*rule.values()))      
    sorted_keys = sorted(rule)
    return [(v, k, freq[k][v]) for v in all_values for k in sorted_keys] 

我认为这里唯一不是不言自明的是all_values = ...行,它:

使用

  • 中列表的所有单个元素(注意,使用operator)

  • converts
  1. operator)
  2. converts
    1. operator)
    2. converts
      1. of a sorted() list),将该集合的列表创建为一个空列表。

如果你仍然保留原文,你可以通过使用all_values = sorted(set(original_text))来避免所有这些工作。

这就是它的实际作用:

代码语言:javascript
复制
>>> triples({'a': ['b', 'd'], 'b': ['b', 'c'], 'c': ['a']})
[
    ('a', 'a', 0), ('a', 'b', 0), ('a', 'c', 1),
    ('b', 'a', 1), ('b', 'b', 1), ('b', 'c', 0),
    ('c', 'a', 0), ('c', 'b', 1), ('c', 'c', 0),
    ('d', 'a', 1), ('d', 'b', 0), ('d', 'c', 0)
]
票数 2
EN

Stack Overflow用户

发布于 2019-04-17 00:20:57

我想不出一个快速的方法,除了迭代单词的字符,计算字典中每个列表中的出现次数,并在最后对其求和:

代码语言:javascript
复制
alphabet = sorted(set("abbcad"))
rule = {'a': ['b', 'd'], 'b': ['b', 'c'], 'c': ['a']}

totalMatrix = []
for elem in alphabet:
    total = 0
    occurences = []
    for key in rule.keys():
        currentCount = rule[key].count(elem)
        total += currentCount
        occurences.append((elem,key,currentCount))
    totalMatrix.append([elem, total] + occurences)

for elem in totalMatrix:
    print(elem)

totalMatrix的内容为:

代码语言:javascript
复制
['a', 1, ('a', 'a', 0), ('a', 'b', 0), ('a', 'c', 1)]
['b', 2, ('b', 'a', 1), ('b', 'b', 1), ('b', 'c', 0)]
['c', 1, ('c', 'a', 0), ('c', 'b', 1), ('c', 'c', 0)]
['d', 1, ('d', 'a', 1), ('d', 'b', 0), ('d', 'c', 0)]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55693682

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档