Esempio n. 1
0
 def test_alignment(self):
     log = xes_importer.apply(
         os.path.join("input_data", "running-example.xes"))
     from pm4py.algo.discovery.alpha import algorithm as alpha_miner
     net, im, fm = alpha_miner.apply(log)
     from pm4py.algo.conformance.alignments import algorithm as alignments
     aligned_traces = alignments.apply(
         log,
         net,
         im,
         fm,
         variant=alignments.Variants.VERSION_STATE_EQUATION_A_STAR)
     aligned_traces = alignments.apply(
         log,
         net,
         im,
         fm,
         variant=alignments.Variants.VERSION_DIJKSTRA_NO_HEURISTICS)
     from pm4py.evaluation.replay_fitness import evaluator as rp_fitness_evaluator
     fitness = rp_fitness_evaluator.apply(
         log,
         net,
         im,
         fm,
         variant=rp_fitness_evaluator.Variants.ALIGNMENT_BASED)
     evaluation = rp_fitness_evaluator.evaluate(
         aligned_traces,
         variant=rp_fitness_evaluator.Variants.ALIGNMENT_BASED)
     from pm4py.evaluation.precision import evaluator as precision_evaluator
     precision = precision_evaluator.apply(
         log,
         net,
         im,
         fm,
         variant=rp_fitness_evaluator.Variants.ALIGNMENT_BASED)
Esempio n. 2
0
 def test_alignment(self):
     log = xes_importer.apply(os.path.join("input_data", "running-example.xes"))
     from pm4py.algo.discovery.alpha import algorithm as alpha_miner
     net, im, fm = alpha_miner.apply(log)
     from pm4py.algo.conformance.alignments import algorithm as alignments
     aligned_traces = alignments.apply(log, net, im, fm, variant=alignments.Variants.VERSION_STATE_EQUATION_A_STAR)
     aligned_traces = alignments.apply(log, net, im, fm, variant=alignments.Variants.VERSION_DIJKSTRA_NO_HEURISTICS)
Esempio n. 3
0
 def test_importingPetriLogAlignment(self):
     # to avoid static method warnings in tests,
     # that by construction of the unittest package have to be expressed in such way
     self.dummy_variable = "dummy_value"
     imported_petri1, marking1, fmarking1 = petri_importer.apply(
         os.path.join(INPUT_DATA_DIR, "running-example.pnml"))
     log = xes_importer.apply(
         os.path.join(INPUT_DATA_DIR, "running-example.xes"))
     final_marking = petri.petrinet.Marking()
     for p in imported_petri1.places:
         if not p.out_arcs:
             final_marking[p] = 1
     for trace in log:
         cf_result = align_alg.apply(
             trace,
             imported_petri1,
             marking1,
             final_marking,
             variant=align_alg.VERSION_DIJKSTRA_NO_HEURISTICS)['alignment']
         is_fit = True
         for couple in cf_result:
             if not (couple[0] == couple[1]
                     or couple[0] == ">>" and couple[1] is None):
                 is_fit = False
         if not is_fit:
             raise Exception("should be fit")
def execute_script():
    log = importer.apply(os.path.join("..", "tests", "input_data", "running-example.xes"))
    net, im, fm = inductive_miner.apply(log)
    aligned_traces = alignments.apply(log, net, im, fm)
    gviz = visualizer.apply(log, aligned_traces,
                            parameters={visualizer.Variants.CLASSIC.value.Parameters.FORMAT: "svg"})
    visualizer.view(gviz)
Esempio n. 5
0
def conformance_diagnostics_alignments(
        log: EventLog, petri_net: PetriNet, initial_marking: Marking,
        final_marking: Marking) -> List[Dict[str, Any]]:
    """
    Apply the alignments algorithm between a log and a Petri net
    The methods return the full alignment diagnostics.

    Parameters
    -------------
    log
        Event log
    petri_net
        Petri net
    initial_marking
        Initial marking
    final_marking
        Final marking

    Returns
    -------------
    aligned_traces
        A list of alignments for each trace of the log (in the same order as the traces in the event log)
    """
    from pm4py.algo.conformance.alignments import algorithm as alignments
    return alignments.apply(log, petri_net, initial_marking, final_marking)
