多键多值非确定性Python字典

2024-03-01

已经有一个多键字典 https://pypi.python.org/pypi/multi_key_dict/1.0.2在 python 中,也是一个多值字典。我需要一个 python 字典,它既是:

example:

# probabilistically fetch any one of baloon, toy or car
d['red','blue','green']== "baloon" or "car" or "toy"  

d['red']==d['green'] 的概率较高,而 d['red']!=d['red'] 的概率较低,但有可能

单个输出值应根据键的规则概率确定(模糊) 例如:在上述情况下,规则可能是,如果键同时具有“红色”和“蓝色”,则 80% 的时间返回“气球”,如果只有蓝色,则 15% 的时间返回“玩具”,否则 5% 的时间返回“汽车”。

setitem 方法的设计应使得以下内容成为可能:

d["red", "blue"] =[
    ("baloon",haseither('red','green'),0.8),
    ("toy",.....)
    ,....
]

上面使用谓词函数和相应的概率将多个值分配给字典。并且代替上面的作业列表,甚至使用字典作为作业会更好:

d["red", "blue"] ={ 
    "baloon": haseither('red','green',0.8),
    "toy": hasonly("blue",0.15),
    "car": default(0.05)
}

在上面的气球中,如果出现“红色”或绿色,则 80% 的时间会返回 ,如果有蓝色,则返还玩具 15% 的时间,无条件返还汽车 5% 的时间。

python中是否有现有的数据结构已经满足上述要求?如果不是,那么如何修改 multikeydict 代码以满足 python 中的上述要求?

如果使用字典,那么可以有一个配置文件或使用适当的嵌套装饰器来配置上述概率谓词逻辑,而不必硬编码 if \else 语句。

注意:上面是基于规则的自动响应器应用程序的有用自动机,因此请告诉我 python 中是否有任何类似的基于规则的框架可用,即使它不使用字典结构?


模拟多键字典

multi_key_dict https://pypi.python.org/pypi/multi_key_dict不允许__getitem__() https://docs.python.org/3/reference/datamodel.html#object.__getitem__同时使用多个键...

(e.g. d["red", "green"])

可以用以下方式模拟多键tuple https://docs.python.org/3.5/library/stdtypes.html#tuples or set https://docs.python.org/3.5/library/stdtypes.html#set键。如果顺序不重要的话set https://docs.python.org/3.5/library/stdtypes.html#set似乎是最好的(实际上是可散列的frozen set https://docs.python.org/3.5/library/stdtypes.html#frozenset, 以便 ["red", "blue"]是同一个["blue", "red"].

模拟多值字典

多值是通过使用某些数据类型而固有的,它可以是any storage element https://docs.python.org/3.5/library/stdtypes.html#mapping-types-dict可以方便地建立索引。一个标准dict https://docs.python.org/3.5/library/stdtypes.html#dict应该提供这一点。

非决定论

Using a probability distribution defined by the rules and assumptions1, non-deterministic selection is performed using this recipe https://docs.python.org/3/library/random.html#examples-and-recipes from the python docs.

MultiKeyMultiValNonDeterministicDict Class

What a name.   \o/-nice!

