Ejemplo n.º 1
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.import_net(
         os.path.join(INPUT_DATA_DIR, "running-example.pnml"))
     soundness = check_soundness.check_petri_wfnet_and_soundness(
         imported_petri1)
     del soundness
     log = xes_importer.import_log(
         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_factory.apply(
             trace,
             imported_petri1,
             marking1,
             final_marking,
             version=align_factory.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 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 factory as alignments_factory
        aligned_traces = alignments_factory.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
Ejemplo n.º 3
0
 def clean_log_from_non_fitting_traces(log,
                                       model,
                                       i_m,
                                       f_m,
                                       occurence=False):
     activities = Utility.get_activities(log)
     #filter event log. The perfect fitting traces are kept. However, for unfitting traces, we keep the alligned event log
     replay_result = alignments.apply(log, model, i_m, f_m)
     return Utility.get_perfect_fitting_trace_variants_and_number_of_occurence(
         replay_result, activities, occurence)
Ejemplo n.º 4
0
def perform_alignments(log, petri_string, parameters=None):
    """
    Perform alignments

    Parameters
    ------------
    log
        Log
    net
        Petri net
    parameters
        Parameters of the algorithm

    Returns
    -------------
    petri
        SVG of the decorated Petri
    table
        SVG of the decorated table
    """
    if parameters is None:
        parameters = {}

    net, im, fm = pnml.import_petri_from_string(petri_string,
                                                parameters=parameters)

    parameters_align = copy(parameters)
    parameters_align["ret_tuple_as_trans_desc"] = True

    alignments = align_factory.apply(log,
                                     net,
                                     im,
                                     fm,
                                     parameters=parameters_align)
    decorations = alignments_decoration.get_alignments_decoration(
        net, im, fm, aligned_traces=alignments, parameters=parameters)

    gviz_on_petri = pn_vis_factory.apply(net,
                                         im,
                                         fm,
                                         aggregated_statistics=decorations,
                                         variant="alignments",
                                         parameters={"format": "svg"})
    svg_on_petri = get_base64_from_gviz(gviz_on_petri)

    parameters_table = copy(parameters)
    parameters_table["format"] = "svg"

    gviz_table = align_table_factory.apply(log,
                                           alignments,
                                           parameters=parameters_table)
    svg_table = get_base64_from_gviz(gviz_table)

    return svg_on_petri, svg_table
Ejemplo n.º 5
0
 def test_heu_log(self):
     log = xes_importer.apply(
         os.path.join("input_data", "running-example.xes"))
     net, im, fm = heuristics_miner.apply(log)
     aligned_traces_tr = tr_factory.apply(log, net, im, fm)
     aligned_traces_alignments = align_factory.apply(log, net, im, fm)
     evaluation = eval_factory.apply(log, net, im, fm)
     fitness = rp_fit_factory.apply(log, net, im, fm)
     precision = precision_factory.apply(log, net, im, fm)
     generalization = generalization_factory.apply(log, net, im, fm)
     simplicity = simplicity_factory.apply(net)
Ejemplo n.º 6
0
 def test_inductiveminer_df(self):
     log = csv_import_adapter.import_dataframe_from_path(
         os.path.join("input_data", "running-example.csv"))
     net, im, fm = inductive_miner.apply(log)
     aligned_traces_tr = tr_factory.apply(log, net, im, fm)
     aligned_traces_alignments = align_factory.apply(log, net, im, fm)
     evaluation = eval_factory.apply(log, net, im, fm)
     fitness = rp_fit_factory.apply(log, net, im, fm)
     precision = precision_factory.apply(log, net, im, fm)
     generalization = generalization_factory.apply(log, net, im, fm)
     simplicity = simplicity_factory.apply(net)
Ejemplo n.º 7
0
 def test_inductiveminer_stream(self):
     stream = csv_importer.apply(
         os.path.join("input_data", "running-example.csv"))
     net, im, fm = inductive_miner.apply(stream)
     aligned_traces_tr = tr_factory.apply(stream, net, im, fm)
     aligned_traces_alignments = align_factory.apply(stream, net, im, fm)
     evaluation = eval_factory.apply(stream, net, im, fm)
     fitness = rp_fit_factory.apply(stream, net, im, fm)
     precision = precision_factory.apply(stream, net, im, fm)
     generalization = generalization_factory.apply(stream, net, im, fm)
     simplicity = simplicity_factory.apply(net)
Ejemplo n.º 8
0
 def test_alignment(self):
     log = xes_importer.apply(
         os.path.join("input_data", "running-example.xes"))
     from pm4py.algo.discovery.alpha import factory as alpha_miner
     net, im, fm = alpha_miner.apply(log)
     from pm4py.algo.conformance.alignments import factory as alignments
     aligned_traces = alignments.apply(
         log, net, im, fm, version=alignments.VERSION_STATE_EQUATION_A_STAR)
     aligned_traces = alignments.apply(
         log,
         net,
         im,
         fm,
         version=alignments.VERSION_DIJKSTRA_NO_HEURISTICS)
     from pm4py.evaluation.replay_fitness import factory as rp_fitness_evaluator
     fitness = rp_fitness_evaluator.apply(
         log, net, im, fm, variant=rp_fitness_evaluator.ALIGNMENT_BASED)
     evaluation = rp_fitness_evaluator.evaluate(
         aligned_traces, variant=rp_fitness_evaluator.ALIGNMENT_BASED)
     from pm4py.evaluation.precision import factory as precision_evaluator
     precision = precision_evaluator.apply(
         log, net, im, fm, variant=precision_evaluator.ALIGN_ETCONFORMANCE)
Ejemplo n.º 9
0
 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.import_log(os.path.join(INPUT_DATA_DIR, "running-example.xes"))
     net, marking, final_marking = inductive_miner.apply(log)
     for trace in log:
         cf_result = align_factory.apply(trace, net, marking, final_marking, version=align_factory.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")
#-----------------

from pm4py.objects.log.importer.csv import factory as csv_importer
excellentLog1A = csv_importer.import_event_stream('Excellent1A_fixed.csv')
from pm4py.objects.conversion.log import factory as conversion_factory
log1 = conversion_factory.apply(excellentLog1A)

from pm4py.visualization.dfg import factory as dfg_vis_factory

gviz = dfg_vis_factory.apply(dfg1, log=log1, variant="frequency")
dfg_vis_factory.view(gviz)

from pm4py.objects.conversion.dfg import factory as dfg_mining_factory

net, im, fm = dfg_mining_factory.apply(dfg1)

from pm4py.visualization.petrinet import factory as pn_vis_factory

gviz = pn_vis_factory.apply(net, im, fm)
pn_vis_factory.view(gviz)

from pm4py.evaluation.replay_fitness import factory as replay_factory
fitness_alpha = replay_factory.apply(log1, net, im, fm)

from pm4py.algo.conformance.alignments import factory as align_factory

alignments = align_factory.apply(log1, net, im, fm)

print(alignments)

#excellentLog1A = excellentLog1A.sort_values(by=['org:resource','case','time:timestamp'])
Ejemplo n.º 11
0
def apply(log, parameters=None):
    """
    Returns a log from which a sound workflow net could be extracted taking into account
    a discovery algorithm returning models only with visible transitions

    Parameters
    ------------
    log
        Trace log
    parameters
        Possible parameters of the algorithm, including:
            discovery_algorithm -> Discovery algorithm to consider, possible choices: alphaclassic
            max_no_variants -> Maximum number of variants to consider to return a Petri net

    Returns
    ------------
    filtered_log
        Filtered trace log
    """
    if parameters is None:
        parameters = {}
    discovery_algorithm = parameters[
        "discovery_algorithm"] if "discovery_algorithm" in parameters else "alphaclassic"
    max_no_variants = parameters[
        "max_no_variants"] if "max_no_variants" in parameters else 20
    all_variants_dictio = variants_filter.get_variants(log,
                                                       parameters=parameters)
    all_variants_list = []
    for var in all_variants_dictio:
        all_variants_list.append([var, len(all_variants_dictio[var])])
    all_variants_list = sorted(all_variants_list,
                               key=lambda x: (x[1], x[0]),
                               reverse=True)
    considered_variants = []
    considered_traces = []

    i = 0
    while i < min(len(all_variants_list), max_no_variants):
        variant = all_variants_list[i][0]

        considered_variants.append(variant)
        considered_traces.append(all_variants_dictio[variant][0])
        filtered_log = TraceLog(considered_traces)
        net = None
        initial_marking = None
        final_marking = None
        if discovery_algorithm == "alphaclassic" or discovery_algorithm == "alpha":
            net, initial_marking, final_marking = alpha_miner.apply(
                filtered_log, parameters=parameters)
        is_sound = check_soundness.check_petri_wfnet_and_soundness(net)
        if not is_sound:
            del considered_variants[-1]
            del considered_traces[-1]
        else:
            try:
                alignments = alignment_factory.apply(filtered_log, net,
                                                     initial_marking,
                                                     final_marking)
                del alignments
                fitness = replay_fitness_factory.apply(filtered_log,
                                                       net,
                                                       initial_marking,
                                                       final_marking,
                                                       parameters=parameters)
                if fitness["log_fitness"] < 0.99999:
                    del considered_variants[-1]
                    del considered_traces[-1]
            except TypeError:
                del considered_variants[-1]
                del considered_traces[-1]
        i = i + 1

    sound_log = TraceLog()
    if considered_variants:
        sound_log = variants_filter.apply(log,
                                          considered_variants,
                                          parameters=parameters)

    return sound_log
Ejemplo n.º 12
0
def py_data_2019_demo_script():
    event_data = xes_log_importer.apply('<path_to_data>')
    model, marking_i, marking_f = pn_importer.apply('<path_to_model>')
    alignments = alignment_algorithm.apply(event_data, model, marking_i, marking_f)
    print(alignments)
def apply(df, parameters=None):
    """
    Returns a Pandas dataframe from which a sound workflow net could be extracted taking into account
    a discovery algorithm returning models only with visible transitions

    Parameters
    ------------
    df
        Pandas dataframe
    parameters
        Possible parameters of the algorithm, including:
            max_no_variants -> Maximum number of variants to consider to return a Petri net

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

    if PARAMETER_CONSTANT_CASEID_KEY not in parameters:
        parameters[PARAMETER_CONSTANT_CASEID_KEY] = CASE_CONCEPT_NAME
    if PARAMETER_CONSTANT_ACTIVITY_KEY not in parameters:
        parameters[PARAMETER_CONSTANT_ACTIVITY_KEY] = DEFAULT_NAME_KEY
    if PARAMETER_CONSTANT_TIMESTAMP_KEY not in parameters:
        parameters[PARAMETER_CONSTANT_TIMESTAMP_KEY] = DEFAULT_TIMESTAMP_KEY
    if PARAMETER_CONSTANT_ATTRIBUTE_KEY not in parameters:
        parameters[PARAMETER_CONSTANT_ATTRIBUTE_KEY] = parameters[
            PARAMETER_CONSTANT_ACTIVITY_KEY]

    caseid_glue = parameters[PARAMETER_CONSTANT_CASEID_KEY]
    activity_key = parameters[PARAMETER_CONSTANT_ACTIVITY_KEY]
    timest_key = parameters[PARAMETER_CONSTANT_TIMESTAMP_KEY]

    max_no_variants = parameters[
        "max_no_variants"] if "max_no_variants" in parameters else 20

    variants_df = case_statistics.get_variants_df(df, parameters=parameters)
    parameters["variants_df"] = variants_df

    variant_stats = case_statistics.get_variant_statistics(
        df, parameters=parameters)

    all_variants_list = []
    for var in variant_stats:
        all_variants_list.append([var["variant"], var[caseid_glue]])

    all_variants_list = sorted(all_variants_list,
                               key=lambda x: (x[1], x[0]),
                               reverse=True)

    considered_variants = []
    considered_traces = []

    i = 0
    while i < min(len(all_variants_list), max_no_variants):
        variant = all_variants_list[i][0]

        considered_variants.append(variant)

        filtered_df = variants_filter.apply(df,
                                            considered_variants,
                                            parameters=parameters)

        dfg_frequency = dfg_util.get_dfg_graph(filtered_df,
                                               measure="frequency",
                                               perf_aggregation_key="median",
                                               case_id_glue=caseid_glue,
                                               activity_key=activity_key,
                                               timestamp_key=timest_key)

        net, initial_marking, final_marking = alpha_miner.apply_dfg(
            dfg_frequency, parameters=parameters)

        is_sound = check_soundness.check_petri_wfnet_and_soundness(net)
        if not is_sound:
            del considered_variants[-1]
        else:
            traces_of_this_variant = variants_filter.apply(
                df, [variant], parameters=parameters).groupby(caseid_glue)
            traces_of_this_variant_keys = list(
                traces_of_this_variant.groups.keys())
            trace_of_this_variant = traces_of_this_variant.get_group(
                traces_of_this_variant_keys[0])

            this_trace = transform.transform_event_log_to_trace_log(
                pandas_df_imp.convert_dataframe_to_event_log(
                    trace_of_this_variant),
                case_glue=caseid_glue)[0]
            if not activity_key == DEFAULT_NAME_KEY:
                for j in range(len(this_trace)):
                    this_trace[j][DEFAULT_NAME_KEY] = this_trace[j][
                        activity_key]
            considered_traces.append(this_trace)
            filtered_log = TraceLog(considered_traces)

            try:
                alignments = alignment_factory.apply(filtered_log, net,
                                                     initial_marking,
                                                     final_marking)
                del alignments
                fitness = replay_fitness_factory.apply(filtered_log,
                                                       net,
                                                       initial_marking,
                                                       final_marking,
                                                       parameters=parameters)
                if fitness["log_fitness"] < 0.99999:
                    del considered_variants[-1]
                    del considered_traces[-1]
            except TypeError:
                del considered_variants[-1]
                del considered_traces[-1]

        i = i + 1

    return variants_filter.apply(df,
                                 considered_variants,
                                 parameters=parameters)