Giter Club home page Giter Club logo

Comments (4)

nilp0inter avatar nilp0inter commented on August 11, 2024

Hi,

I am a little confused about the provided code. The patterns inside the EXISTS CE of your rule (FeverGreaterThanFourDays, ConjunctivalInjection) don't seems to match with the FactLists that you provided.

Some things that seems weird to me are:

  • Your rule lacks the self parameter.
  • You are trying to capture as parameters patient_id and appointment_id. This is not possible with EXISTS given that the rule will fire only once if there are facts that satisfy the pattern (even if there are more than one possibility).
  • Replacing EXISTS with OR for testing is not a good idea, a better replacement would be AND. Because all of the patterns inside EXISTS must match for the rule to fire.
  • EXISTS is not for "aggregating" information is for checking if a set of patterns match at least once.

I prepared this example to illustrate the use of EXISTS.

If you can provide a more concise example of what you are trying to achieve it would be very helpful.

from experta.

amsimms avatar amsimms commented on August 11, 2024

Here is a more detailed use case. I'm looking at producing a preliminary and final risk score. The preliminary risk score is calculated from available data, not complete data, and should be produced using as many of the defined criteria that are available.

A final score, in contrast, must have all defined criteria set to either present or absent.

For the sake of argument, consider a score function that includes 4 observation criteria: o1, o2, o3, o4. Each observation can be modeled as fact with attribute "present" that is True if the observed criteria is present, or false if is not. If a given observation, e.g. fever, has not been evaluated, no observation fact for fever is declared.

Both a preliminary score and a final score can be calculated when all four facts (o1, o2, o3, o4) are declared in the knowledge base, as in this example:

o1 - present
o2 - present
o3 - absent
o4 - present
final score = 3, and preliminary score = 3

Then consider this case where only two observation facts are declared in the KB:
o1 - present
o4 - present

Here a final score cannot be calculated as all four observations have not been explicitly evaluated as either present or absent. However, there is enough information to calculate a preliminary score of 2, because o1 and o4 have been set to present (i.e. True).

DECLARE seems like the right way to define a rule to calculate the preliminary score. It would be written as:

DECLARE(o1, o2, o3, o4)

and should match as many facts as possible, binding attributes appropriately.

AND(o1, o2, o3, o4)

is what I am using for the final score.

Let me know if this clears things up.

Thanks!

from experta.

nilp0inter avatar nilp0inter commented on August 11, 2024

I think I understand your needs. I prepared this proof of concept about the MAYBE operator.

Please, tell me if this helps.

from experta import *


def MAYBE(*patterns):
    return AND(
        *[OR(p, NOT(p)) for p in patterns]
    )


class FeverGreaterThanFourDays(Fact):
    pass


class ConjunctivalInjection(Fact):
    pass


class PolymorphousRash(Fact):
    pass


class PeripheralEdema(Fact):
    pass


class KE(KnowledgeEngine):
    @Rule(
        MAYBE(
            AS.f1 << FeverGreaterThanFourDays(
                patient_id=MATCH.patient_id,
                appointment_id=MATCH.appointment_id,
                weight=MATCH.fever_weight,
                present=W(),
            ),
            AS.f2 << ConjunctivalInjection(
                patient_id=MATCH.patient_id,
                appointment_id=MATCH.appointment_id,
                weight=MATCH.conjunctival_weight,
                present=W(),
            ),
            AS.f3 << PolymorphousRash(
                patient_id=MATCH.patient_id,
                appointment_id=MATCH.appointment_id,
                weight=MATCH.polymorphous_weight,
                present=W(),
            ),
            AS.f4 << PeripheralEdema(
                patient_id=MATCH.patient_id,
                appointment_id=MATCH.appointment_id,
                weight=MATCH.peripheral_weight,
                present=W(),
            )
        )
    )
    def something(self, f1=None, f2=None, f3=None, f4=None):
        print("Score:", len(list(filter(None, [f1, f2, f3, f4]))))

k=KE()
k.reset()
k.declare(ConjunctivalInjection(patient_id=1, appointment_id=2, weight=15, present=True))
k.declare(FeverGreaterThanFourDays(patient_id=1, appointment_id=2, weight=12, present=True))
k.declare(PolymorphousRash(patient_id=1, appointment_id=2, weight=0, present=False))
# k.declare(PeripheralEdema(patient_id=1, appointment_id=2, weight=1, present=True))
k.run()

from experta.

lazarkrstic avatar lazarkrstic commented on August 11, 2024

Hi, I have problem with MATCH too. When EXISTS use MATCH.some_value the result is always True and that is not correct. Here is simple example to reproduce

from experta import *
class FactOne(Fact):
    name = Field(str)

class FactTwo(Fact):
    name = Field(str)

class MyEngine(KnowledgeEngine):

    @DefFacts()
    def load(self):
        yield FactOne(name = 'aaaaaaaaa')
        yield FactTwo(name = 'bbbbbbbbb')

    @Rule(
        FactOne(name = MATCH.name),
        EXISTS(
            FactTwo(name = MATCH.name)
        )
    )
    def my_rule(self, name):
        print('my_ryle is activated, name: {0}'.format(name))


e = MyEngine()

than I get

>>> e.reset()
>>> print(e.facts)
<f-0>: InitialFact()
<f-1>: FactOne(name='aaaaaaaaa')
<f-2>: FactTwo(name='bbbbbbbbb')

but also

>>> print(e.agenda)
0: my_rule {InitialFact(), FactOne(name='aaaaaaaaa')}
>>> e.run()
my_ryle is activated, name: aaaaaaaaa

This is not expected behavior (at least it shouldn't be)

from experta.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.