This class takes multiple keys that define a probabilistic rule set of multiple values. During item creation (__setitem__() https://docs.python.org/3/reference/datamodel.html#object.__setitem__) all value probabilities are precomputed for all combinations of keys1. During item access (__getitem__() https://docs.python.org/3/reference/datamodel.html#object.__getitem__) the precomputed probability distribution is selected and the result is evaluated based on a random weighted selection.

定义

import random
import operator
import bisect
import itertools

# or use itertools.accumulate in python 3
def accumulate(iterable, func=operator.add):
    'Return running totals'
    # accumulate([1,2,3,4,5]) --> 1 3 6 10 15
    # accumulate([1,2,3,4,5], operator.mul) --> 1 2 6 24 120
    it = iter(iterable)
    try:
        total = next(it)
    except StopIteration:
        return
    yield total
    for element in it:
        total = func(total, element)
        yield total

class MultiKeyMultiValNonDeterministicDict(dict):

    def key_combinations(self, keys):
        """get all combinations of keys"""
        return [frozenset(subset) for L in range(0, len(keys)+1) for subset in itertools.combinations(keys, L)]

    def multi_val_rule_prob(self, rules, rule):
        """
        assign probabilities for each value, 
        spreading undefined result probabilities
        uniformly over the leftover results not defined by rule.
        """
        all_results = set([result for result_probs in rules.values() for result in result_probs])
        prob = rules[rule]
        leftover_prob = 1.0 - sum([x for x in prob.values()])
        leftover_results = len(all_results) - len(prob)
        for result in all_results:
            if result not in prob:
                # spread undefined prob uniformly over leftover results
                prob[result] = leftover_prob/leftover_results
        return prob

    def multi_key_rule_prob(self, key, val):
        """
        assign probability distributions for every combination of keys,
        using the default for combinations not defined in rule set
        """ 
        combo_probs = {}
        for combo in self.key_combinations(key):
            if combo in val:
                result_probs = self.multi_val_rule_prob(val, combo).items()
            else:
                result_probs = self.multi_val_rule_prob(val, frozenset([])).items()
            combo_probs[combo] = result_probs
        return combo_probs

    def weighted_random_choice(self, weighted_choices):
        """make choice from weighted distribution"""
        choices, weights = zip(*weighted_choices)
        cumdist = list(accumulate(weights))
        return choices[bisect.bisect(cumdist, random.random() * cumdist[-1])]

    def __setitem__(self, key, val):
        """
        set item in dictionary, 
        assigns values to keys with precomputed probability distributions
        """

        precompute_val_probs = self.multi_key_rule_prob(key, val)        
        # use to show ALL precomputed probabilities for key's rule set
        # print precompute_val_probs        

        dict.__setitem__(self, frozenset(key), precompute_val_probs)

    def __getitem__(self, key):
        """
        get item from dictionary, 
        randomly select value based on rule probability
        """
        key = frozenset([key]) if isinstance(key, str) else frozenset(key)             
        val = None
        weighted_val = None        
        if key in self.keys():
            val = dict.__getitem__(self, key)
            weighted_val = val[key]
        else:
            for k in self.keys():
                if key.issubset(k):
                    val = dict.__getitem__(self, k)
                    weighted_val = val[key]

        # used to show probabality for key
        # print weighted_val

        if weighted_val:
            prob_results = self.weighted_random_choice(weighted_val)
        else:
            prob_results = None
        return prob_results

Usage

d = MultiKeyMultiValNonDeterministicDict()

d["red","blue","green"] = {
    # {rule_set} : {result: probability}
    frozenset(["red", "green"]): {"ballon": 0.8},
    frozenset(["blue"]): {"toy": 0.15},
    frozenset([]): {"car": 0.05}
}

Testing

检查概率

N = 10000
red_green_test = {'car':0.0, 'toy':0.0, 'ballon':0.0}
red_blue_test = {'car':0.0, 'toy':0.0, 'ballon':0.0}
blue_test = {'car':0.0, 'toy':0.0, 'ballon':0.0}
red_blue_green_test = {'car':0.0, 'toy':0.0, 'ballon':0.0}
default_test = {'car':0.0, 'toy':0.0, 'ballon':0.0}

for _ in xrange(N):
    red_green_test[d["red","green"]] += 1.0
    red_blue_test[d["red","blue"]] += 1.0
    blue_test[d["blue"]] += 1.0
    default_test[d["green"]] += 1.0
    red_blue_green_test[d["red","blue","green"]] += 1.0

print 'red,green test      =', ' '.join('{0}: {1:05.2f}%'.format(key, 100.0*val/N) for key, val in red_green_test.items())
print 'red,blue test       =', ' '.join('{0}: {1:05.2f}%'.format(key, 100.0*val/N) for key, val in red_blue_test.items())
print 'blue test           =', ' '.join('{0}: {1:05.2f}%'.format(key, 100.0*val/N) for key, val in blue_test.items())
print 'default test        =', ' '.join('{0}: {1:05.2f}%'.format(key, 100.0*val/N) for key, val in default_test.items())
print 'red,blue,green test =', ' '.join('{0}: {1:05.2f}%'.format(key, 100.0*val/N) for key, val in red_blue_green_test.items())

red,green test      = car: 09.89% toy: 10.06% ballon: 80.05%
red,blue test       = car: 05.30% toy: 47.71% ballon: 46.99%
blue test           = car: 41.69% toy: 15.02% ballon: 43.29%
default test        = car: 05.03% toy: 47.16% ballon: 47.81%
red,blue,green test = car: 04.85% toy: 49.20% ballon: 45.95%

概率符合规则!


脚注

  1. 分布假设

    由于规则集尚未完全定义,因此对概率分布进行了假设,其中大部分是在multi_val_rule_prob()。基本上任何未定义的概率都会均匀分布在其余值上。这是为了all键的组合,并为随机加权选择创建通用键接口。

    给定示例规则集

    d["red","blue","green"] = {
        # {rule_set} : {result: probability}
        frozenset(["red", "green"]): {"ballon": 0.8},
        frozenset(["blue"]): {"toy": 0.15},
        frozenset([]): {"car": 0.05}
    }
    

    这将创建以下发行版

    'red'           = [('car', 0.050), ('toy', 0.475), ('ballon', 0.475)]
    'green'         = [('car', 0.050), ('toy', 0.475), ('ballon', 0.475)]
    'blue'          = [('car', 0.425), ('toy', 0.150), ('ballon', 0.425)]
    'blue,red'      = [('car', 0.050), ('toy', 0.475), ('ballon', 0.475)]
    'green,red'     = [('car', 0.098), ('toy', 0.098), ('ballon', 0.800)]
    'blue,green'    = [('car', 0.050), ('toy', 0.475), ('ballon', 0.475)]
    'blue,green,red'= [('car', 0.050), ('toy', 0.475), ('ballon', 0.475)]
     default        = [('car', 0.050), ('toy', 0.475), ('ballon', 0.475)]
    

    如果这不正确,请指教。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多键多值非确定性Python字典 的相关文章

  • LibreOffice 并行将 .docx 转换为 .pdf 效果不佳

    我有很多 docx 文件需要转换为 pdf 将它们一一转换需要很长时间 所以我编写了一个 python 脚本来并行转换它们 from subprocess import Popen import time import os os chdi
  • 如何删除 PyCharm 中的项目?

    如果我关闭一个项目 然后删除该项目文件夹 则在 PyCharm 重新启动后 会再次创建一个空的项目文件夹 只需按顺序执行以下步骤即可 他们假设您当前在 PyCharm 窗口中打开了该项目 单击 文件 gt 关闭项目 关闭项目 在 PyCha
  • 定义Python源代码编码的正确方法

    PEP 263 http www python org dev peps pep 0263 定义如何声明Python源代码编码 通常 Python 文件的前两行应以以下内容开头 usr bin python coding
  • 如何为未捕获的异常处理程序编写单元测试

    我有一个函数可以捕获uncaught例外情况 如下 有没有办法编写一个单元测试来执行uncaught exception handler 功能正常 但测试正常退出 import logging def config logger logge
  • Python re无限执行

    我正在尝试执行这段代码 import re pattern r w w s re compiled re compile pattern results re compiled search COPRO HORIZON 2000 HOR p
  • 如何使用 Python boto3 获取 redshift 中的列名称

    我想使用 python boto3 获取 redshift 中的列名称 创建Redshift集群 将数据插入其中 配置的机密管理器 配置 SageMaker 笔记本 打开Jupyter Notebook写入以下代码 import boto3
  • 从 pyspark.sql 中的列表创建数据框

    我完全陷入了有线的境地 现在我有一个清单li li example data map lambda x get labeled prediction w x collect print li type li 输出就像 0 0 59 0 0
  • 如何获取numpy.random.choice的索引? - Python

    是否可以修改 numpy random choice 函数以使其返回所选元素的索引 基本上 我想创建一个列表并随机选择元素而不进行替换 import numpy as np gt gt gt a 1 4 1 3 3 2 1 4 gt gt
  • numpy:高效执行数组的复杂重塑

    我正在将供应商提供的大型二进制数组读入 2D numpy 数组 tempfid M N load data data numpy fromfile file dirname fid dtype numpy dtype i4 convert
  • python celery -A 的无效值无法加载应用程序

    我有一个以下项目目录 azima init py main py tasks py task py from main import app app task def add x y return x y app task def mul
  • 在 Mac OSX 上从 Python 3.6 运行 wine 命令

    我正在尝试用 Python 编写一个打开的脚本wine然后发送代码到wine终端打开一个 exe程序 这 exe程序也是命令驱动的 我可以打开wine 但我无法进一步 import shlex subprocess line usr bin
  • PIL.Image.open和tf.image.decode_jpeg返回值的区别

    我使用 PIL Image open 和 tf image decode jpeg 将图像文件解析为数组 但发现PIL Image open 中的像素值与tf image decode jpeg不一样 为什么会出现这种情况 Thanks 代
  • 使用标签或 href 传递 Django 数据

    我有一个包含链接的表 当单击该链接进行更多操作时 我想将一些数据传递给我的函数 my html table tbody for query in queries tr td value a href internal my func que
  • NumPy 相当于 Keras 函数 utils.to_categorical

    我有一个使用 Keras 进行机器学习的 Python 脚本 我正在构建 X 和 Y 它们分别是特征和标签 标签的构建方式如下 def main depth 10 nclass 101 skip True output True video
  • Flask 应用程序路由中的多个参数

    烧瓶怎么写app route如果我在 URL 调用中有多个参数 这是我从 AJax 调用的 URL http 0 0 0 0 8888 createcm summary VVV change Feauure 我试图写我的烧瓶app rout
  • R Leaflet Legend:colorBin-删除中断之间的小数

    我正在使用 Leaflet 库在 R 中创建交互式 HTML 地图 传说中采用的是colorBin用于创建将数据分为 6 个类别的方法 使用min values and max values 我已经定义了美国社区调查收入数据的特定范围可能落
  • 如何通过函数注释指示函数需要函数作为参数,或返回函数?

    您可以使用函数注释 http www python org dev peps pep 3107 在python 3中指示参数和返回值的类型 如下所示 def myfunction name str age int gt str return
  • 根据多个阈值将 SciPy 分层树状图切割成簇

    我想将 SciPy 的树状图切割成多个具有多个阈值的簇 我尝试过使用 fcluster 但它只能削减一个阈值 例如 这是我从另一个问题中摘取的一段代码 import pandas data pandas DataFrame total ru
  • 仅允许正小数

    在我的 Django 模型中 我创建了一个如下所示的小数字段 price models DecimalField u Price decimal places 2 max digits 12 显然 价格为负或零是没有意义的 有没有办法将小数
  • 使用 paramiko 运行 Sudo 命令

    我正在尝试执行sudo使用 python paramiko 在远程计算机上运行命令 我尝试了这段代码 import paramiko ssh paramiko SSHClient ssh set missing host key polic

随机推荐