diff --git a/.gitignore b/.gitignore index 806238c..1dbc687 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,62 @@ -# ignore compilation files +# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +#Ipython Notebook +.ipynb_checkpoints diff --git a/README.md b/README.md index 7a737a9..9ff59b9 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,35 @@ -PrefPy -====== - -Rank aggregation algorithms in the computer science field of computational social choice - - -What's New -========== - -- Generalized method of moments algorithm for mixtures of Plackett-Luce models -- Implementation of EMM algorithm for mixtures of Plackett-Luce by Gormley & Murphy - - -Work In Progress -================ - -- This is an initial version of the Python package form, further structural changes will be coming -- Module naming conventions will be changed; currently the algorithm files take the initials of the names of the papers from which they originate (e.g. "gmmra" for Generalized Method of Moments for Rank Aggregation) -- Mixture Model for Plackett-Luce EMM algorithm by Gormley & Murphy is forthcoming pending verification and testing of the method -- Random utility model algorithms (verification of the implentation needs to be completed) - - -Installation -============ - -- Use of MATLAB optimization in this package requires Python 3.4 due to lack of support yet for Python 3.5 by the MATLAB Engine - -Install by running setup.py with Python 3.4 (or greater) with the command - - python3 setup.py install - -Symlink install while developing to keep changes in the code instead with the command - - python3 setup.py develop +PrefPy +====== + +Rank aggregation algorithms in the computer science field of computational social choice + + +What's New +========== + +- Experiments and tests have been factored out of the repository (now located at https://github.com/pdpiech/prefpy-experiments) +- Generalized method of moments algorithm for mixtures of Plackett-Luce models +- Implementation of EMM algorithm for mixtures of Plackett-Luce by Gormley & Murphy + + +Work In Progress +================ + +- This is an initial version of the Python package form, further structural changes will be coming +- Module naming conventions will be changed; currently the algorithm files take the initials of the names of the papers from which they originate (e.g. "gmmra" for Generalized Method of Moments for Rank Aggregation) +- Mixture Model for Plackett-Luce EMM algorithm by Gormley & Murphy is forthcoming pending verification and testing of the method +- Random utility model algorithms (verification of the implentation needs to be completed) + + +Installation +============ + +- Use of MATLAB optimization in this package requires Python 3.4 due to lack of support yet for Python 3.5 by the MATLAB Engine + +Install by running setup.py with Python 3.4 (or greater) with the command + + python3 setup.py install + +Symlink install while developing to keep changes in the code instead with the command + + python3 setup.py develop diff --git a/prefpy/__init__.py b/prefpy/__init__.py index e69de29..4d33ee8 100644 --- a/prefpy/__init__.py +++ b/prefpy/__init__.py @@ -0,0 +1,15 @@ +from . import aggregate +from . import distributions +from . import evbwie +from . import gmm_mixpl_moments +from . import gmm_mixpl_objectives +from . import gmm_mixpl +from . import gmmra +from . import mmgbtl +from . import plackettluce +from . import stats +from . import util + +__all__ = ["aggregate", "distributions", "evbwie", "gmm_mixpl_moments", + "gmm_mixpl_objectives", "gmm_mixpl", "gmmra", "mmgbtl", + "plackettluce", "stats", "util"] diff --git a/prefpy/evbwie.py b/prefpy/evbwie.py index 740b484..4449c0e 100644 --- a/prefpy/evbwie.py +++ b/prefpy/evbwie.py @@ -3,9 +3,9 @@ # A Mixture Modeling Approach by Gormley and Murphy, 2008 import numpy as np -import aggregate -import plackettluce as pl -import stats +from . import aggregate +from . import plackettluce as pl +from . import stats class EMMMixPLResult: @@ -107,11 +107,12 @@ def aggregate(self, rankings, K, epsilon, max_iters, epsilon_mm, max_iters_mm): z_h1[i][k] = (pi_h[k] * EMMMixPLAggregator.f(x[i], p_h[k])) / denom_sum # M-Step: - #for l in range(max_iters_mm): - for l in range(int(g/50) + 5): + for l in range(max_iters_mm): + #for l in range(int(g/50) + 5): for k in range(K): normconst = 0 - pi_h1[k] = np.sum(z_h1.T[k]) / len(z_h1) + if l == 0: # only need to compute pi at first MM iteration + pi_h1[k] = np.sum(z_h1.T[k]) / len(z_h1) for j in range(self.m): omega_k_j = EMMMixPLAggregator.omega(k, j, z_h1, x) # numerator denom_sum = 0 @@ -132,15 +133,18 @@ def aggregate(self, rankings, K, epsilon, max_iters, epsilon_mm, max_iters_mm): p_h1[k][j] /= normconst if (epsilon_mm != None and - np.all(np.absolute(p_h1 - p_h) < epsilon_mm) and - np.all(np.absolute(pi_h1 - pi_h) < epsilon_mm)): + np.all(np.absolute(p_h1 - p_h) < epsilon_mm)): break + p_h = np.copy(p_h1) # deep copy p for next MM iteration + # pi does not change across MM iterations, no copy needed + if (epsilon != None and np.all(np.absolute(p_h1 - p_h) < epsilon) and np.all(np.absolute(pi_h1 - pi_h) < epsilon)): break + # remember that assignments below are references only, not copies p_h = p_h1 pi_h = pi_h1 diff --git a/prefpy/evbwie1.py b/prefpy/evbwie1.py new file mode 100644 index 0000000..9227cf9 --- /dev/null +++ b/prefpy/evbwie1.py @@ -0,0 +1,184 @@ +# Implementation of algorithm (2) from +# Exploring Voting Blocs Within the Irish Electorate: +# A Mixture Modeling Approach by Gormley and Murphy, 2008 + +import numpy as np +from . import aggregate +from . import plackettluce as pl +from . import stats + + +class EMMMixPLResult: + def __init__(self, num_alts, num_votes, num_mix, true_params, epsilon, max_iters, epsilon_mm, max_iters_mm, init_guess, soln_params, runtime): + self.num_alts = num_alts + self.num_votes = num_votes + self.num_mix = num_mix + self.true_params = true_params + self.epsilon = epsilon + self.max_iters = max_iters + self.epsilon_mm = epsilon_mm + self.max_iters_mm = max_iters_mm + self.init_guess = init_guess + self.soln_params = soln_params + self.runtime = runtime + +class EMMMixPLAggregator(aggregate.RankAggregator): + + def c(x_i, j): + try: + return x_i[j] + except IndexError: + return -1 + + def f(x_i, p): + prod = 1 + for t in range(len(x_i)): + denom_sum = 0 + for s in range(t, len(p)): + denom_sum += p[EMMMixPLAggregator.c(x_i, s)] + prod *= p[EMMMixPLAggregator.c(x_i, t)] / denom_sum + return prod + + def indic(j, x_i, s): + flag = j == EMMMixPLAggregator.c(x_i, s) + if flag: + return 1 + else: + return 0 + + def delta(x_i, j, s, N): + """ delta_i_j_s """ + flag = j == EMMMixPLAggregator.c(x_i, s) + if flag and s < len(x_i): + return 1 + elif s == N: + found_equal = False + for l in range(len(x_i)): + if j == EMMMixPLAggregator.c(x_i, l): + found_equal = True + break + if not found_equal: + return 1 + return 0 + + def omega(k, j, z, x): + """ omega_k_j """ + sum_out = 0 + for i in range(len(x)): + sum_in = 0 + for t in range(len(x[i])): + sum_in += z[i][k] * EMMMixPLAggregator.indic(j, x[i], t) + sum_out += sum_in + return sum_out + + def aggregate(self, rankings, K, epsilon, tot_iters, epsilon_mm, max_iters_em): + x = rankings # shorter pseudonym for voting data + self.n = len(rankings) # number of votes + + # pre-compute the delta values + delta_i_j_s = np.empty((self.n, self.m, self.m + 1)) + for i in range(self.n): + for j in range(self.m): + for s in range(self.m + 1): + delta_i_j_s[i][j][s] = EMMMixPLAggregator.delta(x[i], j, s, self.m) + + # generate initial values for p and pi: + p_h0 = np.random.rand(K, self.m) + p_h0 /= np.sum(p_h0, axis=1, keepdims=True) + + pi_h0 = np.random.rand(K) + pi_h0 /= np.sum(pi_h0) + + p_h = np.copy(p_h0) + pi_h = np.copy(pi_h0) + + inner = tot_iters // max_iters_em + + for g in range(max_iters_em): + #for g in range(max_iters): + + p_h1 = np.empty((K, self.m)) + pi_h1 = np.empty(K) + z_h1 = np.empty((self.n, K)) + + # E-Step: + for i in range(self.n): + for k in range(K): + denom_sum = 0 + for k2 in range(K): + denom_sum += pi_h[k2] * EMMMixPLAggregator.f(x[i], p_h[k2]) + z_h1[i][k] = (pi_h[k] * EMMMixPLAggregator.f(x[i], p_h[k])) / denom_sum + + # M-Step: + test = (g + 1) * inner + (max_iters_em - g - 1) * (inner + 1) + if test < tot_iters: + inner += 1 + for l in range(inner): + #for l in range(max_iters_mm): + #for l in range(int(g/50) + 5): + for k in range(K): + normconst = 0 + if l == 0: # only need to compute pi at first MM iteration + pi_h1[k] = np.sum(z_h1.T[k]) / len(z_h1) + for j in range(self.m): + omega_k_j = EMMMixPLAggregator.omega(k, j, z_h1, x) # numerator + denom_sum = 0 + for i in range(self.n): + sum1 = 0 + for t in range(len(x[i])): + sum2 = 0 + sum3 = 0 + for s in range(t, self.m): + sum2 += p_h[k][EMMMixPLAggregator.c(x[i], s)] + for s in range(t, self.m + 1): + sum3 += delta_i_j_s[i][j][s] + sum1 += z_h1[i][k] * (sum2 ** -1) * sum3 + denom_sum += sum1 + p_h1[k][j] = omega_k_j / denom_sum + normconst += p_h1[k][j] + for j in range(self.m): + p_h1[k][j] /= normconst + + if (epsilon_mm != None and + np.all(np.absolute(p_h1 - p_h) < epsilon_mm)): + break + + p_h = np.copy(p_h1) # deep copy p for next MM iteration + # pi does not change across MM iterations, no copy needed + + if (epsilon != None and + np.all(np.absolute(p_h1 - p_h) < epsilon) and + np.all(np.absolute(pi_h1 - pi_h) < epsilon)): + break + + # remember that assignments below are references only, not copies + p_h = p_h1 + pi_h = pi_h1 + + return (pi_h1, p_h1, pi_h0, p_h0) + +def main(): + n = 100 + m = 4 + k = 2 + cand_set = np.arange(m) + #np.random.seed(0) + params, votes = pl.generate_mix2pl_dataset(n, m, useDirichlet=True) + print("Ground-Truth Parameters:\n" + str(params)) + print("EMM Algorithm:") + + emmagg = EMMMixPLAggregator(cand_set) + pi, p = emmagg.aggregate(votes, K=2, epsilon=1e-8, max_iters=1000, epsilon_mm=1e-8, max_iters_mm=10) + + sol_params = np.empty(2*m+1) + sol_params[0] = pi[0] + sol_params[1:m+1] = p[0] + sol_params[m+1:] = p[1] + + print("Ground-Truth Parameters:\n" + str(params)) + print("Final Solution:\n" + str(sol_params)) + print("\t\"1 - alpha\" = " + str(pi[1])) + print("WSSE:\n" + str(stats.mix2PL_wsse(params, sol_params, m))) + +if __name__ == "__main__": + main() diff --git a/prefpy/gen_mixpl_datasets.py b/prefpy/gen_mixpl_datasets.py deleted file mode 100644 index ada37f7..0000000 --- a/prefpy/gen_mixpl_datasets.py +++ /dev/null @@ -1,28 +0,0 @@ -import sys -import numpy as np -import plackettluce as pl - -def print_usage(argv0): - print("USAGE: python3 " + argv0 + " ") - sys.exit() - -def main(argv): - if len(argv) != 5: - print_usage(argv[0]) - m = int(argv[1]) - n = int(argv[2]) - len_d = str(len(argv[3])) - d = int(argv[3]) - filename_base = argv[4] - - print("i = ", end='') - for i in range(d): - print("\b"*len(str(i-1)) + str(i), end='') - sys.stdout.flush() - outfilename = filename_base + '_' + ("{0:0" + len_d + "d}").format(i) + ".csv" - outfile = open(outfilename, 'w') - pl._generate_mix2pl_dataset(n, m, outfile, True) - outfile.close() - -if __name__ == "__main__": - main(sys.argv) diff --git a/prefpy/gmm_mixpl.py b/prefpy/gmm_mixpl.py index 049cb85..0b88660 100644 --- a/prefpy/gmm_mixpl.py +++ b/prefpy/gmm_mixpl.py @@ -10,15 +10,16 @@ import numpy as np import scipy +import os import time import importlib from collections import namedtuple import functools -import aggregate -import plackettluce as pl -import gmm_mixpl_moments as mixpl_moments -import gmm_mixpl_objectives as mixpl_objs -import stats +from . import aggregate +from . import plackettluce as pl +from . import gmm_mixpl_moments as mixpl_moments +from . import gmm_mixpl_objectives as mixpl_objs +from . import stats _matlab_support = True try: @@ -116,6 +117,9 @@ def __init__(self, alts_list, use_matlab=False): self.Aeq_uncons = matlab.double([]) self.beq_uncons = matlab.double([]) + # set matlab directory to the folder containing this module and thus also "optimize.m" + self.matlabEng.cd(os.path.dirname(__file__), nargout=0) + def aggregate(self, rankings, algorithm, epsilon, max_iters, approx_step, opto="scipy", true_params=None): """ Description: diff --git a/prefpy/gmm_mixpl_nodata.py b/prefpy/gmm_mixpl_nodata.py deleted file mode 100644 index fe93464..0000000 --- a/prefpy/gmm_mixpl_nodata.py +++ /dev/null @@ -1,94 +0,0 @@ -import sys -import numpy as np -import scipy -import functools -import plackettluce as pl -import stats - -def calcMoments(params): # Full top3 (20 moments) - alpha = params[0] - a = params[1:5] - b = params[5:] - p1 = alpha*a+(1-alpha)*b - p21 = alpha*a[0]*a[1:]/(1-a[0])+(1-alpha)*b[0]*b[1:]/(1-b[0]) - p22 = alpha*a[1]*np.hstack((a[0],a[2:]))/(1-a[1])+(1-alpha)*b[1]*np.hstack((b[0],b[2:]))/(1-b[1]) - p23 = alpha*a[2]*np.hstack((a[:2],a[3]))/(1-a[2])+(1-alpha)*b[2]*np.hstack((b[:2],b[3]))/(1-b[2]) - p24 = alpha*a[3]*a[:3]/(1-a[3])+(1-alpha)*b[3]*b[:3]/(1-b[3]) - p3 = np.array([ - alpha*a[0]*a[2]*a[3]/(1-a[2])/(a[0]+a[1])+(1-alpha)*b[0]*b[2]*b[3]/(1-b[2])/(b[0]+b[1]), - alpha*a[0]*a[1]*a[3]/(1-a[3])/(a[1]+a[2])+(1-alpha)*b[0]*b[1]*b[3]/(1-b[3])/(b[1]+b[2]), - alpha*a[0]*a[1]*a[2]/(1-a[0])/(a[3]+a[2])+(1-alpha)*b[0]*b[1]*b[2]/(1-b[0])/(b[3]+b[2]), - alpha*a[2]*a[1]*a[3]/(1-a[1])/(a[0]+a[3])+(1-alpha)*b[2]*b[1]*b[3]/(1-b[1])/(b[0]+b[3]) - ]) - return np.concatenate((p1,p21,p22,p23,p24)) - -def mixPLobjective(params, moments): # Full top3 (20 moments) - alpha = params[0] - a = params[1:5] - b = params[5:] - p = moments - p1 = alpha*a+(1-alpha)*b-p[:4] - p21 = alpha*a[0]*a[1:]/(1-a[0])+(1-alpha)*b[0]*b[1:]/(1-b[0])-p[4:7] - p22 = alpha*a[1]*np.hstack((a[0],a[2:]))/(1-a[1])+(1-alpha)*b[1]*np.hstack((b[0],b[2:]))/(1-b[1])-p[7:10] - p23 = alpha*a[2]*np.hstack((a[:2],a[3]))/(1-a[2])+(1-alpha)*b[2]*np.hstack((b[:2],b[3]))/(1-b[2])-p[10:13] - p24 = alpha*a[3]*a[:3]/(1-a[3])+(1-alpha)*b[3]*b[:3]/(1-b[3])-p[13:16] - p3 = np.array([ - alpha*a[0]*a[2]*a[3]/(1-a[2])/(a[0]+a[1])+(1-alpha)*b[0]*b[2]*b[3]/(1-b[2])/(b[0]+b[1])-p[16], - alpha*a[0]*a[1]*a[3]/(1-a[3])/(a[1]+a[2])+(1-alpha)*b[0]*b[1]*b[3]/(1-b[3])/(b[1]+b[2])-p[17], - alpha*a[0]*a[1]*a[2]/(1-a[0])/(a[3]+a[2])+(1-alpha)*b[0]*b[1]*b[2]/(1-b[0])/(b[3]+b[2])-p[18], - alpha*a[2]*a[1]*a[3]/(1-a[1])/(a[0]+a[3])+(1-alpha)*b[2]*b[1]*b[3]/(1-b[1])/(b[0]+b[3])-p[19] - ]) - allp = np.concatenate((p1,p21,p22,p23,p24)) - return np.sum(allp**2) - -if __name__ == "__main__": - m = 4 - alpha = 0.1 - gamma1 = np.array([0.4, 0.2, 0.2, 0.2]) - gamma2 = np.array([0.1, 0.3, 0.3, 0.3]) - - # collect the parameters into one array - params = np.empty(2*m + 1) - params[0] = alpha - params[1:m+1] = gamma1 - params[m+1:] = gamma2 - - # compute 16 moment condition values - moments = calcMoments(params) - - # generate an initial guess for the optimizer - #params_t0 = np.empty(2*m + 1) - #params_t0[0] = np.random.rand() - #params_t0[1:m+1] = np.random.dirichlet(np.ones(m)) - #params_t0[m+1:] = np.random.dirichlet(np.ones(m)) - params_t0 = np.array([0.4030, 0.2347, 0.2551, 0.2551, 0.2551, 0.0593, 0.3135, 0.3135, 0.3135]) - - # optimization - bounds_pairs = [(0.0, 1.0) for i in range(2*m + 1)] - cons = ({"type": "eq", - "fun": lambda x: 1 - np.sum(x[1:m+1])}, - {"type": "eq", - "fun": lambda x: 1 - np.sum(x[m+1:])} - ) - mixPLobjective_partial = functools.partial(mixPLobjective, moments=moments) - res = scipy.optimize.minimize(mixPLobjective_partial, - params_t0, - method="SLSQP", - bounds=bounds_pairs, - constraints=cons, - tol=1e-07, - options={ - 'disp': False, - 'maxiter': 1e5, - 'ftol': 1e-07, - 'eps': 1.4901161193847656e-08 - } - ) - print("Ground-Truth Parameters:\n" + str(params)) - print("True Minimum:\n" + str(mixPLobjective(params, moments))) - if res.success: - print("Success!\nMinimum Found:\n" + str(res.fun)) - else: - print("Failed!") - print("Minimizing Value:\n" + str(res.x)) - print("MSE:\n" + str(stats.mix2PL_mse(params, res.x, m))) diff --git a/prefpy/gmmra.py b/prefpy/gmmra.py index 755b2e8..a44b738 100644 --- a/prefpy/gmmra.py +++ b/prefpy/gmmra.py @@ -3,9 +3,9 @@ # Aggregation by Azari, Chen, Parkes, & Xia import numpy as np -import aggregate -import plackettluce as pl -import util +from . import aggregate +from . import plackettluce as pl +from . import util class GMMPLAggregator(aggregate.RankAggregator): diff --git a/prefpy/mixpl_defectiveparams.py b/prefpy/mixpl_defectiveparams.py deleted file mode 100644 index 91bba0e..0000000 --- a/prefpy/mixpl_defectiveparams.py +++ /dev/null @@ -1,123 +0,0 @@ -import sys -import time -import pickle -import numpy as np -import matplotlib.pyplot as plt -import plackettluce as pl -import gmm_mixpl -import stats - - -def print_usage(argv0): - print("USAGE: python3", argv0, "<# of alternatives> <# of trials> \n" + - " Notes:\n All data files read from disk must be CSV format and have the explicit file extension '.csv'" + - " The dataset base file name given must be suffixed with an underscore, followed by padding zeros, and without the '.csv' extension (e.g. 'mixpl-dataset_000' where there are at most 999 'mixpl-dataset_.csv' files in the same directory)") - sys.exit() - -def plot_wsse_dist_data(wsse_dist_data, output_img_filename, alpha_str): - # Plot data - fig = plt.figure(num=1, figsize=(845/96, 615/96), dpi=96) - plt.title("Weighted SSE for alpha in " + alpha_str) - plt.xlabel("Absolute Distance Between PL Support Vectors") - plt.plot(wsse_dist_data.T[0], wsse_dist_data.T[1], "bs", label="GMM") - plt.savefig(output_img_filename, dpi=96) - -def main(argv): - if len(argv) != 9: - print_usage(argv[0]) - m = int(argv[1]) # number of alternatives - t = int(argv[2]) # number of trials / datasets - a_init = float(argv[3]) # initial value for alpha - a_stop = float(argv[4]) # final value for alpha - a_step = float(argv[5]) # iteration step size for alpha - data_filename_base = argv[6] # input data filename - plot_filename_base = argv[7] # output plots filenames - solns_filename = argv[8] - solns_file = open(solns_filename, 'wb') # writable binary mode - - print("Reading Datasets from Disk...") - datasets = [] - len_d = str(len(data_filename_base.split("_")[-1])) - data_filename_base = "_".join(data_filename_base.split("_")[:-1]) - for i in range(t): - infilename = data_filename_base + '_' + ("{0:0" + len_d + "d}").format(i) + ".csv" - infile = open(infilename) - datasets.append(pl.read_mix2pl_dataset(infile, numVotes=0)[0]) - - solns = [] # store all GMM Results - - alts = np.arange(m) - # initialize the aggregators for each class of algorithm - print("Initializing GMM Aggregator Class...") - gmmagg = gmm_mixpl.GMMMixPLAggregator(alts, use_matlab=True) - - print("Starting Experiments...") - results = [] - # new experiments for all alphas in range: - print("i = ", end='') - for i in range(t): - print("\b"*len(str(i-1)) + str(i), end='') - sys.stdout.flush() - params = datasets[i] - - if params[0] >= a_init and params[0] <= a_stop: - dist = np.sum(np.abs(params[1:m+1] - params[m+1:])) - if dist > 0.1: - time_val = time.perf_counter() - soln = gmmagg.aggregate(rankings=None, algorithm="top3_full", epsilon=None, max_iters=None, approx_step=None, opto="matlab_emp", true_params=params) - time_val = time.perf_counter() - time_val - wsse = stats.mix2PL_wsse(params, soln, m) - gmm_result = gmm_mixpl.GMMMixPLResult(m, 0, params, "top3_full", "matlab_emp", soln, time_val) - solns.append(gmm_result) - results.append([dist, wsse]) - else: - continue - else: - continue - - print("Number of Results to Plot:", len(results)) - if len(results) > 0: - plot_wsse_dist_data(np.asarray(results), plot_filename_base, '[' + str(a_init) + ", " + str(a_stop) + ']') - numHi = 0 - for j in range(len(results)): - if results[j][1] >= 0.02: - numHi += 1 - print("Results with WSSE >= 0.02:", numHi) - # end of new experiments - - # old experiments for each interval of alpha vals: - #alpha = a_init - #while alpha <= a_stop: - # print("alpha =", alpha) - # print("i = ", end='') - # sys.stdout.flush() - # results = [] - # numRes = 0 - # for i in range(t): - # print("\b"*len(str(i-1)) + str(i), end='') - # sys.stdout.flush() - # params = datasets[i] - # - # if params[0] >= alpha and params[0] < alpha + a_step: - # dist = np.sum(np.abs(params[1:m+1] - params[m+1:])) - # if dist > 0.1: - # soln = gmmagg.aggregate(rankings=None, algorithm="top3_full", epsilon=None, max_iters=None, approx_step=None, opto="matlab4", true_params=params) - # wsse = stats.mix2PL_wsse(params, soln, m) - # results.append([dist, wsse]) - # numRes += 1 - # else: - # continue - # else: - # continue - # if len(results) > 0: - # print("Plotting", numRes, "Results for Alpha=", alpha) - # out_filename = plot_filename_base + str(alpha) + ".png" - # plot_wsse_dist_data(np.asarray(results), out_filename, str(alpha)) - # alpha = alpha + a_step - - pickle.dump(solns, solns_file) - solns_file.close() - - -if __name__ == "__main__": - main(sys.argv) diff --git a/prefpy/mixpl_experiments.py b/prefpy/mixpl_experiments.py deleted file mode 100644 index 57439db..0000000 --- a/prefpy/mixpl_experiments.py +++ /dev/null @@ -1,247 +0,0 @@ -import sys -import time -import pickle -import numpy as np -import plackettluce as pl -import stats as stats -import gmm_mixpl -import evbwie as emm -import plot_mixpl as plot -np.seterr(all='raise') - - -def print_usage(argv0): - print("USAGE: python3", argv0, "<# of alternatives> <# of trials> <# of votes start> <# of votes end> <# votes step> <# iters for EMM>