Exemple #1
0
    def calculate_accuracy(H,
                           X_train,
                           X_test,
                           train_ind,
                           test_ind,
                           W,
                           return_output,
                           s=0.5):  # all that is needed to propagate
        H0c = to_centering_beliefs(H)

        eps_max = eps_convergence_linbp_parameterized(H0c,
                                                      W,
                                                      method='noecho',
                                                      alpha=alpha,
                                                      beta=beta,
                                                      gamma=gamma,
                                                      X=X2)

        eps = s * eps_max

        F, actualIt, actualPercentageConverged = \
            linBP_symmetric_parameterized(X_train, W, H*eps,
                                          method='noecho',
                                          alpha=alpha, beta=beta, gamma=gamma,
                                          numMaxIt=numMax,
                                          convergencePercentage=0.99,
                                          convergenceThreshold=0.99,
                                          debug=2)

        n, k = F.shape
        for i in range(n):
            if i not in test_ind:
                F[i] = np.zeros(k)

        accuracy_X = matrix_difference(X_test,
                                       F,
                                       ignore_rows=list(train_ind),
                                       similarity='accuracy')

        print("Holdout accuracy: {}".format(accuracy_X))
        return_output.put(accuracy_X)  ## For Parallel
Exemple #2
0
    def calculate_accuracy(H, X_train, X_test, train_ind, test_ind, W, s=0.5):
        """Propagates from X_train numMax times, calculates accuracy over X_test
        """
        H0c = to_centering_beliefs(H)
        eps_max = eps_convergence_linbp_parameterized(
            H0c,
            W,  # TODO: an optimized version could attempt to calculate the spectral radius fewer times and re-use it for multiple splits
            method='noecho',
            alpha=alpha,
            beta=beta,
            gamma=gamma,
            X=X2)
        eps = s * eps_max
        F, actualIt, actualPercentageConverged = linBP_symmetric_parameterized(
            X_train,
            W,
            H * eps,
            method='noecho',
            alpha=alpha,
            beta=beta,
            gamma=gamma,
            numMaxIt=numMax,
            convergencePercentage=0.99,
            convergenceThreshold=0.99,
            debug=2)
        n, k = F.shape
        for i in range(n):
            if i not in test_ind:
                F[i] = np.zeros(k)

        # TODO For label imbalance, better to use CLASSWISE (macro-averaging) here
        accuracy_X = matrix_difference(X_test,
                                       F,
                                       ignore_rows=list(train_ind),
                                       similarity='accuracy')
        # print("accuracy now is {}".format(accuracy_X))
        return accuracy_X
