跳转到主要内容

简单的功能模糊规则实现

项目描述

Build Status Coverage Status

frules - 简单功能模糊规则

Frules代表 模糊/功能规则。它允许轻松地处理模糊规则和变量。

安装

pip install frules

语言变量和表达式

表达式是frules中的核心概念。 Expression 类代表模糊逻辑中语言变量的子范围。

在经典数学中,变量取数值。在模糊逻辑中,语言变量 是非数值的,用表达式来描述。表达式将连续变量(如数值温度)映射到其语言对应物。例如,温度可以描述为冷、温暖或热。冷和温暖之间没有严格的界限 - 这就是为什么这些表达式是模糊的。

要创建新的表达式,我们使用一个函数,该函数接受连续变量的数值并返回 真值。真值介于0和1之间 - 它是连续值对该语言变量的隶属度。

from frules.expressions import Expression
#We know that anything over 50 degrees is hot and below 40 is't hot
hot = Expression(lambda x: min(1, max((x - 40) / 10., 0)))

这个丑陋的lambda表示某种模糊集。如果我们看看它的行为,我们会看到它实际上对超过50的任何值返回1,对低于40的任何值返回0,在40和50之间返回一些线性值。

>>> map(lambda x: {x: min(1, max((x - 40) / 10., 0))}, xrange(35, 55, 2))
[{35: 0}, {37: 0}, {39: 0}, {41: 0.1}, {43: 0.3}, {45: 0.5}, {47: 0.7}, {49: 0.9}, {51: 1}, {53: 1}

在实践中使用大量的lambda会使你的代码变得一团糟。以这种方式描述的模糊表达式也难以编写,因为它们必须满足一些值断言。

这就是为什么我们封装了它们,而不是使用原始函数,并使用表达式封装它们。此外,frules提供了一组辅助工具,简化了新表达式的定义。例如,温度变量的完整表达式集可能如下所示

from frules.expressions import Expression as E
from frules.expressions import ltrapezoid, trapezoid, rtrapezoid

cold = E(ltrapezoid(10, 20), "cold")        # anything below 10, more is fuzzy
warm = E(trapezoid(10, 20, 30, 35), "warm") # anything between 20 and 30
hot = E(rtrapezoid(30, 35), "hot")          # anything over 35, less is fuzzy

可以使用逻辑运算符重复使用/混合表达式

cold_or_hot = cold || warm
not_hot = !hot

可选名称在开始使用模糊规则时将很有帮助。

模糊规则

虽然表达式定义了语言变量,但它们并非严格绑定到任何变量。它们更像是我们用来描述事物的形容词,其含义严格依赖于上下文。人和数据都可以是“大的”,但这个形容词在每个情况下都有略微不同的含义。

Rule 对象将连续变量与表达式绑定。规则还可以被评估,以查看它们在给定的连续输入下有多真。

>>> from frules.rules import Rule
>>> is_hot = Rule(temperature=hot)
>>> is_hot.eval(temperature=5)
0.8

可以通过逻辑运算符(&|)混合规则,以创建更复杂的规则,允许进行模糊推理。

from frules.expressions import Expression as E
from frules.rules import Rule as R
from frules.expressions import ltrapezoid, trapezoid, rtrapezoid

# car age expressions
old = E(ltrapezoid(2001, 2008), "old")
new = E(rtrapezoid(2013, 2014), "new")
not_so_old = - (old & new)

# power expressions
strong = E(rtrapezoid(50, 100), "strong")
weak = E(ltrapezoid(50, 100), "weak")

# price expression
expensive = E(rtrapezoid(25000, 30000), "expensive")
cheap = - expensive

# yes expression
yes = E(lambda yes: float(yes), "yes") # converts bool to float


# rules
is_attractive = R(production_year=not_so_old) & R(horsepower=strong)
should_buy = is_attractive & R(price=cheap)

拥有这样一套规则,我们可以进行一些推理。

>>> should_buy
(((age = !(old & new) & horsepower = strong) & !None = None) & cost = !expensive)
>>> should_buy.eval(horsepower=70, production_year=2012, price=15000)
0.4
>>>
>>> candidates = {
...     "car1": {"horsepower": 70, "production_year": 2012, "price": 15000},
...     "car2": {"horsepower": 150, "production_year": 2010, "price": 30000},
...     "car3": {"horsepower": 90, "production_year": 2014, "price": 10000},
...     "car4": {"horsepower": 85, "production_year": 2009, "price": 35000},
... }
>>> max(candidates.iteritems(), key=lambda (key, inputs): is_hot.eval(**inputs))
('car3', {'horsepower': 90, 'price': 10000, 'production_year': 2014})

项目详情


下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。

源分布

此版本没有可用的源分布文件。请参阅 生成分布存档 的教程。

构建分布

frules-0.2.0-py3-none-any.whl (9.9 kB 查看哈希值)

上传时间 Python 3

由以下组织支持