Example #1
0
def filter_eventually_follows_relation(log: Union[EventLog, pd.DataFrame], relations: List[str], retain: bool = True) -> \
        Union[EventLog, pd.DataFrame]:
    """
    Retain traces that contain any of the specified 'eventually follows' relations.
    For example, if relations == [('a','b'),('a','c')] and log [<a,b,c>,<a,c,b>,<a,d,b>]
    the resulting log will contain traces describing [<a,b,c>,<a,c,b>,<a,d,b>].

    Parameters
    ---------------
    log
        Log object
    relations
        List of activity name pairs, which are allowed/forbidden paths
    retain
        Parameter that says whether the paths
        should be kept/removed

    Returns
    ----------------
    filtered_log
        Filtered log object
    """
    if check_is_dataframe(log):
        from pm4py.algo.filtering.pandas.ltl import ltl_checker
        if retain:
            cases = set()
        else:
            cases = set(log[constants.CASE_CONCEPT_NAME])
        for path in relations:
            filt_log = ltl_checker.A_eventually_B(log, path[0], path[1],
                                                  parameters={ltl_checker.Parameters.POSITIVE: retain})
            this_traces = set(filt_log[constants.CASE_CONCEPT_NAME])
            if retain:
                cases = cases.union(this_traces)
            else:
                cases = cases.intersection(this_traces)
        return log[log[constants.CASE_CONCEPT_NAME].isin(cases)]
    else:
        from pm4py.objects.log.log import EventLog
        from pm4py.algo.filtering.log.ltl import ltl_checker
        if retain:
            cases = set()
        else:
            cases = set(id(trace) for trace in log)
        for path in relations:
            filt_log = ltl_checker.A_eventually_B(log, path[0], path[1],
                                                  parameters={ltl_checker.Parameters.POSITIVE: retain})
            this_traces = set(id(trace) for trace in filt_log)
            if retain:
                cases = cases.union(this_traces)
            else:
                cases = cases.intersection(this_traces)
        filtered_log = EventLog(attributes=log.attributes, extensions=log.extensions, omni_present=log.omni_present,
                                classifiers=log.classifiers)
        for trace in log:
            if id(trace) in cases:
                filtered_log.append(trace)
        return filtered_log
Example #2
0
 def test_AeventuallyB_neg(self):
     df = csv_import_adapter.import_dataframe_from_path(
         os.path.join("input_data", "running-example.csv"))
     filt_A_ev_B_neg = ltl_checker.A_eventually_B(
         df,
         "check ticket",
         "pay compensation",
         parameters={ltl_checker.Parameters.POSITIVE: False})
Example #3
0
def apply(dataframe, filter, parameters=None):
    """
    Apply an LTL checker filter on the dataframe

    Parameters
    --------------
    dataframe
        Dataframe
    filter
        Content of the filter (dictionary including the type, the arguments and the parameters)

    Returns
    -------------
    filtered_dataframe
        Filtered dataframe
    """
    if parameters is None:
        parameters = {}

    filter = filter[1]

    args = filter["arguments"]

    for param in filter["parameters"]:
        parameters[param] = filter["parameters"][param]

    if filter["type"] == "A_eventually_B":
        return ltl_checker.A_eventually_B(dataframe,
                                          args[0],
                                          args[1],
                                          parameters=parameters)
    elif filter["type"] == "A_eventually_B_eventually_C":
        return ltl_checker.A_eventually_B_eventually_C(dataframe,
                                                       args[0],
                                                       args[1],
                                                       args[2],
                                                       parameters=parameters)
    elif filter["type"] == "A_eventually_B_eventually_C_eventually_D":
        return ltl_checker.A_eventually_B_eventually_C_eventually_D(
            dataframe,
            args[0],
            args[1],
            args[2],
            args[3],
            parameters=parameters)
    elif filter["type"] == "A_next_B_next_C":
        return ltl_checker.A_next_B_next_C(dataframe,
                                           args[0],
                                           args[1],
                                           args[2],
                                           parameters=parameters)
    elif filter["type"] == "four_eyes_principle":
        return ltl_checker.four_eyes_principle(dataframe,
                                               args[0],
                                               args[1],
                                               parameters=parameters)
    elif filter["type"] == "attr_value_different_persons":
        return ltl_checker.four_eyes_principle(dataframe,
                                               args[0],
                                               parameters=parameters)

    return dataframe
Example #4
0
 def test_AeventuallyB_pos(self):
     df = csv_import_adapter.import_dataframe_from_path(os.path.join("input_data", "running-example.csv"))
     filt_A_ev_B_pos = ltl_checker.A_eventually_B(df, "check ticket", "pay compensation",
                                                  parameters={"positive": True})
 def test_AeventuallyB_pos(self):
     df = pd.read_csv(os.path.join("input_data", "running-example.csv"))
     df = dataframe_utils.convert_timestamp_columns_in_df(df)
     filt_A_ev_B_pos = ltl_checker.A_eventually_B(df, "check ticket", "pay compensation",
                                                  parameters={ltl_checker.Parameters.POSITIVE: True})