def run(choice,
        variant,
        create_data=False,
        add_data=False,
        create_graph=False,
        create_fig=True,
        show_plot=False,
        create_pdf=False,
        show_pdf=False,
        shorten_length=False,
        show_arrows=True):
    """main parameterized method to produce all figures.
    Can be run from external jupyther notebook or method to produce all figures in PDF
    """

    # -- Setup
    CHOICE = choice  # determines the CSV data file to use
    VARIANT = variant  # determines the variant of how the figures are plotted
    CREATE_DATA = create_data  # starts new CSV file and stores experimental timing results
    ADD_DATA = add_data  # adds data to existing file
    CREATE_GRAPH = create_graph  # creates the actual graph for experiments (stores W and X in CSV files)

    SHOW_PDF = show_pdf
    SHOW_PLOT = show_plot
    CREATE_FIG = create_fig
    CREATE_PDF = create_pdf
    SHORTEN_LENGTH = shorten_length  # to prune certain fraction of data to plot
    SHOW_SCALING_LABELS = True  # first entry in the legend is for the dashed line of scalability
    SHOW_TITLE = True  # show parameters in title of plot
    SHOW_DCER_WITH_BOX = True  # show DCER value in a extra box
    LABEL_FONTSIZE = 16  # size of number labels in figure
    SHOW_LINEAR = True  # show dashed line for linear scaling

    SHOW_ARROWS = show_arrows  # show extra visual comparison of speed-up

    csv_filename = 'Fig_Timing_{}.csv'.format(
        CHOICE)  # CSV filename includes CHOICE
    filename = 'Fig_Timing_{}-{}'.format(
        CHOICE, VARIANT)  # PDF filename includes CHOICE and VARIANT
    header = ['n', 'type', 'time']
    if CREATE_DATA:
        save_csv_record(join(data_directory, csv_filename),
                        header,
                        append=False)

    # -- Default Graph parameters
    distribution = 'powerlaw'
    exponent = -0.3
    k = 3
    a = 1  # this value was erroneously set to 5 previously!!! TODO: fix everywhere else
    # err = 0
    avoidNeighbors = False
    f = 0.1
    est_EC = True  # !!! TODO: for graph estimation
    weights = 10
    pyamg = False
    convergencePercentage_W = None
    alpha = 0
    beta = 0
    gamma = 0
    s = 0.5
    numMaxIt = 10
    xtick_lab = [0.001, 0.01, 0.1, 1]
    ytick_lab = np.arange(0, 1, 0.1)
    xmin = 1e2
    xmax = 1e8
    # xmax = 1e6
    ymin = 1e-3
    ymax = 5e3
    color_vec = [
        "#4C72B0", "#55A868", "#8172B2", "#C44E52", "#CCB974", 'black',
        'black', "#64B5CD", "black"
    ]
    marker_vec = ['s', '^', 'x', 'o', 'None', 'None', 'None', 'None']
    linestyle_vec = ['solid'] * 6 + ['dashed']
    linewidth_vec = [3] * 3 + [4, 3, 4] + [3] * 7
    SHOWMAXNUMBER = True
    show_num_vec = ['MHE', 'LHE', 'DHE', 'DHEr', 'Holdout', 'prop', 'eps_max']

    # %% -- Main Options
    if CHOICE == 3:
        n_vec = [
            100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200, 102400,
            204800, 409600, 819200, 1638400, 3276800, 6553600
        ]
        # # n_vec = [1638400]  # graph:  12021 sec = 3.4h, 18600 sec = 5h, 21824 sec (34000 sec old laptop)
        # # n_vec = [3276800]  # graph:  49481 sec = 13.8h, 68145 sec (125233 sec old laptop)
        # # n_vec = [6553600]  # graph: 145020 sec = 40h
        h = 8
        d = 5

        repeat_vec_vec = [[
            50, 50, 50, 50, 50, 50, 50, 20, 10, 10, 5, 5, 5, 3, 3, 3, 3
        ], [5, 5, 5, 5, 3, 3, 3, 3, 3, 1,
            1], [20, 20, 20, 10, 10, 10, 10, 10, 5, 5, 5, 3, 3, 1, 1, 1, 1]]
        method_vec_vec = [['MHE', 'DHE', 'DHEr', 'LHE'], ['Holdout'], ['prop']]

        if VARIANT == 1:
            method_vec_fig = ['MHE', 'LHE', 'DHE', 'DHEr', 'Holdout', 'prop']
            label_vec = ['MCE', 'LCE', 'DCE', 'DCEr', 'Holdout', 'prop']
            show_num_vec = ['MHE', 'LHE', 'DHE', 'DHEr', 'Holdout', 'prop']

        if VARIANT == 2:  # version used for main paper figure
            method_vec_fig = ['MHE', 'LHE', 'DHE', 'DHEr', 'Holdout', 'prop']
            label_vec = ['MCE', 'LCE', 'DCE', 'DCEr', 'Holdout', 'prop']
            linestyle_vec = ['solid'] * 5 + ['dashed']
            SHOW_ARROWS = False

        if VARIANT == 3:  # version used for main paper figure
            method_vec_fig = ['DHEr', 'Holdout', 'prop']
            label_vec = [
                'DCEr', 'Holdout', 'Propagation', '$\epsilon_{\mathrm{max}}$'
            ]
            linestyle_vec = ['solid'] * 2 + ['dashed']
            color_vec = [
                "#C44E52", "#CCB974", 'black', 'black', "#64B5CD", "black"
            ]
            marker_vec = ['o', 'x', 'None', 'None', 'None']
            linestyle_vec = ['solid'] * 3 + ['dashed']
            linewidth_vec = [4, 3, 4] + [3] * 7
            ymin = 1e-2
            SHOW_ARROWS = True

        if VARIANT == 4:  # figure used in slides
            method_vec_fig = ['prop']
            label_vec = ['Propagation']
            color_vec = ['black']
            marker_vec = ['None']
            linestyle_vec = ['solid'] * 1
            linewidth_vec = [2]
            ymin = 1e-2
            SHOW_ARROWS = False
            SHOW_SCALING_LABELS = False
            SHOW_TITLE = False
            SHOW_DCER_WITH_BOX = False
            LABEL_FONTSIZE = 20
            SHOW_LINEAR = False

        if VARIANT == 5:  # figure used in slides
            method_vec_fig = ['prop', 'Holdout']
            label_vec = ['Propagation', 'Baseline']
            color_vec = ['black', "#CCB974"]
            marker_vec = ['None', '^']
            linestyle_vec = ['solid'] * 2
            linewidth_vec = [2, 4]
            ymin = 1e-2
            SHOW_ARROWS = True
            SHOW_SCALING_LABELS = False
            SHOW_TITLE = False
            SHOW_DCER_WITH_BOX = False
            LABEL_FONTSIZE = 20
            SHOW_LINEAR = False

        if VARIANT == 6:  # figure used in slides
            method_vec_fig = ['prop', 'Holdout', 'DHEr']
            label_vec = ['Propagation', 'Baseline', 'Our method']
            color_vec = ['black', "#CCB974", "#C44E52"]
            marker_vec = ['None', '^', 'o', 'None', 'None']
            linestyle_vec = ['solid'] + ['solid'] * 2
            linewidth_vec = [2, 4, 4]
            ymin = 1e-2
            SHOW_ARROWS = True
            SHOW_SCALING_LABELS = False
            SHOW_TITLE = True
            SHOW_DCER_WITH_BOX = False
            LABEL_FONTSIZE = 20
            SHOW_LINEAR = False

        graph_cvs = 'Fig_Timing_SSLH_1'  # re-use existing large graphs

    elif CHOICE == 4:
        n_vec = [
            200,
            400,
            800,
            1600,
            3200,
            6400,
            12800,
            25600,
            51200,
            102400,
            204800,
            409600,
            819200,
        ]
        # n_vec = [819200]    # graph: 47905 sec = 13.3h. 90562 sec = 25h (180527 sec old laptop)
        h = 3
        d = 25
        repeat_vec_vec = [[
            50,
            50,
            50,
            50,
            50,
            50,
            20,
            10,
            10,
            5,
            3,
            3,
            3,
        ], [5, 5, 5, 3, 1, 1, 1, 1, 1],
                          [
                              20,
                              20,
                              10,
                              10,
                              10,
                              10,
                              10,
                              5,
                              5,
                              5,
                              1,
                              1,
                              1,
                          ]]
        method_vec_vec = [['MHE', 'DHE', 'DHEr', 'LHE'], ['Holdout'], ['prop']]

        VARIANT = 2

        if VARIANT == 1:
            method_vec_fig = [
                'MHE', 'LHE', 'DHE', 'DHEr', 'Holdout', 'prop', 'eps_max'
            ]
            label_vec = [
                'MCE', 'LCE', 'DCE', 'DCEr', 'Holdout', 'prop',
                '$\epsilon_{\mathrm{max}}$'
            ]
            show_num_vec = [
                'MHE', 'LHE', 'DHE', 'DHEr', 'Holdout', 'prop', 'eps_max'
            ]

        if VARIANT == 2:
            method_vec_fig = ['MHE', 'LHE', 'DHE', 'DHEr', 'Holdout', 'prop']
            label_vec = ['MCE', 'LCE', 'DCE', 'DCEr', 'Holdout', 'prop']
            linestyle_vec = ['solid'] * 5 + ['dashed']

        if VARIANT == 3:
            method_vec_fig = ['DHEr', 'Holdout', 'prop']

            label_vec = [
                'DCEr', 'Holdout', 'Propagation', '$\epsilon_{\mathrm{max}}$'
            ]
            linestyle_vec = ['solid'] * 2 + ['dashed']
            color_vec = [
                "#C44E52", "#CCB974", 'black', 'black', "#64B5CD", "black"
            ]
            marker_vec = ['o', 'x', 'None', 'None', 'None']
            linestyle_vec = ['solid'] * 3 + ['dashed']
            linewidth_vec = [4, 3, 4] + [3] * 7
            ymin = 1e-2

        graph_cvs = 'Fig_Timing_SSLH_2'  # re-use existing large graphs
        xmin = 1e3
        xmax = 5e7
        ymax = 1e3

    elif CHOICE == 2:
        # rep_Estimation = 10
        # n_vec = [200, 400, 800, 1600, 3200, 6400, 12800,
        #          25600, 51200, 102400, 204800, 409600, 819200]
        # repeat_vec = [20, 20, 20, 20, 20, 10, 10,
        #               10, 10, 10, 5, 5, 1]
        # n_vec = [819200]    # graph: 47905 sec = 13.3h. 90562 sec = 25h (180527 sec old laptop)
        n_vec = [1638400]  # !!! not done yet
        repeat_vec = [1]
        h = 3
        d = 25
        xmax = 5e7
        graph_cvs = 'Fig_Timing_SSLH_2'

    elif CHOICE == 10:  # same as 3 but with difference bars
        n_vec = [
            100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200, 102400,
            204800, 409600, 819200, 1638400, 3276800, 6553600
        ]
        # # n_vec = [1638400]  # graph:  12021 sec = 3.4h, 18600 sec = 5h, 21824 sec (34000 sec old laptop)
        # # n_vec = [3276800]  # graph:  49481 sec = 13.8h, 68145 sec (125233 sec old laptop)
        # # n_vec = [6553600]  # graph: 145020 sec = 40h
        h = 8
        d = 5

        repeat_vec_vec = [[
            50, 50, 50, 50, 50, 50, 50, 20, 10, 10, 5, 5, 5, 3, 3, 3, 3
        ], [5, 5, 5, 5, 3, 3, 3, 3, 3, 1,
            1], [20, 20, 20, 10, 10, 10, 10, 10, 5, 5, 5, 3, 3, 1, 1, 1, 1]]
        method_vec_vec = [['MHE', 'DHE', 'DHEr', 'LHE'], ['Holdout'], ['prop']]

        method_vec_fig = ['DHEr', 'Holdout', 'prop']
        label_vec = [
            'DCEr', 'Holdout', 'Propagation', '$\epsilon_{\mathrm{max}}$'
        ]
        linestyle_vec = ['solid'] * 2 + ['dashed']
        color_vec = [
            "#C44E52", "#CCB974", 'black', 'black', "#64B5CD", "black"
        ]
        marker_vec = ['o', 'x', 'None', 'None', 'None']
        linestyle_vec = ['solid'] * 3 + ['dashed']
        linewidth_vec = [4, 3, 4] + [3] * 7
        ymin = 1e-2

        graph_cvs = 'Fig_Timing_SSLH_1'  # re-use existing large graphs

    else:
        raise Warning("Incorrect choice!")

    # %% -- Common options

    alpha0 = np.array([a, 1., 1.])
    alpha0 = alpha0 / np.sum(alpha0)
    H0 = create_parameterized_H(k, h, symmetric=True)
    H0c = to_centering_beliefs(H0)
    RANDOMSEED = None  # For repeatability
    random.seed(RANDOMSEED)  # seeds some other python random generator
    np.random.seed(
        seed=RANDOMSEED
    )  # seeds the actually used numpy random generator; both are used and thus needed

    # print("CHOICE: {}".format(CHOICE))

    def save_tuple(n, label, time):
        tuple = [str(datetime.datetime.now())]
        text = [n, label, time]
        tuple.extend(text)
        print("time potential {}: {}".format(label, time))
        save_csv_record(join(data_directory, csv_filename), tuple)

    # %% -- Create data
    if CREATE_DATA or ADD_DATA:

        for repeat_vec, method_vec in zip(repeat_vec_vec, method_vec_vec):

            for n, repeat in zip(n_vec, repeat_vec):
                print("\nn: {}".format(n))
                # repeat = repeat_vec[j]

                # -- Graph
                if CREATE_GRAPH:
                    start = time.time()
                    W, Xd = planted_distribution_model(
                        n,
                        alpha=alpha0,
                        P=H0,
                        m=d * n,
                        distribution=distribution,
                        exponent=exponent,
                        directed=False,
                        debug=False)
                    X0 = from_dictionary_beliefs(Xd)
                    time_graph = time.time() - start

                    save_W(join(data_directory,
                                '{}_{}_W.csv'.format(graph_cvs, n)),
                           W,
                           saveWeights=False)
                    save_X(
                        join(data_directory,
                             '{}_{}_X.csv'.format(graph_cvs, n)), X0)
                    save_tuple(n, 'graph', time_graph)

                else:
                    W, _ = load_W(join(data_directory,
                                       '{}_{}_W.csv'.format(graph_cvs, n)),
                                  skiprows=1,
                                  zeroindexing=True,
                                  n=None,
                                  doubleUndirected=False)
                    X0, _, _ = load_X(join(data_directory,
                                           '{}_{}_X.csv'.format(graph_cvs, n)),
                                      n=None,
                                      k=None,
                                      skiprows=1,
                                      zeroindexing=True)

                # -- Repeat loop
                for i in range(repeat):
                    print("\n  repeat: {}".format(i))
                    X2, ind = replace_fraction_of_rows(
                        X0, 1 - f, avoidNeighbors=avoidNeighbors, W=W)

                    for method in method_vec:

                        if method == 'DHE':
                            start = time.time()
                            H2 = estimateH(X2,
                                           W,
                                           method='DHE',
                                           variant=1,
                                           distance=5,
                                           EC=est_EC,
                                           weights=weights)
                            time_est = time.time() - start
                            save_tuple(n, 'DHE', time_est)

                        elif method == 'DHEr':
                            start = time.time()
                            H2 = estimateH(X2,
                                           W,
                                           method='DHE',
                                           variant=1,
                                           distance=5,
                                           EC=est_EC,
                                           weights=weights,
                                           randomize=True)
                            time_est = time.time() - start
                            save_tuple(n, 'DHEr', time_est)

                        elif method == 'MHE':
                            start = time.time()
                            H2 = estimateH(X2,
                                           W,
                                           method='MHE',
                                           variant=1,
                                           distance=1,
                                           EC=est_EC,
                                           weights=None)
                            time_est = time.time() - start
                            save_tuple(n, 'MHE', time_est)

                        elif method == 'LHE':
                            start = time.time()
                            H2 = estimateH(X2,
                                           W,
                                           method='LHE',
                                           variant=1,
                                           distance=1,
                                           EC=est_EC,
                                           weights=None)
                            time_est = time.time() - start
                            save_tuple(n, 'LHE', time_est)

                        elif method == 'Holdout':
                            start = time.time()
                            H2 = estimateH_baseline_serial(
                                X2,
                                ind,
                                W,
                                numMax=numMaxIt,
                                numberOfSplits=1,
                                # EC=EC,
                                # weights=weight,
                                alpha=alpha,
                                beta=beta,
                                gamma=gamma)
                            time_est = time.time() - start
                            save_tuple(n, 'Holdout', time_est)

                        elif method == 'prop':
                            H2c = to_centering_beliefs(H0)
                            X2c = to_centering_beliefs(
                                X2, ignoreZeroRows=True)  # try without
                            start = time.time()
                            eps_max = eps_convergence_linbp_parameterized(
                                H2c,
                                W,
                                method='noecho',
                                alpha=alpha,
                                beta=beta,
                                gamma=gamma,
                                X=X2,
                                pyamg=pyamg)
                            time_eps_max = time.time() - start
                            save_tuple(n, 'eps_max', time_eps_max)

                            # -- Propagate
                            eps = s * eps_max
                            try:
                                start = time.time()
                                F, actualIt, actualPercentageConverged = \
                                    linBP_symmetric_parameterized(X2, W, H2c * eps,
                                                                  method='noecho',
                                                                  alpha=alpha, beta=beta, gamma=gamma,
                                                                  numMaxIt=numMaxIt,
                                                                  convergencePercentage=convergencePercentage_W,
                                                                  debug=2)
                                time_prop = time.time() - start
                            except ValueError as e:
                                print("ERROR: {}: d={}, h={}".format(e, d, h))
                            else:
                                save_tuple(n, 'prop', time_prop)

                        else:
                            raise Warning("Incorrect choice!")

    # %% -- Read, aggregate, and pivot data for all options
    df1 = pd.read_csv(join(data_directory, csv_filename))
    # print("\n-- df1: (length {}):\n{}".format(len(df1.index), df1.head(50)))

    # Aggregate repetitions
    df2 = df1.groupby(['n', 'type']).agg \
        ({'time': [np.mean, np.median, np.std, np.size],  # Multiple Aggregates
          })
    df2.columns = ['_'.join(col).strip() for col in df2.columns.values
                   ]  # flatten the column hierarchy
    df2.reset_index(inplace=True)  # remove the index hierarchy
    df2.rename(columns={'time_size': 'count'}, inplace=True)
    # print("\n-- df2 (length {}):\n{}".format(len(df2.index), df2.head(15)))

    # Pivot table
    df3 = pd.pivot_table(df2,
                         index=['n'],
                         columns=['type'],
                         values=['time_mean', 'time_median'])  # Pivot
    # df3 = pd.pivot_table(df2, index=['n'], columns=['type'], values=['time_mean', 'time_median', 'time_std'] )  # Pivot
    # print("\n-- df3 (length {}):\n{}".format(len(df3.index), df3.head(30)))
    df3.columns = ['_'.join(col).strip() for col in df3.columns.values
                   ]  # flatten the column hierarchy
    df3.reset_index(inplace=True)  # remove the index hierarchy
    # df2.rename(columns={'time_size': 'count'}, inplace=True)
    # print("\n-- df3 (length {}):\n{}".format(len(df3.index), df3.head(30)))

    # Extract values
    X = df3['n'].values  # plot x values
    X = X * d / 2  # calculate edges (!!! notice dividing by 2 as one edge appears twice in symmetric adjacency matrix)
    Y = {}
    for method in method_vec_fig:
        # Y[method] = df3['time_mean_{}'.format(method)].values
        Y[method] = df3['time_median_{}'.format(method)].values

    if SHORTEN_LENGTH:
        SHORT_FACTOR = 4  ## KEEP EVERY Nth ELEMENT
        X = np.copy(X[list(range(0, len(X), SHORT_FACTOR)), ])
        for method in method_vec_fig:
            Y[method] = np.copy(
                Y[method][list(range(0, len(Y[method]), SHORT_FACTOR)), ])

    # %% -- Figure
    if CREATE_FIG:
        fig_filename = '{}.pdf'.format(
            filename)  # TODO: repeat pattern in other files
        mpl.rcParams['backend'] = 'agg'
        mpl.rcParams['lines.linewidth'] = 3
        mpl.rcParams['font.size'] = LABEL_FONTSIZE
        mpl.rcParams['axes.labelsize'] = 20
        mpl.rcParams['axes.titlesize'] = 16
        mpl.rcParams['xtick.labelsize'] = 16
        mpl.rcParams['ytick.labelsize'] = 16
        mpl.rcParams['legend.fontsize'] = 12
        mpl.rcParams['axes.edgecolor'] = '111111'  # axes edge color
        mpl.rcParams['grid.color'] = '777777'  # grid color
        mpl.rcParams['figure.figsize'] = [4, 4]
        mpl.rcParams[
            'xtick.major.pad'] = 4  # padding of tick labels: default = 4
        mpl.rcParams[
            'ytick.major.pad'] = 4  # padding of tick labels: default = 4
        fig = plt.figure()
        ax = fig.add_axes([0.13, 0.17, 0.8, 0.8])

        # -- Draw the plots
        if SHOW_LINEAR:
            ax.plot([1, 1e8], [1e-5, 1e3],
                    linewidth=1,
                    color='gray',
                    linestyle='dashed',
                    label='1sec/100k edges',
                    clip_on=True,
                    zorder=3)
        for i, (method, color, marker, linewidth, linestyle) in enumerate(
                zip(method_vec_fig, color_vec, marker_vec, linewidth_vec,
                    linestyle_vec)):
            ax.plot(X,
                    Y[method],
                    linewidth=linewidth,
                    color=color,
                    linestyle=linestyle,
                    label=label_vec[i],
                    clip_on=True,
                    marker=marker,
                    markersize=6,
                    markeredgewidth=1,
                    markeredgecolor='black',
                    zorder=4)

            # for choice, (option, label, color, linewidth, clip_on, linestyle, marker, markersize) in \
            #         enumerate(zip(option_vec, labels, facecolor_vec, linewidth_vec, clip_on_vec, linestyle_vec, marker_vec, markersize_vec)):
            #     P = ax.plot(X_f, Y[choice], linewidth=linewidth, color=color, linestyle=linestyle, label=label, zorder=4, marker=marker,
            #                 markersize=markersize, markeredgewidth=1, markeredgecolor='black', clip_on=clip_on)

            if SHOWMAXNUMBER and method in show_num_vec:
                if method == 'DHEr' and SHOW_DCER_WITH_BOX:
                    j = np.argmax(np.ma.masked_invalid(
                        Y[method]))  # mask nan, then get index of max element
                    ax.annotate(int(np.round(Y[method][j])),
                                xy=(X[j] * 1.5, Y[method][j]),
                                color=color,
                                va='center',
                                bbox=dict(boxstyle="round,pad=0.3", fc="w"),
                                annotation_clip=False,
                                zorder=5)
                else:
                    j = np.argmax(np.ma.masked_invalid(
                        Y[method]))  # mask nan, then get index of max element
                    ax.annotate(int(np.round(Y[method][j])),
                                xy=(X[j] * 1.5, Y[method][j]),
                                color=color,
                                va='center',
                                annotation_clip=False,
                                zorder=5)

        if SHOW_ARROWS:
            dce_opt = 'DHEr'
            holdout_opt = 'Holdout'
            prop_opt = 'prop'

            j_holdout = np.argmax(np.ma.masked_invalid(Y[holdout_opt]))

            if dce_opt in Y:
                j_dce = np.argmax(np.ma.masked_invalid(Y[dce_opt]))
                ax.annotate(s='',
                            xy=(X[j_dce], Y[prop_opt][j_dce]),
                            xytext=(X[j_dce], Y[dce_opt][j_dce]),
                            arrowprops=dict(arrowstyle='<->'))
                ax.annotate(
                    str(int(np.round(Y[prop_opt][j_dce] / Y[dce_opt][j_dce])))
                    + 'x',
                    xy=(X[j_dce],
                        int(Y[prop_opt][j_dce] + Y[dce_opt][j_dce]) / 6),
                    color='black',
                    va='center',
                    fontsize=14,
                    # bbox = dict(boxstyle="round,pad=0.3", fc="w"),
                    annotation_clip=False,
                    zorder=5)

                ax.annotate(s='',
                            xy=(X[j_holdout], Y[holdout_opt][j_holdout]),
                            xytext=(X[j_holdout], Y[dce_opt][j_holdout]),
                            arrowprops=dict(arrowstyle='<->'))
                ax.annotate(
                    str(
                        int(
                            np.round(Y[holdout_opt][j_holdout] /
                                     Y[dce_opt][j_holdout]))) + 'x',
                    xy=(X[j_holdout],
                        int(Y[holdout_opt][j_holdout] + Y[dce_opt][j_holdout])
                        / 8),
                    color='black',
                    va='center',
                    fontsize=14,
                    # bbox = dict(boxstyle="round,pad=0.3", fc="w"),
                    annotation_clip=False,
                    zorder=5)

            else:  # in case dce_opt not shown, then show arrow as compared to prop method
                ax.annotate(s='',
                            xy=(X[j_holdout], Y[holdout_opt][j_holdout]),
                            xytext=(X[j_holdout], Y[prop_opt][j_holdout]),
                            arrowprops=dict(arrowstyle='<->'))
                ax.annotate(
                    str(
                        int(
                            np.round(Y[holdout_opt][j_holdout] /
                                     Y[prop_opt][j_holdout]))) + 'x',
                    xy=(X[j_holdout],
                        int(Y[holdout_opt][j_holdout] + Y[prop_opt][j_holdout])
                        / 8),
                    color='black',
                    va='center',
                    fontsize=14,
                    # bbox = dict(boxstyle="round,pad=0.3", fc="w"),
                    annotation_clip=False,
                    zorder=5)

        if SHOW_TITLE:
            plt.title(r'$\!\!\!d\!=\!{}, h\!=\!{}$'.format(d, h))

        handles, labels = ax.get_legend_handles_labels()
        if not SHOW_SCALING_LABELS and SHOW_LINEAR:
            handles = handles[1:]
            labels = labels[1:]

        legend = plt.legend(
            handles,
            labels,
            loc='upper left',  # 'upper right'
            handlelength=2,
            labelspacing=0,  # distance between label entries
            handletextpad=
            0.3,  # distance between label and the line representation
            borderaxespad=0.2,  # distance between legend and the outer axes
            borderpad=0.3,  # padding inside legend box
            numpoints=1,  # put the marker only once
        )
        legend.set_zorder(3)
        frame = legend.get_frame()
        frame.set_linewidth(0.0)
        frame.set_alpha(0.2)  # 0.8

        # -- Figure settings and save
        plt.minorticks_on()
        plt.xscale('log')
        plt.yscale('log')
        minorLocator = LogLocator(
            base=10, subs=[0.1 * n for n in range(1, 10)], numticks=40
        )  # TODO: discuss with Paul trick that helped with grid lines last time; necessary in order to create the log locators (otherwise does now show the wanted ticks
        #         ax.xaxis.set_minor_locator(minorLocator)
        plt.xticks([1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9])
        plt.grid(True,
                 which='both',
                 axis='both',
                 alpha=0.2,
                 linestyle='-',
                 linewidth=1,
                 zorder=1)  # linestyle='dashed', which='minor', axis='y',
        # grid(b=True, which='minor', axis='x', alpha=0.2, linestyle='solid', linewidth=0.5)  # linestyle='dashed', which='minor', axis='y',
        plt.xlabel(r'Number of edges ($m$)', labelpad=0)  # labelpad=0
        plt.ylabel(r'Time [sec]', labelpad=0)
        plt.xlim(xmin, xmax)
        plt.ylim(ymin, ymax)
        # print(ax.get_xaxis().get_minor_locator())

        if CREATE_PDF:
            plt.savefig(
                join(figure_directory, fig_filename),
                format='pdf',
                dpi=None,
                edgecolor='w',
                orientation='portrait',
                transparent=False,
                bbox_inches='tight',
                pad_inches=0.05,
                # frameon=None
            )
        if SHOW_PDF:
            showfig(join(figure_directory,
                         fig_filename))  # shows actually created PDF
        if SHOW_PLOT:
            plt.show()