Esempio n. 6
0
def apply(log, petri_net, initial_marking, final_marking, align_variant=alignments.DEFAULT_VARIANT, parameters=None):
    """
    Evaluate fitness based on alignments

    Parameters
    ----------------
    log
        Event log
    petri_net
        Petri net
    initial_marking
        Initial marking
    final_marking
        Final marking
    align_variant
        Variants of the alignments to apply
    parameters
        Parameters of the algorithm

    Returns
    ---------------
    dictionary
        Containing two keys (percFitTraces and averageFitness)
    """
    if align_variant == decomp_alignments.Variants.RECOMPOS_MAXIMAL.value:
        alignment_result = decomp_alignments.apply(log, petri_net, initial_marking, final_marking,
                                                   variant=align_variant, parameters=parameters)
    else:
        alignment_result = alignments.apply(log, petri_net, initial_marking, final_marking, variant=align_variant,
                                            parameters=parameters)
    return evaluate(alignment_result)
Esempio n. 7
0
def getFitness(net,m0,mf,log,size_of_run):
    '''
    Prefix-aware fitness
    :param net:
    :param m0:
    :param mf:
    :param log:
    :param size_of_run:
    :return:
    '''
    sum=0
    for l in log._list:
        model_cost_function = dict()
        sync_cost_function = dict()
        for t in net.transitions:
            if t.label is not None:
                model_cost_function[t]=2**(len(l)+size_of_run-getIndexOfT(t,m0))
            sync_cost_function[t]=0
        trace_cost_function = dict()
        for a in range (0,len(l)):
            trace_cost_function[a]=2**(len(l)+size_of_run-a)
        parameters = {}
        parameters[alignments.Variants.VERSION_STATE_EQUATION_A_STAR.value.Parameters.PARAM_MODEL_COST_FUNCTION] = model_cost_function
        parameters[alignments.Variants.VERSION_STATE_EQUATION_A_STAR.value.Parameters.PARAM_SYNC_COST_FUNCTION] = sync_cost_function
        parameters[alignments.Variants.VERSION_STATE_EQUATION_A_STAR.value.Parameters.PARAM_TRACE_COST_FUNCTION] = trace_cost_function
        ali = alignments.apply(l, net, m0, mf, parameters=parameters, variant=versions.dijkstra_no_heuristics)
        if ali == None:
            vizu.apply(net, m0, mf).view()
        sum+=ali['cost']
    return sum
def get_alignments_decoration(net, im, fm, log=None, aligned_traces=None, parameters=None):
    """
    Get a decoration for the Petri net based on alignments

    Parameters
    -------------
    net
        Petri net
    im
        Initial marking
    fm
        Final marking
    log
        Event log
    aligned_traces
        Aligned traces
    parameters
        Parameters of the algorithm

    Returns
    -------------
    decorations
        Decorations to use
    """
    if parameters is None:
        parameters = {}
    if aligned_traces is None and log is not None:
        from pm4py.algo.conformance.alignments import algorithm as alignments
        aligned_traces = alignments.apply(log, net, im, fm, parameters={"ret_tuple_as_trans_desc": True})
    decorations = {}
    net_transitions = {}
    for trans in net.transitions:
        net_transitions[trans.name] = trans
    for align_trace0 in aligned_traces:
        align_trace = align_trace0["alignment"]
        for move in align_trace:
            move_trans_name = move[0][1]
            activity_trace_name = move[0][0]
            if move_trans_name in net_transitions:
                trans = net_transitions[move_trans_name]
                if trans not in decorations:
                    decorations[trans] = {"count_fit": 0, "count_move_on_model": 0}

                if activity_trace_name == ">>":
                    decorations[trans]["count_move_on_model"] = decorations[trans]["count_move_on_model"] + 1
                else:
                    decorations[trans]["count_fit"] = decorations[trans]["count_fit"] + 1

    for trans in decorations:
        if trans.label is not None:
            decorations[trans]["label"] = trans.label + " (" + str(
                decorations[trans]["count_move_on_model"]) + "," + str(decorations[trans]["count_fit"]) + ")"
            decorations[trans]["color"] = get_transitions_color(decorations[trans]["count_move_on_model"],
                                                                decorations[trans]["count_fit"])

    return decorations