Example #6
0
def execute_script():
    # import the dataframe
    df = csv_import_adapter.import_dataframe_from_path(
        os.path.join("..", "tests", "input_data", "running-example.csv"))
    # A eventually B positive: filter the cases of the log where each instance of A is eventually followed by an instance
    # of B
    filt_A_ev_B_pos = ltl_checker.A_eventually_B(df,
                                                 "check ticket",
                                                 "pay compensation",
                                                 parameters={"positive": True})
    print("len(filt_A_ev_B_pos) = ",
          len(filt_A_ev_B_pos.groupby("case:concept:name")))
    # A eventually B negative: filter the cases of the log where A or B where not there, or cases where an instance of
    # A is not followed by an instance of B
    filt_A_ev_B_neg = ltl_checker.A_eventually_B(
        df, "check ticket", "pay compensation", parameters={"positive": False})
    print("len(filt_A_ev_B_neg) = ",
          len(filt_A_ev_B_neg.groupby("case:concept:name")))

    # A eventually B eventually C positive: filter the cases of the log where each instance of A is
    # eventually followed by an instance of B that is eventually followed by an instance of C
    filt_A_ev_B_ev_C_pos = ltl_checker.A_eventually_B_eventually_C(
        df,
        "check ticket",
        "decide",
        "pay compensation",
        parameters={"positive": True})
    print("len(filt_A_ev_B_ev_C_pos) = ",
          len(filt_A_ev_B_ev_C_pos.groupby("case:concept:name")))
    # A eventually B eventually C negative: filter the cases of the log where A,B,C are not all in the case,
    # or an instance of A is not eventually followed by an instance of B that is not eventually followed by
    # an instance of C
    filt_A_ev_B_ev_C_neg = ltl_checker.A_eventually_B_eventually_C(
        df,
        "check ticket",
        "decide",
        "pay compensation",
        parameters={"positive": False})
    print("len(filt_A_ev_B_ev_C_neg) = ",
          len(filt_A_ev_B_ev_C_neg.groupby("case:concept:name")))

    # A next B next C positive: filter the cases of the log where an instance of A was followed by an
    # instance of B, and the instance of B was directly followed by an instance of C
    filt_A_next_B_next_C_pos = ltl_checker.A_next_B_next_C(
        df,
        "check ticket",
        "decide",
        "pay compensation",
        parameters={"positive": True})
    print("len(filt_A_next_B_net_C_pos) = ",
          len(filt_A_next_B_next_C_pos.groupby("case:concept:name")))
    # A next B next C negative: filter the cases of the log where none instance of A was followed directly
    # by an instance of B, and the instance of B was directly followed by an instance of C
    filt_A_next_B_next_C_neg = ltl_checker.A_next_B_next_C(
        df,
        "check ticket",
        "decide",
        "pay compensation",
        parameters={"positive": False})
    print("len(filt_A_next_B_next_C_neg) = ",
          len(filt_A_next_B_next_C_neg.groupby("case:concept:name")))

    # four eyes principle positive: filter the cases of the log where A and B are both there, and the resource doing A
    # is NEVER the same resource doing B
    filt_foureyes_pos = ltl_checker.four_eyes_principle(
        df, "check ticket", "pay compensation", parameters={"positive": True})
    print("len(filt_foureyes_pos) = ",
          len(filt_foureyes_pos.groupby("case:concept:name")))
    # four eyes principle negative: filter the cases of the log where A and B are both there, and there is a common
    # resource doing A and B
    filt_foureyes_neg = ltl_checker.four_eyes_principle(
        df, "check ticket", "pay compensation", parameters={"positive": False})
    print("len(filt_foureyes_neg) = ",
          len(filt_foureyes_neg.groupby("case:concept:name")))

    # attr_value_different_persons positive: filter the cases of the log in which A was done by two different resources
    attr_value_different_persons_pos = ltl_checker.attr_value_different_persons(
        df, "check ticket", parameters={"positive": True})
    print("len(attr_value_different_persons_pos) = ",
          len(attr_value_different_persons_pos.groupby("case:concept:name")))
    # attr_value_different_persons negative: filter the cases of the log in which A was not there or was not executed
    # by two different resources
    attr_value_different_persons_neg = ltl_checker.attr_value_different_persons(
        df, "check ticket", parameters={"positive": False})
    print("len(attr_value_different_persons_neg) = ",
          len(attr_value_different_persons_neg.groupby("case:concept:name")))