Exemple #4
0
def run(choice, create_data=False, add_data=False, show_plot=False, create_pdf=False, show_pdf=False, shorten_length=False):

    # -- Setup
    CHOICE = choice
    CREATE_DATA = create_data
    ADD_DATA = add_data
    SHOW_PDF = show_pdf
    SHOW_PLOT = show_plot
    CREATE_PDF = create_pdf
    STD_FILL = True


    csv_filename = 'Fig_End-to-End_accuracy_VaryK_{}.csv'.format(CHOICE)
    header = ['currenttime',
              'option',
              'k',
              'f',
              'accuracy']
    if CREATE_DATA:
        save_csv_record(join(data_directory, csv_filename), header, append=False)


    # -- Default Graph parameters
    rep_SameGraph = 10       # iterations on same graph
    initial_h0 = None           # initial vector to start finding optimal H
    distribution = 'powerlaw'
    exponent = -0.3
    length = 5
    variant = 1
    EC = True                   # Non-backtracking for learning
    ymin = 0.3
    ymax = 1
    xmax = 8
    xtick_lab = [2,3,4,5,6,7, 8]
    xtick_labels = ['2', '3', '4', '5', '6', '7', '8']
    ytick_lab = np.arange(0, 1.1, 0.1)
    f_vec = [0.9 * pow(0.1, 1 / 5) ** x for x in range(21)]
    k_vec = [3, 4, 5 ]
    rep_DifferentGraphs = 10   # iterations on different graphs
    err = 0
    avoidNeighbors = False
    gradient = False
    pruneRandom = False
    convergencePercentage_W = None
    stratified = True
    label_vec = ['*'] * 10
    clip_on_vec = [False] * 10
    draw_std_vec = range(10)
    numberOfSplits = 1
    linestyle_vec = ['dashed'] + ['solid'] * 10
    linewidth_vec = [5, 4, 3, 3] + [3] * 10
    marker_vec = [None, None, 'o', 'x', 'o', '^', 'o', 'x', 'o', '^', 'o', 'x', 'o', '^']
    markersize_vec = [0, 0, 4, 8] + [6] * 10
    facecolor_vec = ["#4C72B0", "#55A868", "#C44E52", "#8172B2", "#CCB974", "#64B5CD"]


    # -- Options with propagation variants
    if CHOICE == 500:     ## 1k nodes
        n = 1000
        h = 8
        d = 25
        option_vec = ['opt1', 'opt2', 'opt3']
        learning_method_vec = ['GS', 'MHE', 'DHE']
        weight_vec = [10] * 3
        alpha_vec = [0] * 10
        beta_vec = [0] * 10
        gamma_vec = [0] * 10
        s_vec = [0.5] * 10
        numMaxIt_vec = [10] * 10
        randomize_vec = [False] * 2 + [True]
        xmin = 3.
        ymin = 0.
        ymax = 1.
        label_vec = ['GS', 'MCE', 'DCEr']
        facecolor_vec = ['black'] + ["#55A868", "#4C72B0", "#8172B2", "#C44E52", "#CCB974"] * 3
        f_vec = [0.03, 0.01, 0.001]
        k_vec = [3, 4, 5, 6]

    elif CHOICE == 501:        ## 10k nodes
        n = 10000
        h = 8
        d = 25
        option_vec = ['opt1', 'opt2', 'opt3']
        learning_method_vec = ['GT', 'MHE', 'DHE']
        weight_vec = [10] * 3
        alpha_vec = [0] * 10
        beta_vec = [0] * 10
        gamma_vec = [0] * 10
        s_vec = [0.5] * 10
        numMaxIt_vec = [10] * 10
        randomize_vec = [False] * 2 + [True]
        xmin = 2.
        ymin = 0.
        ymax = 1.
        label_vec = ['GT', 'MCE', 'DCEr']
        facecolor_vec = ['black'] + ["#55A868", "#4C72B0", "#8172B2", "#C44E52", "#CCB974"] * 3
        f_vec = [0.03, 0.01, 0.001]
        k_vec = [2, 3, 4, 5]


    elif CHOICE == 502:        ## 10k nodes
        n = 10000
        h = 8
        d = 25
        option_vec = ['opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6']
        learning_method_vec = ['GT', 'LHE', 'MHE', 'DHE', 'DHE', 'Holdout']
        weight_vec = [10] * 10
        alpha_vec = [0] * 10
        beta_vec = [0] * 10
        gamma_vec = [0] * 10
        s_vec = [0.5] * 10
        numMaxIt_vec = [10] * 10
        randomize_vec = [False] * 4 + [True] + [False]
        xmin = 2
        ymin = 0.6
        ymax = 1.
        label_vec = ['GT', 'LCE', 'MCE', 'DCE', 'DCEr', 'Holdout']
        facecolor_vec = ['black'] + ["#55A868", "#4C72B0", "#8172B2", "#C44E52", "#CCB974"] * 3
        f_vec = [0.01]
        k_vec = [2, 3, 4, 5, 6, 7, 8]

        # option_vec = ['opt1', 'opt2', 'opt3', 'opt4']
        # learning_method_vec = ['GT', 'LHE', 'MHE', 'DHE']
        # k_vec = [2, 3, 4, 5]



    elif CHOICE == 503:        ## 10k nodes
        n = 10000
        h = 3
        d = 25
        option_vec = ['opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6']
        learning_method_vec = ['GT', 'LHE', 'MHE', 'DHE', 'DHE', 'Holdout']
        weight_vec = [10] * 10
        alpha_vec = [0] * 10
        beta_vec = [0] * 10
        gamma_vec = [0] * 10
        s_vec = [0.5] * 10
        numMaxIt_vec = [10] * 10
        randomize_vec = [False] * 4 + [True] + [False]
        xmin = 2
        ymin = 0.3
        ymax = 0.9
        label_vec = ['GT', 'LCE', 'MCE', 'DCE', 'DCEr', 'Holdout']
        facecolor_vec = ['black'] + ["#55A868", "#4C72B0", "#8172B2", "#C44E52", "#CCB974"] * 3
        f_vec = [0.01]
        k_vec = [2, 3, 4, 5, 6, 7, 8]
        # k_vec = [6, 7, 8]
        clip_on_vec = [True] * 10

        # option_vec = ['opt1', 'opt2', 'opt3', 'opt4']
        # learning_method_vec = ['GT', 'LHE', 'MHE', 'DHE']
        # k_vec = [2, 3, 4, 5]



    elif CHOICE == 504:        ## 10k nodes
        n = 10000
        h = 3
        d = 25
        option_vec = ['opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6']
        learning_method_vec = ['GT', 'LHE', 'MHE', 'DHE', 'DHE', 'Holdout']
        weight_vec = [10] * 10
        alpha_vec = [0] * 10
        beta_vec = [0] * 10
        gamma_vec = [0] * 10
        s_vec = [0.5] * 10
        numMaxIt_vec = [10] * 10
        randomize_vec = [False] * 4 + [True] + [False]
        xmin = 2
        xmax = 7
        ymin = 0.2
        ymax = 0.9
        label_vec = ['GT', 'LCE', 'MCE', 'DCE', 'DCEr', 'Holdout']
        facecolor_vec = ['black'] + ["#55A868", "#4C72B0", "#8172B2", "#C44E52", "#CCB974"] * 3
        f_vec = [0.01]
        # k_vec = [2, 3, 4, 5, 6, 7, 8]
        k_vec = [7]
        clip_on_vec = [True] * 10




    elif CHOICE == 505:        ## 10k nodes    with f = 0.005
        n = 10000
        h = 3
        d = 25
        option_vec = ['opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6']
        learning_method_vec = ['GT', 'LHE', 'MHE', 'DHE', 'DHE', 'Holdout']
        weight_vec = [10] * 10
        alpha_vec = [0] * 10
        beta_vec = [0] * 10
        gamma_vec = [0] * 10
        s_vec = [0.5] * 10
        numMaxIt_vec = [10] * 10
        randomize_vec = [False] * 4 + [True] + [False]
        xmin = 2
        xmax = 7
        ymin = 0.2
        ymax = 0.9
        label_vec = ['GT', 'LCE', 'MCE', 'DCE', 'DCEr', 'Holdout']
        facecolor_vec = ['black'] + ["#55A868", "#4C72B0", "#8172B2", "#C44E52", "#CCB974"] * 3
        f_vec = [0.005]
        k_vec = [2, 3, 4, 5, 6, 7]
        # k_vec = [7]
        clip_on_vec = [True] * 10

    # elif CHOICE == 506:        ## 10k nodes    with f = 0.005
    #     n = 10000
    #     h = 3
    #     d = 25
    #     option_vec = ['opt1', 'opt2', 'opt3', 'opt4', 'opt5']
    #     learning_method_vec = ['GT', 'LHE', 'MHE', 'DHE', 'DHE']
    #     weight_vec = [10] * 10
    #     alpha_vec = [0] * 10
    #     beta_vec = [0] * 10
    #     gamma_vec = [0] * 10
    #     s_vec = [0.5] * 10
    #     numMaxIt_vec = [10] * 10
    #     randomize_vec = [False] * 4 + [True] + [False]
    #     xmin = 2
    #     xmax = 7
    #     ymin = 0.2
    #     ymax = 0.9
    #     label_vec = ['GT', 'LCE', 'MCE', 'DCE', 'DCEr']
    #     facecolor_vec = ['black'] + ["#55A868", "#4C72B0", "#8172B2", "#C44E52", "#CCB974"] * 3
    #     f_vec = [0.005]
    #     k_vec = [2,3,4,5,6,7]
    #     # k_vec = [7]
    #     clip_on_vec = [True] * 10




    elif CHOICE == 506:        ## 10k nodes
        n = 10000
        h = 8
        d = 25
        option_vec = ['opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6']
        option_vec = ['opt1', 'opt2', 'opt3', 'opt4', 'opt5']
        learning_method_vec = ['GT', 'LHE', 'MHE', 'DHE', 'DHE', 'Holdout']
        learning_method_vec = ['GT', 'LHE', 'MHE', 'DHE', 'DHE']
        weight_vec = [10] * 10
        alpha_vec = [0] * 10
        beta_vec = [0] * 10
        gamma_vec = [0] * 10
        s_vec = [0.5] * 10
        numMaxIt_vec = [10] * 10
        randomize_vec = [False] * 4 + [True] + [False]
        xmin = 2
        xmax = 7
        ymin = 0.2
        ymax = 0.9
        label_vec = ['GT', 'LCE', 'MCE', 'DCE', 'DCEr', 'Holdout']
        facecolor_vec = ['black'] + ["#55A868", "#4C72B0", "#8172B2", "#C44E52", "#CCB974"] * 3
        f_vec = [0.005]
        k_vec = [2, 3, 4, 5, 6, 7, 8]
        # k_vec = [5]
        clip_on_vec = [True] * 10

        rep_SameGraph = 1       # iterations on same graph
        rep_DifferentGraphs = 1  # iterations on same graph

    elif CHOICE == 507:  ## 10k nodes   with gradient and PruneRandom
        n = 10000
        h = 3
        d = 25
        option_vec = ['opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6']
        learning_method_vec = ['GS', 'LHE', 'MHE', 'DHE', 'DHE', 'Holdout']
        weight_vec = [10] * 10
        alpha_vec = [0] * 10
        beta_vec = [0] * 10
        gamma_vec = [0] * 10
        s_vec = [0.5] * 10
        numMaxIt_vec = [10] * 10
        randomize_vec = [False] * 4 + [True] + [False]
        xmin = 2
        ymin = 0.1
        ymax = 0.9
        label_vec = ['GS', 'LCE', 'MCE', 'DCE', 'DCEr', 'Holdout']
        facecolor_vec = ['black'] + ["#55A868", "#4C72B0", "#8172B2", "#C44E52", "#CCB974"] * 3
        f_vec = [0.01]
        k_vec = [2, 3, 4, 5, 6, 7, 8]
        # k_vec = [6, 7, 8]
        clip_on_vec = [True] * 10

        # option_vec = ['opt1', 'opt2', 'opt3', 'opt4']
        # learning_method_vec = ['GT', 'LHE', 'MHE', 'DHE']
        # k_vec = [2, 3, 4, 5]

        gradient = True
        pruneRandom = True


    elif CHOICE == 508:  ## 10k nodes   with gradient and PruneRandom
        n = 1000
        h = 3
        d = 10
        option_vec = ['opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6']
        learning_method_vec = ['GS', 'LHE', 'MHE', 'DHE', 'DHE', 'Holdout']
        weight_vec = [10] * 10
        alpha_vec = [0] * 10
        beta_vec = [0] * 10
        gamma_vec = [0] * 10
        s_vec = [0.5] * 10
        numMaxIt_vec = [10] * 10
        randomize_vec = [False] * 4 + [True] + [False]
        xmin = 2
        ymin = 0.1
        ymax = 0.9
        label_vec = ['GS', 'LCE', 'MCE', 'DCE', 'DCEr', 'Holdout']
        facecolor_vec = ['black'] + ["#55A868", "#4C72B0", "#8172B2", "#C44E52", "#CCB974"] * 3
        f_vec = [0.01]
        k_vec = [2, 3, 4, 5, 6, 7, 8]
        # k_vec = [6, 7, 8]
        clip_on_vec = [True] * 10

        # option_vec = ['opt1', 'opt2', 'opt3', 'opt4']
        # learning_method_vec = ['GT', 'LHE', 'MHE', 'DHE']
        # k_vec = [2, 3, 4, 5]

        gradient = True
        pruneRandom = True
        rep_DifferentGraphs = 1
        rep_SameGraph = 1



    else:
        raise Warning("Incorrect choice!")


    RANDOMSEED = None  # For repeatability
    random.seed(RANDOMSEED)  # seeds some other python random generator
    np.random.seed(seed=RANDOMSEED)  # seeds the actually used numpy random generator; both are used and thus needed
    # print("CHOICE: {}".format(CHOICE))


    # -- Create data
    if CREATE_DATA or ADD_DATA:
        for i in range(rep_DifferentGraphs):  # create several graphs with same parameters
            # print("\ni: {}".format(i))

            for k in k_vec:
                # print("\nk: {}".format(k))

                H0 = create_parameterized_H(k, h, symmetric=True)
                H0c = to_centering_beliefs(H0)

                a = [1.] * k
                alpha0 = np.array(a)
                alpha0 = alpha0 / np.sum(alpha0)

                W, Xd = planted_distribution_model_H(n, alpha=alpha0, H=H0, d_out=d,
                                                          distribution=distribution,
                                                          exponent=exponent,
                                                          directed=False,
                                                          debug=False)
                X0 = from_dictionary_beliefs(Xd)

                for j in range(rep_SameGraph):  # repeat several times for same graph
                    # print("j: {}".format(j))

                    ind = None
                    for f in f_vec:             # Remove fraction (1-f) of rows from X0 (notice that different from first implementation)
                        X1, ind = replace_fraction_of_rows(X0, 1-f, avoidNeighbors=avoidNeighbors, W=W, ind_prior=ind, stratified=stratified)
                        X2 = introduce_errors(X1, ind, err)



                        for option_index, (learning_method, alpha, beta, gamma, s, numMaxIt, weights, randomize) in \
                                enumerate(zip(learning_method_vec, alpha_vec, beta_vec, gamma_vec, s_vec, numMaxIt_vec, weight_vec, randomize_vec)):

                            # -- Learning
                            if learning_method == 'GT':
                                H2c = H0c


                            elif learning_method == 'Holdout':


                                H2 = estimateH_baseline_serial(X2, ind, W, numMax=numMaxIt,
                                                               # ignore_rows=ind,
                                                               numberOfSplits=numberOfSplits,
                                                               # method=learning_method, variant=1, distance=length,
                                                               EC=EC,
                                                               alpha=alpha, beta=beta, gamma=gamma)
                                H2c = to_centering_beliefs(H2)

                            elif learning_method != 'DHE':
                                H2 = estimateH(X2, W, method=learning_method, variant=1, distance=length, EC=EC, weights=weights, randomize=randomize)
                                H2c = to_centering_beliefs(H2)

                            else:
                                H2 = estimateH(X2, W, method=learning_method, variant=1, distance=length, EC=EC, weights=weights, randomize=randomize, gradient=gradient, randomrestarts=pruneRandom)
                                H2c = to_centering_beliefs(H2)


                            # -- Propagation
                            X2c = to_centering_beliefs(X2, ignoreZeroRows=True)       # try without
                            eps_max = eps_convergence_linbp_parameterized(H2c, W,
                                                                          method='noecho',
                                                                          alpha=alpha, beta=beta, gamma=gamma,
                                                                          X=X2)
                            eps = s * eps_max
                            try:
                                F, actualIt, actualPercentageConverged = \
                                    linBP_symmetric_parameterized(X2, W, H2c * eps,
                                                                  method='noecho',
                                                                  alpha=alpha, beta=beta, gamma=gamma,
                                                                  numMaxIt=numMaxIt,
                                                                  convergencePercentage=convergencePercentage_W,
                                                                  debug=2)
                            except ValueError as e:
                                print (
                                "ERROR: {} with {}: d={}, h={}".format(e, learning_method, d, h))

                            else:
                                accuracy_X = matrix_difference(X0, F, ignore_rows=ind)

                                tuple = [str(datetime.datetime.now())]
                                text = [option_vec[option_index],
                                        k,
                                        f,
                                        accuracy_X]
                                # text = ['' if v is None else v for v in text]       # TODO: test with vocabularies
                                # text = np.asarray(text)         # without np, entries get ugly format
                                tuple.extend(text)
                                # print("option: {}, f: {}, actualIt: {}, accuracy: {}".format(option_vec[option_index], f, actualIt, accuracy_X))
                                save_csv_record(join(data_directory, csv_filename), tuple)


    # -- Read, aggregate, and pivot data for all options
    df1 = pd.read_csv(join(data_directory, csv_filename))
    # print("\n-- df1: (length {}):\n{}".format(len(df1.index), df1.head(15)))

    # -- Aggregate repetitions
    df2 = df1.groupby(['option', 'k', 'f']).agg \
        ({'accuracy': [np.mean, np.std, np.size, np.median],  # Multiple Aggregates
          })
    df2.columns = ['_'.join(col).strip() for col in df2.columns.values]  # flatten the column hierarchy
    df2.reset_index(inplace=True)  # remove the index hierarchy
    df2.rename(columns={'accuracy_size': 'count'}, inplace=True)
    # print("\n-- df2 (length {}):\n{}".format(len(df2.index), df2.head(15)))

    # -- Pivot table
    df3 = pd.pivot_table(df2, index=['f', 'k'], columns=['option'], values=[ 'accuracy_mean', 'accuracy_std'] )  # Pivot
    # print("\n-- df3 (length {}):\n{}".format(len(df3.index), df3.head(30)))
    df3.columns = ['_'.join(col).strip() for col in df3.columns.values]  # flatten the column hierarchy
    df3.reset_index(inplace=True)  # remove the index hierarchy
    # df2.rename(columns={'time_size': 'count'}, inplace=True)
    # print("\n-- df3 (length {}):\n{}".format(len(df3.index), df3.head(100)))



    # X_f = k_vec
    X_f = df3['k'].values            # read k from values instead

    Y_hash = defaultdict(dict)
    Y_hash_std = defaultdict(dict)
    for f in f_vec:
        for option in option_vec:
            Y_hash[f][option] = list()
            Y_hash_std[f][option] = list()
    for f in f_vec:
        for option in option_vec:
            Y_hash[f][option] = df3.loc[df3['f'] == f]['accuracy_mean_{}'.format(option)].values
            Y_hash_std[f][option] = df3.loc[df3['f'] == f]['accuracy_std_{}'.format(option)].values




    if CREATE_PDF or SHOW_PLOT or SHOW_PDF:

        # -- Setup figure
        fig_filename = 'Fig_End-to-End_accuracy_varyK_{}.pdf'.format(CHOICE)
        mpl.rc('font', **{'family': 'sans-serif', 'sans-serif': [u'Arial', u'Liberation Sans']})
        mpl.rcParams['axes.labelsize'] = 20
        mpl.rcParams['xtick.labelsize'] = 16
        mpl.rcParams['ytick.labelsize'] = 16
        mpl.rcParams['legend.fontsize'] = 14
        mpl.rcParams['grid.color'] = '777777'  # grid color
        mpl.rcParams['xtick.major.pad'] = 2  # padding of tick labels: default = 4
        mpl.rcParams['ytick.major.pad'] = 1  # padding of tick labels: default = 4
        mpl.rcParams['xtick.direction'] = 'out'  # default: 'in'
        mpl.rcParams['ytick.direction'] = 'out'  # default: 'in'
        mpl.rcParams['axes.titlesize'] = 16
        mpl.rcParams['figure.figsize'] = [4, 4]
        fig = figure()
        ax = fig.add_axes([0.13, 0.17, 0.8, 0.8])

        opt_f_vecs = [(option, f) for option in option_vec for f in f_vec]

        for ((option, f), color, linewidth, clip_on, linestyle, marker, markersize) in \
            zip(opt_f_vecs, facecolor_vec, linewidth_vec, clip_on_vec, linestyle_vec, marker_vec, markersize_vec):

            # label = learning_method_vec[option_vec.index(option)]
            label = label_vec[option_vec.index(option)]
            # label = label + " " + str(f)

            if STD_FILL:


                # print((X_f))
                # print(Y_hash[f][option])


                ax.fill_between(X_f, Y_hash[f][option] + Y_hash_std[f][option], Y_hash[f][option] - Y_hash_std[f][option],
                                facecolor=color, alpha=0.2, edgecolor=None, linewidth=0)
                ax.plot(X_f, Y_hash[f][option] + Y_hash_std[f][option], linewidth=0.5, color='0.8', linestyle='solid')
                ax.plot(X_f, Y_hash[f][option] - Y_hash_std[f][option], linewidth=0.5, color='0.8', linestyle='solid')

            ax.plot(X_f, Y_hash[f][option], linewidth=linewidth, color=color, linestyle=linestyle, label=label, zorder=4, marker=marker,
                markersize=markersize, markeredgewidth=1, markeredgecolor='black', clip_on=clip_on)

        if CHOICE==507:
            Y_f = [1/float(i) for i in X_f]

            ax.plot(X_f, Y_f, linewidth=2, color='black', linestyle='dashed',
                    label='Random', zorder=4, marker='x',
                markersize=8, markeredgewidth=1, markeredgecolor='black', clip_on=clip_on)

        # -- Title and legend
        if distribution == 'uniform':
            distribution_label = ',$uniform'
        else:
            distribution_label = '$'
        if n < 1000:
            n_label='{}'.format(n)
        else:
            n_label = '{}k'.format(int(n / 1000))

        title(r'$\!\!\!n\!=\!{}, d\!=\!{}, h\!=\!{}, f\!=\!{}{}'.format(n_label, d, h, f, distribution_label))
        handles, label_vec = ax.get_legend_handles_labels()
        legend = plt.legend(handles, label_vec,
                            loc='upper right',  # 'upper right'
                            handlelength=2,
                            labelspacing=0,  # distance between label entries
                            handletextpad=0.3,  # distance between label and the line representation
                            borderaxespad=0.2,  # distance between legend and the outer axes
                            borderpad=0.3,  # padding inside legend box
                            numpoints=1,  # put the marker only once
                            )
        # # legend.set_zorder(1)
        frame = legend.get_frame()
        frame.set_linewidth(0.0)
        frame.set_alpha(0.9)  # 0.8


        # -- Figure settings and save
        plt.xticks(xtick_lab, xtick_labels)
        plt.yticks(ytick_lab, ytick_lab)
        ax.yaxis.set_major_formatter(mpl.ticker.FormatStrFormatter('%.1f'))

        # Only show ticks on the left and bottom spines
        ax.yaxis.set_ticks_position('left')
        ax.xaxis.set_ticks_position('bottom')

        grid(b=True, which='major', axis='both', alpha=0.2, linestyle='solid', linewidth=0.5)  # linestyle='dashed', which='minor', axis='y',
        grid(b=True, which='minor', axis='both', alpha=0.2, linestyle='solid', linewidth=0.5)  # linestyle='dashed', which='minor', axis='y',
        xlabel(r'Number of Classes $(k)$', labelpad=0)      # labelpad=0
        ylabel(r'Accuracy', labelpad=0)

        xlim(xmin, xmax)
        ylim(ymin, ymax)

        if CREATE_PDF:
            savefig(join(figure_directory, fig_filename), format='pdf',
                    dpi=None,
                    edgecolor='w',
                    orientation='portrait',
                    transparent=False,
                    bbox_inches='tight',
                    pad_inches=0.05,
                    frameon=None)

        if SHOW_PLOT:
            plt.show()

        if SHOW_PDF:
            showfig(join(figure_directory, fig_filename))