def g():
    aa = time.time()
    aligned_traces = alignments.apply(
        Shared.log,
        Shared.net,
        Shared.im,
        Shared.fm,
        variant=alignments.Variants.VERSION_DIJKSTRA_NO_HEURISTICS)
    bb = time.time()
    print(bb - aa)
def f():
    aa = time.time()
    aligned_traces = alignments.apply(
        Shared.log,
        Shared.net,
        Shared.im,
        Shared.fm,
        variant=alignments.Variants.VERSION_DIJKSTRA_LESS_MEMORY)
    bb = time.time()
    print(bb - aa)
Esempio n. 11
0
 def test_inductiveminer_log(self):
     log = xes_importer.apply(
         os.path.join("input_data", "running-example.xes"))
     net, im, fm = inductive_miner.apply(log)
     aligned_traces_tr = tr_alg.apply(log, net, im, fm)
     aligned_traces_alignments = align_alg.apply(log, net, im, fm)
     evaluation = eval_alg.apply(log, net, im, fm)
     fitness = rp_fit.apply(log, net, im, fm)
     precision = precision_evaluator.apply(log, net, im, fm)
     gen = generalization.apply(log, net, im, fm)
     sim = simplicity.apply(net)
Esempio n. 12
0
 def test_alphaminer_df(self):
     log = pd.read_csv(os.path.join("input_data", "running-example.csv"))
     log = dataframe_utils.convert_timestamp_columns_in_df(log)
     net, im, fm = alpha_miner.apply(log)
     aligned_traces_tr = tr_alg.apply(log, net, im, fm)
     aligned_traces_alignments = align_alg.apply(log, net, im, fm)
     evaluation = eval_alg.apply(log, net, im, fm)
     fitness = rp_fit.apply(log, net, im, fm)
     precision = precision_evaluator.apply(log, net, im, fm)
     gen = generalization.apply(log, net, im, fm)
     sim = simplicity.apply(net)
Esempio n. 13
0
 def test_inductiveminer_stream(self):
     df = pd.read_csv(os.path.join("input_data", "running-example.csv"))
     df = dataframe_utils.convert_timestamp_columns_in_df(df)
     stream = log_conversion.apply(df,
                                   variant=log_conversion.TO_EVENT_STREAM)
     net, im, fm = inductive_miner.apply(stream)
     aligned_traces_tr = tr_alg.apply(stream, net, im, fm)
     aligned_traces_alignments = align_alg.apply(stream, net, im, fm)
     evaluation = eval_alg.apply(stream, net, im, fm)
     fitness = rp_fit.apply(stream, net, im, fm)
     precision = precision_evaluator.apply(stream, net, im, fm)
     gen = generalization.apply(stream, net, im, fm)
     sim = simplicity.apply(net)