def run(choice, create_data=False, add_data=False, show_plot=False, create_pdf=False, show_pdf=False, shorten_length=False):

    verbose = False
    repeat_diffGraph = 1000
    SUBSET = True
    NOGT = False        ## Not draw Ground Truth Comparison
    CHOICE = choice
    CREATE_DATA = create_data
    ADD_DATA = add_data
    SHOW_PLOT = show_plot
    SHOW_PDF = show_pdf
    CREATE_PDF = create_pdf

    STD_FILL = False

    csv_filename = 'Fig_fast_optimal_restarts_Accv2_{}.csv'.format(CHOICE)
    fig_filename = 'Fig_fast_optimal_restarts_Accv2_{}.pdf'.format(CHOICE)
    header = ['currenttime',
              'k',
              'restarts',
              'accuracy']
    if CREATE_DATA:
        save_csv_record(join(data_directory, csv_filename), header, append=False)




    # -- Default Graph parameters
    global f_vec, labels, facecolor_vec
    global number_of_restarts



    initial_h0 = None
    distribution = 'powerlaw'
    exponent = -0.3  # for powerlaw
    length = 4  # path length
    constraint = True
    gradient = True
    variant = 1
    EC = True
    delta = 0.001
    numMaxIt = 10
    avoidNeighbors = False
    convergencePercentage_W = None
    stratified = True

    learning_method = 'DHE'
    weights = 10
    randomize = True
    return_min_energy = True
    number_of_restarts = [8, 6, 5, 4]



    clip_on_vec = [True] * 20
    draw_std_vec = range(10)
    ymin = 0.3
    ymax = 1
    xmin = 0.001
    xmax = 1
    xtick_lab = []
    xtick_labels = []
    ytick_lab = np.arange(0, 1.1, 0.1)
    linestyle_vec = ['solid','solid','solid'] * 20
    linewidth_vec = [4,4,4,4]*10
    marker_vec = ['x', 'v', '^', '+', '>', '<'] *10
    markersize_vec = [10, 8, 8, 8 ,8 ,8 ,8 ]*10
    facecolor_vec = ["#C44E52", "#4C72B0", "#8172B2",  "#CCB974",  "#55A868", "#64B5CD"]*5




    # -- Options mainly change k

    if CHOICE == 101:
        n = 10000
        h = 3
        d = 15
        k_vec = [3, 4, 5, 6, 7, 10, 13, 16, 18, 20]
        # k_vec = [4, 5, 7, 10]
        f = 0.09
        distribution = 'uniform'

        # Write in DESCENDING ORDER
        number_of_restarts = [30, 20, 10, 7, 5, 4, 3, 2, 1, 50, 99, 100]
        ### 100:GT 99:GTr
        ### 50:min{30,GTr} 1:uninformative

        labels = ['r' + str(a1) for a1 in number_of_restarts]
        xtick_lab = k_vec
        xtick_labels = [str(a1) for a1 in k_vec]


    elif CHOICE == 102:
        n = 10000
        h = 3
        d = 15
        k_vec = [3, 4, 5, 6, 7, 8]
        # k_vec = [4, 5, 7, 10]
        f = 0.09
        distribution = 'uniform'

        # Write in DESCENDING ORDER
        # number_of_restarts = [30, 20, 10, 7, 5, 4, 3, 2, 1, 50, 99, 100]

        number_of_restarts = [20, 10, 5, 4, 3, 2]
        ### 100:GT 99:GTr
        ### 50:min{30,GTr} 1:uninformative

        labels = ['r' + str(a1) for a1 in number_of_restarts]
        xtick_lab = k_vec
        xtick_labels = [str(a1) for a1 in k_vec]


    elif CHOICE == 103:
        n = 10000
        h = 3
        d = 15
        k_vec = [3, 4, 5, 6, 7, 8]
        # k_vec = [4, 5, 7, 10]
        f = 0.09
        distribution = 'uniform'

        # Write in DESCENDING ORDER
        number_of_restarts = [20, 10, 5, 4, 3, 2, 99]
        ### 100:GT 99:GTr
        ### 50:min{30,GTr} 1:uninformative

        marker_vec = ['o', 'x', 'v', '^', '+', 's', None] * 10
        markersize_vec = [6, 10, 6, 6, 10, 6] * 10

        labels = ['r' + str(a1) for a1 in number_of_restarts]
        xtick_lab = k_vec
        xtick_labels = [str(a1) for a1 in k_vec]


    elif CHOICE == 104:
        n = 10000
        h = 8
        d = 15
        k_vec = [3, 4, 5, 6, 7, 8]
        # k_vec = [4, 5, 7, 10]
        f = 0.09
        distribution = 'uniform'

        # Write in DESCENDING ORDER
        number_of_restarts = [20, 10, 5, 4, 3, 2, 99]
        ### 100:GT 99:GTr
        ### 50:min{30,GTr} 1:uninformative

        marker_vec = ['o', 'x', 'v', '^', '+', 's', None] * 10
        markersize_vec = [6, 10, 6, 6, 10, 6] * 10

        labels = ['r' + str(a1) for a1 in number_of_restarts]
        xtick_lab = k_vec
        xtick_labels = [str(a1) for a1 in k_vec]



    elif CHOICE == 105:
        n = 10000
        h = 8
        d = 15
        k_vec = [3, 4, 5, 6, 7, 8]
        # k_vec = [4, 5, 7, 10]
        f = 0.09
        distribution = 'uniform'

        # Write in DESCENDING ORDER
        number_of_restarts = [20, 10, 5, 4, 3, 2, 100]
        ### 100:GT 99:GTr
        ### 50:min{30,GTr} 1:uninformative

        marker_vec = ['o', 'x', 'v', '^', '+', 's', None] * 10
        markersize_vec = [6, 10, 6, 6, 10, 6] * 10

        labels = ['r' + str(a1) for a1 in number_of_restarts]
        xtick_lab = k_vec
        xtick_labels = [str(a1) for a1 in k_vec]

    elif CHOICE == 106:
        n = 10000
        h = 3
        d = 15
        k_vec = [3, 4, 5, 6, 7, 8]
        # k_vec = [4, 5, 7, 10]
        f = 0.09
        distribution = 'uniform'

        # Write in DESCENDING ORDER
        number_of_restarts = [20, 10, 5, 4, 3, 2, 100]
        ### 100:GT 99:GTr
        ### 50:min{30,GTr} 1:uninformative

        marker_vec = ['o', 'x', 'v', '^', '+', 's', None] * 10
        markersize_vec = [6, 10, 6, 6, 10, 6] * 10

        labels = ['r' + str(a1) for a1 in number_of_restarts]
        xtick_lab = k_vec
        xtick_labels = [str(a1) for a1 in k_vec]


    elif CHOICE == 107:

        n = 10000
        h = 8
        d = 15
        k_vec = [2, 3, 4, 5, 6, 7, 8]
        # k_vec = [4, 5, 7, 10]
        f = 0.09
        distribution = 'uniform'

        # Write in DESCENDING ORDER
        number_of_restarts = [10, 5, 4, 3, 2, 99]
        # number_of_restarts = [20, 10, 5, 4, 3, 2, 100]
        ### 100:GT 99:GTr
        ### 50:min{30,GTr} 1:uninformative

        marker_vec = ['x', 'v', '^', 's', 'o',  's', None] * 10
        markersize_vec = [10, 6, 6, 6, 6, 6, 6] * 10

        labels = [r'$r=$' + str(a1) for a1 in number_of_restarts]
        xtick_lab = k_vec
        xtick_labels = [str(a1) for a1 in k_vec]

    elif CHOICE == 108:

        n = 10000
        h = 8
        d = 15
        k_vec = [2, 3, 4, 5, 6, 7, 8]
        # k_vec = [4, 5, 7, 10]
        f = 0.09
        distribution = 'uniform'

        # Write in DESCENDING ORDER
        number_of_restarts = [10, 5, 4, 3, 2, 99]
        # number_of_restarts = [20, 10, 5, 4, 3, 2, 100]
        ### 100:GT 99:GTr
        ### 50:min{30,GTr} 1:uninformative

        marker_vec = ['x', 'v', '^', 's', 'o',  's', None] * 10
        markersize_vec = [10, 6, 6, 6, 6, 6, 6] * 10

        labels = [r'$r=$' + str(a1) for a1 in number_of_restarts]
        xtick_lab = k_vec
        xtick_labels = [str(a1) for a1 in k_vec]
        repeat_diffGraph = 10

    else:
        raise Warning("Incorrect choice!")

    RANDOMSEED = None  # For repeatability
    random.seed(RANDOMSEED)  # seeds some other python random generator
    np.random.seed(seed=RANDOMSEED)  # seeds the actually used numpy random generator; both are used and thus needed
    # print("CHOICE: {}".format(CHOICE))



    # -- Create data
    if CREATE_DATA or ADD_DATA:
        for _ in range(repeat_diffGraph):

            for k in k_vec:
                a = [1.] * k
                k_star = int(k * (k - 1) / 2)
                alpha0 = np.array(a)
                alpha0 = alpha0 / np.sum(alpha0)

                # Generate Graph
                # print("Generating Graph: n={} h={} d={} k={}".format(n, h, d, k))
                H0 = create_parameterized_H(k, h, symmetric=True)
                W, Xd = planted_distribution_model_H(n, alpha=alpha0, H=H0, d_out=d, distribution=distribution, exponent=exponent, directed=False, debug=False)
                H0_vec = transform_HToh(H0)
                # print("\nGold standard {}".format(np.round(H0_vec, decimals=3)))

                X0 = from_dictionary_beliefs(Xd)
                X2, ind = replace_fraction_of_rows(X0, 1 - f, avoidNeighbors=avoidNeighbors, W=W, ind_prior=None, stratified=stratified)

                h0 = [1.] * int(k_star)
                h0 = np.array(h0)
                h0 = h0 / k

                delta = 1 / (3 * k)
                # print("delta: ", delta)

                perm = []
                while len(perm) < number_of_restarts[0]:
                    temp = []
                    for _ in range(k_star):
                        temp.append(random.choice([-delta, delta]))
                    if temp not in perm:
                        perm.append(temp)
                    if len(perm) >= 2 ** (k_star):
                        break

                E_list = []   ## format = [[energy, H_vec], []..]
                for vec in perm:
                    H2_vec, energy = estimateH(X2, W, method=learning_method, variant=1, distance=length, EC=EC,
                                               weights=weights, randomize=False, constraints=constraint,
                                               gradient=gradient, return_min_energy=True, verbose=verbose,
                                               initial_h0=h0 + np.array(vec))
                    E_list.append([energy, list(H2_vec)])

                # print("All Optimizaed vector:")
                # [print(i) for i in E_list ]

                # print("Outside Energy:{} optimized vec:{} \n".format(min_energy_vec[0], optimized_Hvec))

                # min_energy_vec = min(E_list)
                # optimized_Hvec = min_energy_vec[1]
                #
                # print("\nEnergy:{} optimized vec:{}  \n\n".format(min_energy_vec[0],optimized_Hvec))
                #
                #

                GTr_optimized_Hvec, GTr_energy = estimateH(X2, W, method=learning_method, variant=1, distance=length, EC=EC,
                                                   weights=weights, randomize=False, constraints=constraint,
                                                   gradient=gradient, return_min_energy=True, verbose=verbose,
                                                   initial_h0=H0_vec)

                uninformative_optimized_Hvec, uninformative_energy = estimateH(X2, W, method=learning_method, variant=1, distance=length, EC=EC,
                                                   weights=weights, randomize=False, constraints=constraint,
                                                   gradient=gradient, return_min_energy=True, verbose=verbose,
                                                   initial_h0=h0)


                iterative_permutations = list(E_list)
                for restartz in number_of_restarts:
                    if k==2 or k == 3 and restartz > 8 and restartz<99:
                        continue

                    if restartz <= number_of_restarts[0]:
                        iterative_permutations = random.sample(iterative_permutations, restartz)
                    # print("For restart:{}, we have vectors:\n".format(restartz))
                    # [print(i) for i in  iterative_permutations]


                    if restartz == 100:       ## for GT
                        H2c = to_centering_beliefs(H0)
                        # print("\nGT: ", transform_HToh(H0,k))

                    elif restartz == 99:       ## for DCEr init with GT
                        H2c = to_centering_beliefs(transform_hToH(GTr_optimized_Hvec, k))
                        # print("\nGTr: ", GTr_optimized_Hvec)

                    elif restartz == 1:  ## for DCEr with uninformative initial
                        H2c = to_centering_beliefs(transform_hToH(uninformative_optimized_Hvec, k))
                        # print("\nUninformative: ", uninformative_optimized_Hvec)

                    elif restartz == 50:  ## for min{DCEr , GTr}
                        # print("Length:",len(E_list))
                        # [print(i) for i in E_list]
                        mod_E_list = list(E_list)+[[GTr_energy , list(GTr_optimized_Hvec)]]     #Add GTr to list and take min
                        # print("Mod Length:", len(mod_E_list))
                        # [print(i) for i in mod_E_list]
                        min_energy_vec = min(mod_E_list)
                        # print("\nSelected for 50:",min_energy_vec)
                        optimized_Hvec = min_energy_vec[1]

                        H2c = to_centering_beliefs(transform_hToH(optimized_Hvec, k))

                    else:
                        min_energy_vec = min(iterative_permutations)
                        optimized_Hvec = min_energy_vec[1]
                        H2c = to_centering_beliefs(transform_hToH(optimized_Hvec, k))

                    # print("Inside Chosen Energy:{} optimized vec:{} \n".format(min_energy_vec[0], optimized_Hvec))

                    try:
                        eps_max = eps_convergence_linbp_parameterized(H2c, W, method='noecho', X=X2)
                        s = 0.5
                        eps = s * eps_max

                        F, actualIt, actualPercentageConverged = \
                            linBP_symmetric_parameterized(X2, W, H2c * eps,
                                                          method='noecho',
                                                          numMaxIt=numMaxIt,
                                                          convergencePercentage=convergencePercentage_W,
                                                          debug=2)
                    except ValueError as e:
                        print(
                            "ERROR: {} with {}: d={}, h={}".format(e, learning_method, d, h))

                    else:
                        acc = matrix_difference_classwise(X0, F, ignore_rows=ind)

                        tuple = [str(datetime.datetime.now())]
                        text = [k,
                                restartz,
                                acc]
                        tuple.extend(text)

                        if verbose:
                            print("\nGold standard {}".format(np.round(H0_vec, decimals=3)))
                        # print("k:{}  Restart:{}  OptimizedVec:{}  Energy:{}  Accuracy:{}".format(k, restartz, np.round(min_energy_vec[1], decimals=3), min_energy_vec[0], acc  ))
                        # print("k:{}  Restart:{}   Accuracy:{}".format(k, 1, L2_dist))
                        save_csv_record(join(data_directory, csv_filename), tuple)



    # -- Read, aggregate, and pivot data for all options
    df1 = pd.read_csv(join(data_directory, csv_filename))
    # print("\n-- df1 (length {}):\n{}".format(len(df1.index), df1.head(20)))

    # Aggregate repetitions
    df2 = df1.groupby(['k', 'restarts']).agg \
        ({'accuracy': [np.mean, np.std, np.size], })
    df2.columns = ['_'.join(col).strip() for col in df2.columns.values]  # flatten the column hierarchy
    df2.reset_index(inplace=True)  # remove the index hierarchy
    df2.rename(columns={'accuracy_size': 'count'}, inplace=True)
    df2['restarts'] = df2['restarts'].astype(str)
    # print("\n-- df2 (length {}):\n{}".format(len(df2.index), df2.head(20)))

    # Pivot table
    df3 = pd.pivot_table(df2, index=['k'], columns=['restarts'], values=['accuracy_mean', 'accuracy_std'] )  # Pivot
    # print("\n-- df3 (length {}):\n{}".format(len(df3.index), df3.head(30)))
    df3.columns = ['_'.join(col).strip() for col in df3.columns.values]  # flatten the column hierarchy
    df3.reset_index(inplace=True)  # remove the index hierarchy
    # print("\n-- df3 (length {}):\n{}".format(len(df3.index), df3.head(10)))




    df4 = df3.drop('k', axis=1)
    if NOGT:
        df4 = df3.drop(['k', 'accuracy_mean_0', 'accuracy_mean_1', 'accuracy_std_0', 'accuracy_std_1'], axis=1)

    # df4 = df3.drop(['k', 'accuracy_mean_100', 'accuracy_std_100'], axis=1)


    df5 = df4.div(df4.max(axis=1), axis=0)
    df5['k'] = df3['k']
    # print("\n-- df5 (length {}):\n{}".format(len(df5.index), df5.head(100)))

    # df5 = df3     ## for normalization

    X_f = df5['k'].values            # read k from values instead
    Y=[]
    Y_std=[]
    for rez in number_of_restarts:
        if NOGT:
            if rez == 100 or rez==99:
                continue
        Y.append(df5['accuracy_mean_{}'.format(rez)].values)
        if STD_FILL:
            Y_std.append(df5['accuracy_std_{}'.format(rez)].values)



    if CREATE_PDF or SHOW_PDF or SHOW_PLOT:

        # -- Setup figure
        mpl.rc('font', **{'family': 'sans-serif', 'sans-serif': [u'Arial', u'Liberation Sans']})
        mpl.rcParams['axes.labelsize'] = 20
        mpl.rcParams['xtick.labelsize'] = 16
        mpl.rcParams['ytick.labelsize'] = 16
        mpl.rcParams['legend.fontsize'] = 14
        mpl.rcParams['grid.color'] = '777777'  # grid color
        mpl.rcParams['xtick.major.pad'] = 2  # padding of tick labels: default = 4
        mpl.rcParams['ytick.major.pad'] = 1  # padding of tick labels: default = 4
        mpl.rcParams['xtick.direction'] = 'out'  # default: 'in'
        mpl.rcParams['ytick.direction'] = 'out'  # default: 'in'
        mpl.rcParams['font.size'] = 16
        mpl.rcParams['axes.titlesize'] = 16
        mpl.rcParams['figure.figsize'] = [4, 4]
        fig = figure()
        ax = fig.add_axes([0.13, 0.17, 0.8, 0.8])


        #  -- Drawing
        if STD_FILL:
            for choice, (option, facecolor) in enumerate(zip(number_of_restarts, facecolor_vec)):
                if option == 100:  ## GT
                    if NOGT:
                        continue
                    facecolor = 'black'
                elif option == 99:  ## GT-r
                    if NOGT:
                        continue
                    facecolor = 'black'

                ax.fill_between(X_f, Y[choice] + Y_std[choice], Y[choice] - Y_std[choice],
                                facecolor=facecolor, alpha=0.2, edgecolor=None, linewidth=0)
                ax.plot(X_f, Y[choice] + Y_std[choice], linewidth=0.5, color='0.8', linestyle='solid')
                ax.plot(X_f, Y[choice] - Y_std[choice], linewidth=0.5, color='0.8', linestyle='solid')

        for choice, (option, label, color, linewidth, clip_on, linestyle, marker, markersize) in \
                enumerate(zip(number_of_restarts, labels, facecolor_vec, linewidth_vec, clip_on_vec, linestyle_vec, marker_vec, markersize_vec)):

            if option == 100:     ## GT
                if NOGT:
                    continue
                linestyle='dashed'
                linewidth=3
                color='black'
                label='GS'
                marker='x'
                markersize=6
            elif option == 99:       ## GT-r
                if NOGT:
                    continue
                linestyle='dashed'
                linewidth=2
                color='black'
                label='Global Minima'
                marker = None
                markersize = 6
            elif option == 1:     ## GT
                color="#CCB974"
                linewidth = 2
                label='Uninfo'
            elif option == 50:       ## GT-r
                label='min{30,GTr}'

            P = ax.plot(X_f, Y[choice], linewidth=linewidth, color=color, linestyle=linestyle, label=label, zorder=4, marker=marker,
                    markersize=markersize, markeredgecolor='black',  markeredgewidth=1, clip_on=clip_on)

        # plt.xscale('log')

        # -- Title and legend
        distribution_label = '$'
        if distribution == 'uniform':
            distribution_label = ',$uniform'
        n_label = '{}k'.format(int(n / 1000))
        if n < 1000:
            n_label='{}'.format(n)

        titleString = r'$\!\!\!n\!=\!{}, d\!=\!{}, h\!=\!{}, f\!=\!{} $'.format(n_label, d, h, f)
        title(titleString)

        handles, labels = ax.get_legend_handles_labels()
        legend = plt.legend(handles, labels,
                            loc='lower left',     # 'upper right'
                            handlelength=2,
                            labelspacing=0,  # distance between label entries
                            handletextpad=0.3,  # distance between label and the line representation
                            borderaxespad=0.2,  # distance between legend and the outer axes
                            borderpad=0.3,  # padding inside legend box
                            numpoints=1,  # put the marker only once
                            # bbox_to_anchor=(1.1, 0)
                            )
        # # legend.set_zorder(1)
        frame = legend.get_frame()
        frame.set_linewidth(0.0)
        frame.set_alpha(0.9)  # 0.8

        plt.xticks(xtick_lab, xtick_labels)
        # plt.yticks(ytick_lab, ytick_lab)


        ax.yaxis.set_ticks_position('left')
        ax.xaxis.set_ticks_position('bottom')
        ax.yaxis.set_major_formatter(mpl.ticker.FormatStrFormatter('%.2f'))
        # ax.xaxis.set_major_formatter(mpl.ticker.FormatStrFormatter('%.0f'))

        grid(b=True, which='major', axis='both', alpha=0.2, linestyle='solid', linewidth=0.5)  # linestyle='dashed', which='minor', axis='y',
        grid(b=True, which='minor', axis='both', alpha=0.2, linestyle='solid', linewidth=0.5)  # linestyle='dashed', which='minor', axis='y',
        xlabel(r'Number of Classes $(k)$', labelpad=0)      # labelpad=0
        ylabel(r'Relative Accuracy', labelpad=0)

        xlim(2.9, 7.1)
        #
        ylim(0.65, 1.015)

        if CREATE_PDF:
            savefig(join(figure_directory, fig_filename), format='pdf',
                    dpi=None,
                    edgecolor='w',
                    orientation='portrait',
                    transparent=False,
                    bbox_inches='tight',
                    pad_inches=0.05,
                    frameon=None)
        if SHOW_PLOT:
            plt.show()

        if SHOW_PDF:
            showfig(join(figure_directory, fig_filename))  # shows actually created PDF