Esempio n. 14
0
def conformance_diagnostics_alignments(log: EventLog, *args) -> List[Dict[str, Any]]:
    """
    Apply the alignments algorithm between a log and a process model.
    The methods return the full alignment diagnostics.

    Parameters
    -------------
    log
        Event log
    args
        Specification of the process model

    Returns
    -------------
    aligned_traces
        A list of alignments for each trace of the log (in the same order as the traces in the event log)
    """
    if len(args) == 3:
        if type(args[0]) is PetriNet:
            # Petri net alignments
            from pm4py.algo.conformance.alignments import algorithm as alignments
            return alignments.apply(log, args[0], args[1], args[2])
        elif type(args[0]) is dict or type(args[0]) is Counter:
            # DFG alignments
            from pm4py.objects.dfg.utils import dfg_alignment
            return dfg_alignment.apply(log, args[0], args[1], args[2])
    elif len(args) == 1:
        if type(args[0]) is ProcessTree:
            # process tree alignments
            from pm4py.algo.conformance.tree_alignments import algorithm as tree_alignments
            return tree_alignments.apply(log, args[0])
    # try to convert to Petri net
    import pm4py
    from pm4py.algo.conformance.alignments import algorithm as alignments
    net, im, fm = pm4py.convert_to_petri_net(*args)
    return alignments.apply(log, net, im, fm)
 def test_alignment_pnml(self):
     # to avoid static method warnings in tests,
     # that by construction of the unittest package have to be expressed in such way
     self.dummy_variable = "dummy_value"
     log = xes_importer.apply(
         os.path.join(INPUT_DATA_DIR, "running-example.xes"))
     net, marking, final_marking = inductive_miner.apply(log)
     for trace in log:
         cf_result = \
         align_alg.apply(trace, net, marking, final_marking, variant=align_alg.VERSION_DIJKSTRA_NO_HEURISTICS)[
             'alignment']
         is_fit = True
         for couple in cf_result:
             if not (couple[0] == couple[1]
                     or couple[0] == ">>" and couple[1] is None):
                 is_fit = False
         if not is_fit:
             raise Exception("should be fit")
Esempio n. 16
0
def execute_script():
    log = pm4py.read_xes(
        os.path.join("..", "tests", "input_data", "receipt.xes"))
    print("number of cases", len(log))
    print("number of events", sum(len(x) for x in log))
    print("number of variants", len(pm4py.get_variants(log)))
    ac = get.get_attribute_values(log, "concept:name")
    dfg, sa, ea = pm4py.discover_dfg(log)
    perc = 0.5
    dfg, sa, ea, ac = dfg_filtering.filter_dfg_on_activities_percentage(
        dfg, sa, ea, ac, perc)
    dfg, sa, ea, ac = dfg_filtering.filter_dfg_on_paths_percentage(
        dfg, sa, ea, ac, perc)
    aa = time.time()
    aligned_traces = dfg_alignment.apply(log, dfg, sa, ea)
    bb = time.time()
    net, im, fm = pm4py.convert_to_petri_net(dfg, sa, ea)
    for trace in aligned_traces:
        if trace["cost"] != trace["internal_cost"]:
            print(trace)
            pass
    print(bb - aa)
    print(sum(x["visited_states"] for x in aligned_traces))
    print(sum(x["cost"] // 10000 for x in aligned_traces))
    gviz = visualizer.apply(dfg,
                            activities_count=ac,
                            parameters={
                                "start_activities": sa,
                                "end_activities": ea,
                                "format": "svg"
                            })
    visualizer.view(gviz)
    cc = time.time()
    aligned_traces2 = petri_alignments.apply(
        log,
        net,
        im,
        fm,
        variant=petri_alignments.Variants.VERSION_DIJKSTRA_LESS_MEMORY)
    dd = time.time()
    print(dd - cc)
    print(sum(x["visited_states"] for x in aligned_traces2))
    print(sum(x["cost"] // 10000 for x in aligned_traces2))
Esempio n. 17
0
def conformance_alignments(log, petri_net, initial_marking, final_marking):
    """
    Apply the alignments algorithm between a log and a Petri net

    Parameters
    -------------
    log
        Event log
    petri_net
        Petri net
    initial_marking
        Initial marking
    final_marking
        Final marking

    Returns
    -------------
    aligned_traces
        A list of alignments for each trace of the log
    """
    from pm4py.algo.conformance.alignments import algorithm as alignments
    return alignments.apply(log, petri_net, initial_marking, final_marking)
Esempio n. 18
0
        t0 = time.time()
        token_replay.apply(a32f0n00_log, a32f0n00_net, a32f0n00_im,
                           a32f0n00_fm)
        t1 = time.time()
        T3[0] = (t1 - t0)
        T3[2] = math.ceil(T3[1] / (T3[0] + 0.00000001) * 1000.0)
        print(
            "TEST 3 - Applying token-based replay between A32F0N00 log and model - %.5f s (test score: %d)"
            % (T3[0], T3[2]))

    if ENABLE_TESTS:
        # TEST 4: perform alignments between A32F0N00 log and model
        t0 = time.time()
        alignments.apply(
            a32f0n00_log,
            a32f0n00_net,
            a32f0n00_im,
            a32f0n00_fm,
            variant=alignments.Variants.VERSION_DIJKSTRA_NO_HEURISTICS)
        t1 = time.time()
        T4[0] = (t1 - t0)
        T4[2] = math.ceil(T4[1] / (T4[0] + 0.00000001) * 1000.0)
        print(
            "TEST 4 - Applying alignments between A32F0N00 log and model - %.5f s (test score: %d)"
            % (T4[0], T4[2]))

    if ENABLE_TESTS:
        # TEST 5: perform playout of the a32f0n00 Petri net
        t0 = time.time()
        playout.apply(a32f0n00_net, a32f0n00_im, a32f0n00_fm)
        t1 = time.time()
        T5[0] = (t1 - t0)
Esempio n. 19
0
createAlignments.py : compute alignment costs with pm4py 
'''

# read parameter : python3 createAlignments.py output_file xes_file pnml_file
argv=sys.argv
filename=argv[1]
net, m0, mf = importer.importer.apply(argv[3])
log = xes_importer.apply(argv[2])

# compute alignment for variants only
variants = get_variants.get_variants(log)


start=time.time()
for l in variants:
    ali=alignments.apply(variants[l][0],net, m0,mf,variant=versions.dijkstra_no_heuristics)
    # export in a CSV file with : trace, trace with moves, run, run with moves, cost, frequency
    if ali:
        writer=open(filename,"a")
        alignment=ali["alignment"]
        cost=ali["cost"]
        phrase1=""
        phrase1None=""
        phrase2=""
        phrase2None=""
        for (a,b) in alignment:
            if a!=">>":
                # activities are separated with :::
                phrase1+=a+":::"
            phrase1None+=a+":::"
            if b!=">>" and b!=None:
Esempio n. 20
0
 def test_align(self):
     log = pm4py.read_xes("input_data/running-example.xes")
     net, im, fm = pm4py.discover_petri_net_inductive(log,
                                                      noise_threshold=0.2)
     aligned_traces = alignments.apply(log, net, im, fm)
     diagn_df = alignments.get_diagnostics_dataframe(log, aligned_traces)
Esempio n. 21
0
def get_attributes(log,
                   decision_points,
                   attributes,
                   use_trace_attributes,
                   trace_attributes,
                   k,
                   net,
                   initial_marking,
                   final_marking,
                   decision_points_names,
                   parameters=None):
    """
    This method aims to construct for each decision place a table where for each decision place a list if given with the
     label of the later decision and as value the given attributes
    :param log: Log on which the method is applied
    :param alignments: Computed alignments for a log and a model
    :param decision_points: Places that have multiple outgoing arcs
    :param attributes: Attributes that are considered
    :param use_trace_attributes: If trace attributes have to be considered or not
    :param trace_attributes: List of trace attributes that are considered
    :param k: Taking k last activities into account
    :return: Dictionary that has as keys the decision places. The value for this key is a list.
    The content of these lists are tuples. The first element of these tuples is information regrading the attributes,
    the second element of these tuples is the transition which chosen in a decision.
    """
    if parameters is None:
        parameters = {}
    I = {}
    for key in decision_points:
        I[key] = []
    A = {}
    for attri in attributes:
        A[attri] = None
    i = 0
    # first, take a look at the variants
    variants_idxs = variants_module.get_variants_from_log_trace_idx(
        log, parameters=parameters)
    one_variant = []
    for variant in variants_idxs:
        one_variant.append(variant)
        # TODO: Token based replay code mit paramter für nur varianten einbeziehen ausstatten
    replay_result = token_replay.apply(log,
                                       net,
                                       initial_marking,
                                       final_marking,
                                       parameters=parameters)
    replay_result = simplify_token_replay(replay_result)
    count = 0
    for variant in replay_result:
        if variant['trace_fitness'] == 1.0:
            for trace_index in variants_idxs[one_variant[count]]:
                last_k_list = [None] * k
                trace = log[trace_index]
                if use_trace_attributes:
                    for attribute in trace_attributes:
                        # can be done here since trace attributes does not change for whole trace
                        A[attribute] = trace.attributes[attribute]
                j = 0
                # j is a pointer which points to the current event inside a trace
                for transition in variant['activated_transitions']:
                    for key, value in decision_points_names.items():
                        if transition.label in value:
                            for element in last_k_list:
                                if element != None:
                                    if transition.label != None:
                                        I[key].append(
                                            (element.copy(), transition.label))
                                    else:
                                        I[key].append(
                                            (element.copy(), transition.name))
                    for attri in attributes:
                        # print(variant, transition.label, j)
                        if attri in trace[j]:
                            # only add the attribute information if it is present in the event
                            A[attri] = trace[j][attri]
                    # add A to last_k_list. Using modulo to access correct entry
                    last_k_list[j % k] = A.copy()
                    if transition.label != None:
                        if not j + 1 >= len(trace):
                            # Problem otherwise: If there are tau-transition after the last event related transition,
                            # the pointer j which points to the current event in a trace, gets out of range
                            j += 1
        else:
            example_trace = log[variants_idxs[one_variant[count]][0]]
            align_parameters = copy(parameters)
            align_parameters[star.Parameters.
                             PARAM_ALIGNMENT_RESULT_IS_SYNC_PROD_AWARE] = True
            alignment = ali.apply(example_trace,
                                  net,
                                  initial_marking,
                                  final_marking,
                                  parameters=align_parameters)['alignment']
            for trace_index in variants_idxs[one_variant[count]]:
                last_k_list = [None] * k
                trace = log[trace_index]
                if use_trace_attributes:
                    for attribute in trace_attributes:
                        # can be done here since trace attributes does not change for whole trace
                        A[attribute] = trace.attributes[attribute]
                j = 0
                for el in alignment:
                    if el[1][1] != '>>':
                        # If move in model
                        for key, value in decision_points.items():
                            if el[0][1] in value:
                                for element in last_k_list:
                                    if element != None:
                                        # only add those entries where information is provided
                                        if el[1][1] == None:
                                            # for some dt algorithms, the entry None might be a problem, since it is left out later
                                            I[key].append(
                                                (element.copy(), el[0][1]))
                                        else:
                                            I[key].append(
                                                (element.copy(), el[1][1]))
                    if el[1][0] != '>>' and el[1][1] != '>>':
                        # If there is a move in log and model
                        for attri in attributes:
                            if attri in trace[j]:
                                # only add the attribute information if it is present in the event
                                A[attri] = trace[j][attri]
                        # add A to last_k_list. Using modulo to access correct entry
                        last_k_list[j % k] = A.copy()
                    if el[1][0] != '>>':
                        # only go to next event in trace if the current event has been aligned
                        # TODO: Discuss if this is correct or can lead to problems
                        j += 1
        count += 1
    return I