Exemple #6
0
def _f_worker_(X0, W, f, f_index):
    RANDOMSEED = None  # For repeatability
    random.seed(RANDOMSEED)  # seeds some other python random generator
    np.random.seed(
        seed=RANDOMSEED
    )  # seeds the actually used numpy random generator; both are used and thus needed

    X1, ind = replace_fraction_of_rows(X0,
                                       1 - f,
                                       avoidNeighbors=avoidNeighbors,
                                       W=W,
                                       stratified=stratified)
    X2 = introduce_errors(X1, ind, err)


    for option_index, (label, select_lambda, learning_method, alpha, beta, gamma, s, numMaxIt, weights, randomize) in \
            enumerate(zip(labels, select_lambda_vec, learning_method_vec, alpha_vec, beta_vec, gamma_vec, s_vec, numMaxIt_vec, weight_vec, randomize_vec)):
        learn_time = -1
        # -- Learning
        if learning_method == 'GT':
            H2c = H0c
        elif learning_method == 'Heuristic':
            # print('Heuristic')
            H2c = H_heuristic

        elif learning_method == 'Holdout':
            # print('Holdout')
            H2 = estimateH_baseline_serial(
                X2,
                ind,
                W,
                numMax=numMaxIt,
                # ignore_rows=ind,
                numberOfSplits=numberOfSplits,
                # method=learning_method, variant=1,
                # distance=length,
                EC=EC,
                alpha=alpha,
                beta=beta,
                gamma=gamma,
                doubly_stochastic=doubly_stochastic)
            H2c = to_centering_beliefs(H2)

        else:
            if "DCEr" in learning_method:
                learning_method = "DCEr"
            elif "DCE" in learning_method:
                learning_method = "DCE"

            # -- choose optimal lambda: allows to specify different lambda for different f
            # print("option: ", option_index)
            if select_lambda == True:
                weight = lambda_vec[f_index]
                # print("weight : ", weight)
            else:
                weight = weights

            # -- learn H
            learn_start = time.time()
            H2 = estimateH(X2,
                           W,
                           method=learning_method,
                           variant=1,
                           distance=length,
                           EC=EC,
                           weights=weight,
                           randomrestarts=num_restarts,
                           randomize=randomize,
                           constraints=constraints,
                           gradient=gradient,
                           doubly_stochastic=doubly_stochastic)
            learn_time = time.time() - learn_start
            H2c = to_centering_beliefs(H2)

        # if learning_method not in ['GT', 'GS']:

        # print(FILENAMEZ, f, learning_method)
        # print(H2c)

        # -- Propagation
        prop_start = time.time()
        # X2c = to_centering_beliefs(X2, ignoreZeroRows=True)       # try without
        eps_max = eps_convergence_linbp_parameterized(H2c,
                                                      W,
                                                      method='noecho',
                                                      alpha=alpha,
                                                      beta=beta,
                                                      gamma=gamma,
                                                      X=X2)
        eps = s * eps_max
        # print("Max eps: {}, eps: {}".format(eps_max, eps))
        # eps = 1

        try:
            F, actualIt, actualPercentageConverged = \
                linBP_symmetric_parameterized(X2, W, H2c * eps,
                                              method='noecho',
                                              alpha=alpha, beta=beta, gamma=gamma,
                                              numMaxIt=numMaxIt,
                                              convergencePercentage=convergencePercentage_W,
                                              debug=2)
            prop_time = time.time() - prop_start
            if Macro_Accuracy:
                accuracy_X = matrix_difference_classwise(X0,
                                                         F,
                                                         ignore_rows=ind)
                precision = matrix_difference_classwise(X0,
                                                        F,
                                                        similarity='precision',
                                                        ignore_rows=ind)
                recall = matrix_difference_classwise(X0,
                                                     F,
                                                     similarity='recall',
                                                     ignore_rows=ind)
            else:
                accuracy_X = matrix_difference(X0, F, ignore_rows=ind)
                precision = matrix_difference(X0,
                                              F,
                                              similarity='precision',
                                              ignore_rows=ind)
                recall = matrix_difference(X0,
                                           F,
                                           similarity='recall',
                                           ignore_rows=ind)

            result = [str(datetime.datetime.now())]
            text = [
                label, f, accuracy_X, precision, recall, learn_time, prop_time
            ]
            result.extend(text)
            # print("method: {}, f: {}, actualIt: {}, accuracy: {}, precision:{}, recall: {}, learning time: {}, propagation time: {}".format(label, f, actualIt, accuracy_X, precision, recall, learn_time, prop_time))
            save_csv_record(join(data_directory, csv_filename), result)

        except ValueError as e:

            print("ERROR: {} with {}: d={}, h={}".format(
                e, learning_method, d, h))
            raise e

    return 'success'
Exemple #7
0
def run(choice, create_data=False, add_data=False, show_plot=False, create_pdf=False, show_pdf=False, shorten_length=False,
        show_arrows=False):
    # -- Setup
    CHOICE = choice
    CREATE_DATA = create_data
    ADD_DATA = add_data
    SHOW_PLOT = show_plot
    SHOW_PDF = show_pdf
    CREATE_PDF = create_pdf

    SHOW_STD = True         ## FALSE for just scatter plot points
    SHOW_ARROWS = show_arrows


    # -- Default Graph parameters
    rep_SameGraph = 1       # iterations on same graph
    distribution = 'powerlaw'
    exponent = -0.3
    length = 5
    variant = 1
    EC = False
    numberOfSplits = 1
    scaling_vec = [None]*10
    ymin = 0.3
    ymax = 1
    xmin = 1e-3
    xmax = 1e3
    xtick_lab = [1e-3, 0.01, 0.1, 1, 10, 100, 1000]
    xtick_labels = [r'$10^{-3}$', r'$10^{-2}$', r'$10^{-1}$', r'$1$', r'$10$', r'$10^{2}$', r'$10^{3}$']
    ytick_lab = np.arange(0, 1.1, 0.1)
    k = 3
    a = 1
    rep_DifferentGraphs = 1   # iterations on different graphs
    err = 0
    avoidNeighbors = False
    convergencePercentage_W = 0.99
    facecolor_vec = ["#4C72B0", "#55A868", "#8172B2", "#C44E52", "#CCB974", "#64B5CD"]
    label_vec = ['MCE', 'LCE', 'DCE', 'Holdout']
    linewidth_vec = [4, 3, 1, 2, 2, 1]
    # clip_ons = [True, True, True, True, True, True]
    FILEZNAME = 'Fig_timing_accuracy_learning'
    marker_vec = ['s', '^', 'v', 'o', 'x', '+', 'None']   #'^'
    length_vec = [5]
    stratified = True
    f = 0.01
    numMaxIt_vec = [10]*7
    alpha_vec = [0] * 7
    beta_vec = [0] * 7  # TODO: LinBP does not use beta. Also SSLH uses alpha, but not beta for W^row! Now fixed
    gamma_vec = [0] * 7
    s_vec = [0.5] * 7


    # -- Main Options
    if CHOICE == 1:         # Main graph
        n = 1000
        h = 3
        d = 25
        option_vec = ['opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6']
        learning_method_vec = ['MHE']  + ['LHE'] + ['DHE'] + ['DHE'] + ['Holdout'] + ['GS']
        label_vec = ['MCE', 'LCE', 'DCE', 'DCE r', 'Holdout', 'GS']
        randomize_vec = [False]*3 + [True] + [None]*2
        scaling_vec = [None]*2 + [10, 100] + [None]*2
        splits_vec = [1, 2, 4, 8]


    elif CHOICE == 2:
        n = 1000
        h = 3
        d = 25
        option_vec = ['opt1', 'opt2', 'opt3', 'opt4', 'opt5']
        learning_method_vec = ['MHE']  + ['LHE'] + ['DHE'] + ['DHE'] + ['GS']
        label_vec = ['MCE', 'LCE', 'DCE', 'DCE r', 'GS']
        randomize_vec = [False]*3 + [True] + [None]
        scaling_vec = [None]*2 + [10, 100] + [None]


    elif CHOICE == 3:
        n = 1000
        h = 3
        d = 25
        option_vec = ['opt1', 'opt2', 'opt3', 'opt4', 'opt5']
        learning_method_vec = ['MHE']  + ['LHE'] + ['DHE'] + ['DHE'] + ['GS']
        label_vec = ['MCE', 'LCE', 'DCE', 'DCE r', 'GS']
        randomize_vec = [False]*3 + [True] + [None]
        scaling_vec = [None]*2 + [10, 100] + [None]
        f = 0.02


    elif CHOICE == 4:         # TODO: Overnight Wolfgang
        n = 1000
        h = 3
        d = 25
        option_vec = ['opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6']
        learning_method_vec = ['MHE']  + ['LHE'] + ['DHE'] + ['DHE'] + ['Holdout'] + ['GS']
        label_vec = ['MCE', 'LCE', 'DCE', 'DCE r', 'Holdout', 'GS']
        randomize_vec = [False]*3 + [True] + [None]*2
        scaling_vec = [None]*2 + [10, 100] + [None]*2
        splits_vec = [1, 2, 4, 8, 16]


    elif CHOICE == 5:         # Toy graph with 100 nodes
        n = 100
        h = 3
        d = 8
        option_vec = ['opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6']
        learning_method_vec = ['MHE']  + ['LHE'] + ['DHE'] + ['DHE'] + ['Holdout'] + ['GS']
        label_vec = ['MCE', 'LCE', 'DCE', 'DCE r', 'Holdout', 'GS']
        randomize_vec = [False]*3 + [True] + [None]*2
        scaling_vec = [None]*2 + [10, 100] + [None]*2
        splits_vec = [1, 2, 4, 8]
        f=0.05


    elif CHOICE == 6:         # To be run by Prakhar on Cluster
        n = 10000
        h = 3
        d = 25
        option_vec = ['opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6']
        learning_method_vec = ['MHE']  + ['LHE'] + ['DHE'] + ['DHE'] + ['Holdout'] + ['GS']
        label_vec = ['MCE', 'LCE', 'DCE', 'DCEr', 'Holdout', 'GS']
        randomize_vec = [False]*3 + [True] + [None]*2
        scaling_vec = [None]*2 + [10, 100] + [None]*2
        splits_vec = [1, 2, 4, 8]
        f=0.003
        xmin = 1e-2
        # ymax = 0.9
        ymin = 0.2
        ymax = 0.9
        xmin = 1e-2
        xmax = 1e3



    elif CHOICE == 7:
        n = 1000
        h = 3
        d = 25
        option_vec = ['opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6']
        learning_method_vec = ['MHE']  + ['LHE'] + ['DHE'] + ['DHE'] + ['Holdout'] + ['GS']
        label_vec = ['MCE', 'LCE', 'DCE', 'DCE r', 'Holdout', 'GS']
        randomize_vec = [False]*3 + [True] + [None]*2
        scaling_vec = [None]*2 + [10, 100] + [None]*2
        splits_vec = [1, 2, 4, 8, 16]
        f=0.009

    # elif CHOICE == 8:       # not working well
    #     n = 1000
    #     h = 3
    #     d = 25
    #     option_vec = ['opt1', 'opt2', 'opt3', 'opt4', 'opt5', 'opt6']
    #     learning_method_vec = ['MHE']  + ['LHE'] + ['DHE'] + ['DHE'] + ['Holdout'] + ['GS']
    #     label_vec = ['MCE', 'LCE', 'DCE', 'DCE r', 'Holdout', 'GS']
    #     randomize_vec = [False]*3 + [True] + [None]*2
    #     scaling_vec = [None]*2 + [10, 100] + [None]*2
    #     splits_vec = [1, 2, 4, 8, 16]
    #     f=0.005



    else:
        raise Warning("Incorrect choice!")



    csv_filename = '{}_{}.csv'.format(FILEZNAME, CHOICE)
    header = ['currenttime',
              'option',
              'lensplit',
              'f',
              'accuracy',
              'timetaken']
    if CREATE_DATA:
        save_csv_record(join(data_directory, csv_filename), header, append=False)

    alpha0 = np.array([a, 1., 1.])
    alpha0 = alpha0 / np.sum(alpha0)
    H0 = create_parameterized_H(k, h, symmetric=True)
    H0c = to_centering_beliefs(H0)


    RANDOMSEED = None  # For repeatability
    random.seed(RANDOMSEED)  # seeds some other python random generator
    np.random.seed(seed=RANDOMSEED)  # seeds the actually used numpy random generator; both are used and thus needed
    # print("CHOICE: {}".format(CHOICE))


    # -- Create data
    if CREATE_DATA or ADD_DATA:
        for i in range(rep_DifferentGraphs):  # create several graphs with same parameters
            # print("\ni: {}".format(i))

            W, Xd = planted_distribution_model_H(n, alpha=alpha0, H=H0, d_out=d,
                                                      distribution=distribution,
                                                      exponent=exponent,
                                                      directed=False,
                                                      debug=False)
            X0 = from_dictionary_beliefs(Xd)

            for j in range(rep_SameGraph):  # repeat several times for same graph
                # print("j: {}".format(j))

                ind = None
                X1, ind = replace_fraction_of_rows(X0, 1-f, avoidNeighbors=avoidNeighbors, W=W, ind_prior=ind, stratified = stratified)     # TODO: stratified sampling option = True
                X2 = introduce_errors(X1, ind, err)

                for option_index, (learning_method, alpha, beta, gamma, s, numMaxIt, weight, randomize, option) in \
                        enumerate(zip(learning_method_vec, alpha_vec, beta_vec, gamma_vec, s_vec, numMaxIt_vec, scaling_vec, randomize_vec, option_vec)):

                    # weight = np.array([np.power(scaling, i) for i in range(5)])       # TODO: now enough to specify weight as a scalar!
                    H_est_dict = {}
                    timeTaken_dict = {}

                    # -- Learning
                    if learning_method == 'Holdout' :
                        for numberOfSplits in splits_vec:
                            prev_time = time.time()
                            H_est_dict[numberOfSplits] = estimateH_baseline_serial(X2, ind, W, numMax=numMaxIt,
                                                                                   # ignore_rows=ind,
                                                                                   numberOfSplits=numberOfSplits,
                                                                                   # method=learning_method, variant=1, distance=length,
                                                                                   EC=EC,
                                                                                   weights=weight, alpha=alpha, beta=beta, gamma=gamma)
                            timeTaken = time.time() - prev_time
                            timeTaken_dict[numberOfSplits] = timeTaken

                    elif learning_method in ['LHE', 'MHE', 'DHE']:      # TODO: no smartInit, just randomization as option
                        for length in length_vec:
                            prev_time = time.time()
                            H_est_dict[length] = estimateH(X2, W, method=learning_method, variant=1, randomize=randomize, distance=length, EC=EC, weights=weight)
                            timeTaken = time.time() - prev_time
                            timeTaken_dict[length] = timeTaken

                    elif learning_method == 'GS':
                        H_est_dict['GS'] = H0

                    for key in H_est_dict:
                        H_est = H_est_dict[key]
                        H2c = to_centering_beliefs(H_est)
                        # print("H_estimated by {} is \n".format(learning_method), H_est)
                        # print("H0 is \n", H0)
                        # print("randomize was: ", randomize)

                        # Propagation
                        X2c = to_centering_beliefs(X2, ignoreZeroRows=True)  # try without
                        eps_max = eps_convergence_linbp_parameterized(H2c, W,
                                                                      method='noecho',
                                                                      alpha=alpha, beta=beta, gamma=gamma,
                                                                      X=X2)

                        eps = s * eps_max

                        # print("Max Eps ", eps_max)

                        try:
                            F, actualIt, actualPercentageConverged = \
                                linBP_symmetric_parameterized(X2, W, H2c * eps,
                                                              method='noecho',
                                                              alpha=alpha, beta=beta, gamma=gamma,
                                                              numMaxIt=numMaxIt,
                                                              convergencePercentage=convergencePercentage_W,
                                                              convergenceThreshold=0.99,
                                                              debug=2)

                        except ValueError as e:
                            print(
                                "ERROR: {} with {}: d={}, h={}".format(e, learning_method, d, h))

                        else:
                            accuracy_X = matrix_difference(X0, F, ignore_rows=ind)

                            tuple = [str(datetime.datetime.now())]
                            if learning_method == 'Holdout':
                                text = [option,"split{}".format(key), f, accuracy_X, timeTaken_dict[key]]
                            elif learning_method in ['MHE', 'DHE', 'LHE']:
                                text = [option, "len{}".format(key), f, accuracy_X, timeTaken_dict[key]]
                            elif learning_method == 'GS':
                                text = [option, 0, f, accuracy_X, 0]

                            tuple.extend(text)
                            # print("option: {}, f: {}, actualIt: {}, accuracy: {}".format(option, f, actualIt, accuracy_X))
                            save_csv_record(join(data_directory, csv_filename), tuple)





    # -- Read, aggregate, and pivot data for all options
    df1 = pd.read_csv(join(data_directory, csv_filename))
    # print("\n-- df1: (length {}):\n{}".format(len(df1.index), df1.head(15)))

    # Aggregate repetitions
    df2 = df1.groupby(['option', 'lensplit', 'f']).agg \
        ({'accuracy': [np.mean, np.std, np.size],  # Multiple Aggregates
          })
    df2.columns = ['_'.join(col).strip() for col in df2.columns.values]  # flatten the column hierarchy
    df2.reset_index(inplace=True)  # remove the index hierarchy
    df2.rename(columns={'accuracy_size': 'count'}, inplace=True)
    # print("\n-- df2 (length {}):\n{}".format(len(df2.index), df2.head(15)))

    df3 = df1.groupby(['option', 'lensplit', 'f']).agg({'timetaken': [np.median] })
    df3.columns = ['_'.join(col).strip() for col in df3.columns.values]  # flatten the column hierarchy
    df3.reset_index(inplace=True)  # remove the index hierarchy
    # resultdf3 = df3.sort(['timetaken'], ascending=1)
    # print("\n-- df3 (length {}):\n{}".format(len(df3.index), df3.head(15)))

    X_time_median_dict = {}
    Y_acc_dict = {}
    Y_std_dict = {}

    for option in option_vec:
        Y_acc_dict[option] = df2.loc[(df2['option'] == option), "accuracy_mean"].values
        Y_std_dict[option] = df2.loc[(df2['option'] == option), "accuracy_std"].values
        X_time_median_dict[option] = df3.loc[(df3['option'] == option), "timetaken_median"].values

        # print("option: ", option)
        # print("Y_acc_dict[option]: ", Y_acc_dict[option])
        # print("Y_std_dict[option]: ", Y_std_dict[option])
        # print("X_time_median_dict[option]: ", X_time_median_dict[option])



    # -- Setup figure
    fig_filename = '{}_{}.pdf'.format(FILEZNAME, CHOICE)
    mpl.rc('font', **{'family': 'sans-serif', 'sans-serif': [u'Arial', u'Liberation Sans']})
    mpl.rcParams['axes.labelsize'] = 18
    mpl.rcParams['xtick.labelsize'] = 16
    mpl.rcParams['ytick.labelsize'] = 16
    mpl.rcParams['axes.titlesize'] = 16
    mpl.rcParams['legend.fontsize'] = 14
    mpl.rcParams['grid.color'] = '777777'  # grid color
    mpl.rcParams['xtick.major.pad'] = 2  # padding of tick labels: default = 4
    mpl.rcParams['ytick.major.pad'] = 1  # padding of tick labels: default = 4
    mpl.rcParams['xtick.direction'] = 'out'  # default: 'in'
    mpl.rcParams['ytick.direction'] = 'out'  # default: 'in'
    mpl.rcParams['figure.figsize'] = [4, 4]
    fig = figure()
    ax = fig.add_axes([0.13, 0.17, 0.8, 0.8])


    SHOW_ARROWS = True

    for choice, color, learning_method, label, linewidth, marker in \
            zip(option_vec, facecolor_vec, learning_method_vec, label_vec, linewidth_vec, marker_vec):

        if learning_method == 'Holdout':
            # Draw std
            X1 = X_time_median_dict[choice]
            s = X1.argsort()
            X1 = X1[s]
            Y1 = Y_acc_dict[choice][s]
            Y2 = Y_std_dict[choice][s]

            if SHOW_STD:
                ax.fill_between(X1, Y1 + Y2, Y1 - Y2, facecolor=color, alpha=0.2, edgecolor=None, linewidth=0)
                ax.plot(X1, Y1 + Y2, linewidth=0.5, color='0.8', linestyle='solid')
                ax.plot(X1, Y1 - Y2, linewidth=0.5, color='0.8', linestyle='solid')
                ax.set_ylim(bottom=ymin)

                ax.plot(X1, Y1, linewidth=linewidth, color=color, linestyle='solid', label=label, zorder=20, marker='x', markersize=linewidth + 5, markeredgewidth=1)
                ax.annotate(np.round(X1[1], decimals=1), xy=(X1[1], Y1[1] - 0.05), color=color, va='center', annotation_clip=False, zorder=5)

            else:
                ax.scatter(list(X1), list(Y1),
                           color=color, label=label, marker='x', s=42)


        elif learning_method == 'GS':
            ax.plot([1e-4, 1e4], [Y_acc_dict[choice], Y_acc_dict[choice]],
                    linewidth=1, color='black',
                    linestyle='dashed', zorder=0,
                    marker=None,
                    label=label,
                    )

        else:       # For all other
            if SHOW_STD:
                ax.errorbar(list(X_time_median_dict[choice]), list(Y_acc_dict[choice]), yerr=Y_std_dict[choice],
                            fmt='-o', linewidth=2, color=color,
                            label=label, marker=marker, markersize=8)
                ax.annotate(np.round(X_time_median_dict[choice], decimals=2), xy=(X_time_median_dict[choice], Y_acc_dict[choice]-0.05), color=color, va='center',
                            annotation_clip=False, zorder=5)

            else:
                ax.scatter(list(X_time_median_dict[choice]), list(Y_acc_dict[choice]),
                           color=color, label=label, marker=marker, s=42)

        if SHOW_ARROWS:
            dce_opt = 'opt4'
            holdout_opt = 'opt5'

            ax.annotate(s='', xy=(X_time_median_dict[dce_opt], Y_acc_dict[dce_opt]-0.3), xytext=(X_time_median_dict[holdout_opt][2]+0.02, Y_acc_dict[dce_opt]-0.3), arrowprops=dict(arrowstyle='<->'))
            ax.annotate(str(int(np.round(X_time_median_dict[holdout_opt][2] / X_time_median_dict[dce_opt]))) + 'x', xy=((X_time_median_dict[dce_opt] + X_time_median_dict[holdout_opt][2])/100, Y_acc_dict[dce_opt]-0.28),
                        color='black', va='center',
                        # bbox = dict(boxstyle="round,pad=0.3", fc="w"),
                        annotation_clip=False, zorder=5)






    # -- Title and legend
    title(r'$\!\!\!n\!=\!{}\mathrm{{k}}, d\!=\!{}, h\!=\!{}, f\!=\!{}$'.format(int(n / 1000), d, h, f))
    handles, label_vec = ax.get_legend_handles_labels()
    for i, (h, learning_method) in enumerate(zip(handles, learning_method_vec)):        # remove error bars in legend
        if isinstance(handles[i], collections.Container):
            handles[i] = handles[i][0]

    # plt.legend(loc='upper left', numpoints=1, ncol=3, fontsize=8, bbox_to_anchor=(0, 0))

    SHOW_STD = False


    legend = plt.legend(handles, label_vec,
                        loc='upper right',  # 'upper right'
                        handlelength=2,
                        fontsize=12,
                        labelspacing=0.2,  # distance between label entries
                        handletextpad=0.3,  # distance between label and the line representation
                        borderaxespad=0.2,  # distance between legend and the outer axes
                        borderpad=0.3,  # padding inside legend box
                        numpoints=1,  # put the marker only once
                        )
    if not(SHOW_STD):
        legend = plt.legend(handles, label_vec,
                        loc='upper right',  # 'upper right'
                        handlelength=2,
                        fontsize=10,
                        labelspacing=0.2,  # distance between label entries
                        handletextpad=0.3,  # distance between label and the line representation
                        borderaxespad=0.2,  # distance between legend and the outer axes
                        borderpad=0.3,  # padding inside legend box
                        numpoints=1,  # put the marker only once
                        scatterpoints=1  # display only one-scatter point in legend
                        )

    # # legend.set_zorder(1)
    frame = legend.get_frame()
    frame.set_linewidth(0.0)
    frame.set_alpha(0.9)  # 0.8


    # -- Figure settings and save
    plt.xscale('log')
    plt.xticks(xtick_lab, xtick_labels)
    plt.yticks(ytick_lab, ytick_lab)
    ax.yaxis.set_major_formatter(mpl.ticker.FormatStrFormatter('%.1f'))
    ax.yaxis.set_ticks_position('left')
    ax.xaxis.set_ticks_position('bottom')
    ax.set_ylim(bottom=ymin)

    grid(b=True, which='major', axis='both', alpha=0.2, linestyle='solid', linewidth=0.5)  # linestyle='dashed', which='minor', axis='y',
    grid(b=True, which='minor', axis='both', alpha=0.2, linestyle='solid', linewidth=0.5)  # linestyle='dashed', which='minor', axis='y',

    xlim(xmin, xmax)
    ylim(ymin, ymax)


    xlabel(r'Time Median (sec)', labelpad=0)      # labelpad=0
    ylabel(r'Accuracy', labelpad=0)
    if CREATE_PDF:
        savefig(join(figure_directory, fig_filename), format='pdf',
                dpi=None,
                edgecolor='w',
                orientation='portrait',
                transparent=False,
                bbox_inches='tight',
                pad_inches=0.05,
                frameon=None)

    if SHOW_PDF:
        showfig(join(figure_directory, fig_filename))

    if SHOW_PLOT:
        plt.show()
def run(choice, create_data=False, add_data=False, show_plot=False, create_pdf=False, show_pdf=False, shorten_length=False):
    CHOICE = choice

    CREATE_DATA = create_data
    ADD_DATA = add_data
    SHOW_PLOT = show_plot
    SHOW_PDF = show_pdf
    CREATE_PDF = create_pdf

    STD_FILL = True
    #
    SHORTEN_LENGTH = False

    fig_filename = 'Fig_homophily_{}.pdf'.format(CHOICE)
    csv_filename = 'Fig_homophily_{}.csv'.format(CHOICE)
    header = ['currenttime',
              'option',
              'f',
              'accuracy']
    if CREATE_DATA:
        save_csv_record(join(data_directory, csv_filename), header, append=False)


    # -- Default Graph parameters
    k = 3
    rep_DifferentGraphs = 1
    rep_SameGraph = 2
    initial_h0 = None
    distribution = 'powerlaw'
    exponent = -0.3
    length = 5
    constraint = True

    variant = 1
    EC = True                   # Non-backtracking for learning
    global f_vec, labels, facecolor_vec

    s = 0.5
    err = 0
    numMaxIt = 10
    avoidNeighbors = False
    convergencePercentage_W = None
    stratified = True


    clip_on_vec = [True] * 10
    draw_std_vec = range(10)
    ymin = 0.3
    ymax = 1
    xmin = 0.001
    xmax = 1
    xtick_lab = [0.00001, 0.0001, 0.001, 0.01, 0.1, 1]
    xtick_labels = ['1e-5', '0.01\%', '0.1\%', '1\%', '10\%', '100\%']
    ytick_lab = np.arange(0, 1.1, 0.1)
    linestyle_vec = ['dashed'] + ['solid'] * 10
    linewidth_vec = [5, 2, 3, 3, 3, 3] + [3]*10
    marker_vec = [None, '^', 'v', 'o', '^'] + [None]*10
    markersize_vec = [0, 8, 8, 8, 6, 6] + [6]*10
    facecolor_vec = ['black', "#C44E52",  "#64B5CD"]


    # -- Options with propagation variants
    if CHOICE == 101:
        n = 10000
        h = 3
        d = 15
        f_vec = [0.9 * pow(0.1, 1 / 5) ** x for x in range(21)]
        option_vec = ['opt1', 'opt2', 'opt3']
        learning_method_vec = ['GT','DHE','Homophily']
        weight_vec = [None] + [10] + [None]
        randomize_vec = [None] + [True] + [None]
        xmin = 0.001
        ymin = 0.3
        ymax = 1
        labels = ['GS', 'DCEr', 'Homophily']

    else:
        raise Warning("Incorrect choice!")

    a = 1
    alpha0 = np.array([a, 1., 1.])
    alpha0 = alpha0 / np.sum(alpha0)

    H0 = create_parameterized_H(k, h, symmetric=True)
    RANDOMSEED = None  # For repeatability
    random.seed(RANDOMSEED)  # seeds some other python random generator
    np.random.seed(seed=RANDOMSEED)  # seeds the actually used numpy random generator; both are used and thus needed
    # print("CHOICE: {}".format(CHOICE))


    # -- Create data
    if CREATE_DATA or ADD_DATA:
        for i in range(rep_DifferentGraphs):  # create several graphs with same parameters

            W, Xd = planted_distribution_model_H(n, alpha=alpha0, H=H0, d_out=d, distribution=distribution,
                                                      exponent=exponent, directed=False, debug=False)
            X0 = from_dictionary_beliefs(Xd)

            for j in range(rep_SameGraph):  # repeat several times for same graph
                # print("Graph:{} and j: {}".format(i,j))

                ind = None
                for f in f_vec:
                    X1, ind = replace_fraction_of_rows(X0, 1-f, avoidNeighbors=avoidNeighbors, W=W, ind_prior=ind, stratified=stratified)
                    X2 = introduce_errors(X1, ind, err)

                    for option_index, (option, learning_method,  weights, randomize) in \
                            enumerate(zip(option_vec, learning_method_vec, weight_vec, randomize_vec)):

                        # -- Learning
                        if learning_method == 'GT':
                            H2 = H0
                        elif learning_method == 'Homophily':
                            H2 = np.identity(k)

                        elif learning_method == 'DHE':
                            H2 = estimateH(X2, W, method=learning_method, variant=1, distance=length, EC=EC, weights=weights, randomize=randomize, constraints=constraint)
                            # print("learning_method:", learning_method)
                            # print("H:\n{}".format(H2))

                        # -- Propagation
                        H2c = to_centering_beliefs(H2)
                        X2c = to_centering_beliefs(X2, ignoreZeroRows=True)

                        try:
                            eps_max = eps_convergence_linbp_parameterized(H2c, W,
                                                                          method='noecho',
                                                                          X=X2)
                            eps = s * eps_max

                            F, actualIt, actualPercentageConverged = \
                                linBP_symmetric_parameterized(X2, W, H2c * eps,
                                                              method='noecho',
                                                              numMaxIt=numMaxIt,
                                                              convergencePercentage=convergencePercentage_W,
                                                              debug=2)
                        except ValueError as e:
                            print (
                            "ERROR: {} with {}: d={}, h={}".format(e, learning_method, d, h))

                        else:
                            accuracy_X = matrix_difference_classwise(X0, F, ignore_rows=ind)


                            tuple = [str(datetime.datetime.now())]
                            text = [option_vec[option_index],
                                    f,
                                    accuracy_X]
                            tuple.extend(text)
                            # print("option: {}, f: {}, actualIt: {}, accuracy: {}".format(option_vec[option_index], f, actualIt, accuracy_X))
                            save_csv_record(join(data_directory, csv_filename), tuple)



    # -- Read, aggregate, and pivot data for all options
    df1 = pd.read_csv(join(data_directory, csv_filename))
    # print("\n-- df1: (length {}):\n{}".format(len(df1.index), df1.head(15)))
    desred_decimals = 7
    df1['f'] = df1['f'].apply(lambda x: round(x,desred_decimals))                   # rounding due to different starting points
    # print("\n-- df1: (length {}):\n{}".format(len(df1.index), df1.head(15)))


    # Aggregate repetitions
    df2 = df1.groupby(['option', 'f']).agg \
        ({'accuracy': [np.mean, np.std, np.size],  # Multiple Aggregates
          })
    df2.columns = ['_'.join(col).strip() for col in df2.columns.values]  # flatten the column hierarchy
    df2.reset_index(inplace=True)  # remove the index hierarchy
    df2.rename(columns={'accuracy_size': 'count'}, inplace=True)
    # print("\n-- df2 (length {}):\n{}".format(len(df2.index), df2.head(10)))

    # Pivot table
    df3 = pd.pivot_table(df2, index=['f'], columns=['option'], values=['accuracy_mean', 'accuracy_std'] )  # Pivot
    # print("\n-- df3 (length {}):\n{}".format(len(df3.index), df3.head(30)))
    df3.columns = ['_'.join(col).strip() for col in df3.columns.values]  # flatten the column hierarchy
    df3.reset_index(inplace=True)  # remove the index hierarchy
    # df2.rename(columns={'time_size': 'count'}, inplace=True)
    # print("\n-- df3 (length {}):\n{}".format(len(df3.index), df3.head(10)))

    # Extract values
    X_f = df3['f'].values                     # plot x values
    Y=[]
    Y_std=[]
    for option in option_vec:
        Y.append(df3['accuracy_mean_{}'.format(option)].values)
        if STD_FILL:
            Y_std.append(df3['accuracy_std_{}'.format(option)].values)


    if SHORTEN_LENGTH:
        SHORT_FACTOR = 2        ## KEEP EVERY Nth ELEMENT
        X_f  = np.copy(X_f[list(range(0, len(X_f), SHORT_FACTOR)), ])

        for i in range(len(Y)):
            Y[i] = np.copy(Y[i][list(range(0, len(Y[i]), SHORT_FACTOR)), ])
            if STD_FILL:
                Y_std[i] = np.copy(Y_std[i][list(range(0, len(Y_std[i]), SHORT_FACTOR)),])






    if CREATE_PDF or SHOW_PLOT or SHOW_PDF:

        # -- Setup figure
        mpl.rc('font', **{'family': 'sans-serif', 'sans-serif': [u'Arial', u'Liberation Sans']})
        mpl.rcParams['axes.labelsize'] = 20
        mpl.rcParams['xtick.labelsize'] = 16
        mpl.rcParams['ytick.labelsize'] = 16
        mpl.rcParams['legend.fontsize'] = 14
        mpl.rcParams['grid.color'] = '777777'  # grid color
        mpl.rcParams['xtick.major.pad'] = 2  # padding of tick labels: default = 4
        mpl.rcParams['ytick.major.pad'] = 1  # padding of tick labels: default = 4
        mpl.rcParams['xtick.direction'] = 'out'  # default: 'in'
        mpl.rcParams['ytick.direction'] = 'out'  # default: 'in'
        mpl.rcParams['font.size'] = 16
        mpl.rcParams['axes.titlesize'] = 16
        mpl.rcParams['figure.figsize'] = [4, 4]
        fig = figure()
        ax = fig.add_axes([0.13, 0.17, 0.8, 0.8])


        #  -- Drawing
        if STD_FILL:
            for choice, (option, facecolor) in enumerate(zip(option_vec, facecolor_vec)):
                ax.fill_between(X_f, Y[choice] + Y_std[choice], Y[choice] - Y_std[choice],
                                facecolor=facecolor, alpha=0.2, edgecolor=None, linewidth=0)
                ax.plot(X_f, Y[choice] + Y_std[choice], linewidth=0.5, color='0.8', linestyle='solid')
                ax.plot(X_f, Y[choice] - Y_std[choice], linewidth=0.5, color='0.8', linestyle='solid')

        for choice, (option, label, color, linewidth, clip_on, linestyle, marker, markersize) in \
                enumerate(zip(option_vec, labels, facecolor_vec, linewidth_vec, clip_on_vec, linestyle_vec, marker_vec, markersize_vec)):
            P = ax.plot(X_f, Y[choice], linewidth=linewidth, color=color, linestyle=linestyle, label=label, zorder=4, marker=marker,
                    markersize=markersize, markeredgewidth=1, clip_on=clip_on, markeredgecolor='black')

        plt.xscale('log')

        # -- Title and legend
        distribution_label = '$'
        if distribution == 'uniform':
            distribution_label = ',$uniform'
        n_label = '{}k'.format(int(n / 1000))
        if n < 1000:
            n_label='{}'.format(n)
        a_label = ''
        if a != 1:
            a_label = ', a\!=\!{}'.format(a)

        titleString = r'$\!\!\!n\!=\!{}, d\!=\!{}, h\!=\!{}{}{}'.format(n_label, d, h, a_label, distribution_label)
        plt.title(titleString)

        handles, labels = ax.get_legend_handles_labels()
        legend = plt.legend(handles, labels,
                            loc='upper left',     # 'upper right'
                            handlelength=2,
                            labelspacing=0,  # distance between label entries
                            handletextpad=0.3,  # distance between label and the line representation
                            borderaxespad=0.2,  # distance between legend and the outer axes
                            borderpad=0.3,  # padding inside legend box
                            numpoints=1,  # put the marker only once
                            )
        # # legend.set_zorder(1)
        frame = legend.get_frame()
        frame.set_linewidth(0.0)
        frame.set_alpha(0.9)  # 0.8

        plt.xticks(xtick_lab, xtick_labels)
        plt.yticks(ytick_lab, ytick_lab)


        ax.yaxis.set_ticks_position('left')
        ax.xaxis.set_ticks_position('bottom')
        ax.yaxis.set_major_formatter(mpl.ticker.FormatStrFormatter('%.1f'))

        grid(b=True, which='major', axis='both', alpha=0.2, linestyle='solid', linewidth=0.5)  # linestyle='dashed', which='minor', axis='y',
        grid(b=True, which='minor', axis='both', alpha=0.2, linestyle='solid', linewidth=0.5)  # linestyle='dashed', which='minor', axis='y',
        xlabel(r'Label Sparsity $(f)$', labelpad=0)      # labelpad=0
        ylabel(r'Accuracy', labelpad=0)

        xlim(xmin, xmax)
        ylim(ymin, ymax)

        if CREATE_PDF:
            savefig(join(figure_directory, fig_filename), format='pdf',
                    dpi=None,
                    edgecolor='w',
                    orientation='portrait',
                    transparent=False,
                    bbox_inches='tight',
                    pad_inches=0.05,
                    frameon=None)
        
        if SHOW_PLOT:
            plt.show()

        if SHOW_PDF:
            showfig(join(figure_directory, fig_filename))  # shows actually created PDF