def read_profile(inputfile): inf = open(inputfile, 'r') cmap, rmaps, rmapscounts, nvoters = prefpy_io.read_election_file(inf) inf.close() profile = Profile(cmap, preferences=[]) Profile.importPreflibFile(profile, inputfile) # Currently, we expect the profile to contain complete ordering over candidates. Ties are allowed however. elecType = profile.getElecType() if elecType != "soc" and elecType != "soi" and elecType != "csv": print("ERROR: unsupported election type") exit() return profile
i += 1 missed_winners_file.close() os.chdir(rpconfig.path) output_data_file = open('missed_winners_data.dat', 'w') # need to update for anything other than m10 I = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] for thing in missed_winners: inputfile = thing[0] profile_missed_winners = thing[1:] inf = open(inputfile, 'r') cmap, rmaps, rmapscounts, nvoters = prefpy_io.read_election_file(inf) inf.close() profile = Profile(cmap, preferences=[]) Profile.importPreflibFile(profile, inputfile) winners, stats, data = MechanismRankedPairs().outer_loop_lp( profile, profile_missed_winners) print(inputfile, winners) # output to file # outputs in form G E K a[0] a[1] output_data_file.write(inputfile + '\n') for w in data.keys(): data_points = data[w]
def RP_SL_v2(self, model, model_id, parameters_file): print("***********************************************") print("Starting Supervised Learning", model_id) parameters_file.write("SL Loss Function\t" + str(self.loss_fn) + '\n') parameters_file.flush() data_file = open('missed_winners_data.dat', 'r') os.chdir(rpconfig.path) self.I = [i for i in range(int(params.m))] # dict of tuples (profile, G, E, K) -> list of actions (u,v) self.data_state_to_actions = {} current_profile = None self.profile_to_adjacency0 = {} self.profile_to_E0 = {} self.profile_to_plurality = {} self.profile_to_borda = {} self.profile_to_copeland = {} self.profile_to_maximin = {} self.profile_to_max_edge_weight = {} self.profile_to_vectorized_wmg = {} self.profile_to_posmat = {} n = 0 n2 = 0 # read data for line in data_file: line = line.strip('\n') line = line.split('\t') if len(line) == 1: current_profile = line[0] # read profile inf = open(current_profile, 'r') cmap, rmaps, rmapscounts, nvoters = prefpy_io.read_election_file( inf) inf.close() profile = Profile(cmap, preferences=[]) Profile.importPreflibFile(profile, current_profile) wmg = profile.getWmg() profile_matrix = [] for p in profile.preferences: profile_matrix.append(p.getOrderVector()) profile_matrix = np.asmatrix(profile_matrix) E = nx.DiGraph() E.add_nodes_from(self.I) self.profile_to_max_edge_weight[current_profile] = 0 for cand1, cand2 in itertools.permutations(wmg.keys(), 2): if wmg[cand1][cand2] > 0: E.add_edge(cand1, cand2, weight=wmg[cand1][cand2]) self.profile_to_max_edge_weight[current_profile] = max( self.profile_to_max_edge_weight[current_profile], wmg[cand1][cand2]) self.profile_to_E0[current_profile] = E.copy() adjacency_0 = nx.adjacency_matrix(E, nodelist=self.I).todense() self.profile_to_adjacency0[current_profile] = adjacency_0.copy( ) # compute voting rules scores self.profile_to_plurality[ current_profile] = RP_utils.plurality_score(profile_matrix) self.profile_to_borda[current_profile] = RP_utils.borda_score( profile_matrix) self.profile_to_copeland[ current_profile] = RP_utils.copeland_score(wmg) self.profile_to_maximin[ current_profile] = RP_utils.maximin_score(wmg) self.profile_to_vectorized_wmg[ current_profile] = RP_utils.vectorize_wmg(wmg) self.profile_to_posmat[ current_profile] = RP_utils.profile2posmat(profile_matrix) if len(line) == 5: # each line in form G E K a[0] a[1] G_str = line[0] E_str = line[1] K_str = line[2] a = (int(line[3]), int(line[4])) data_key = (current_profile, G_str, E_str, K_str) if data_key in self.data_state_to_actions: self.data_state_to_actions[data_key].append(a) else: self.data_state_to_actions[data_key] = [a] n2 += 1 n += 1 print("total data", n) print("unique states", n2) print("have same state", n - n2) data = list(self.data_state_to_actions.keys()) random.shuffle(data) test_data = data[-params.SL_num_test_data:] # Open files for output loss_output_file = open( rpconfig.results_path + str(model_id) + '_SL_loss.txt', 'w+') test_output_file = open( rpconfig.results_path + str(model_id) + '_SL_test_results.txt', 'w+') loss_output_file.write("Epoch" + '\t' + "Avg Loss Per State" + '\t' + "Percent Correct" + '\n') test_output_file.write("Epoch" + '\t' + "Percent Correct" + '\t' + "Time to Test" + '\n') loss_output_file.flush() test_output_file.flush() # order the edges for model ease self.edges_ordered = {} index = 0 for i in range(len(self.I)): for j in range(len(self.I)): if i != j: self.edges_ordered[(i, j)] = index index += 1 for epoch in range(params.SL_num_epochs): running_loss = 0 num_correct = 0 # Test model if (epoch % params.SL_test_every == 0 and params.SL_test_at_start): test_start = time.perf_counter() test_results = self.test(test_data, model) time_to_test = time.perf_counter() - test_start print("Test", epoch, test_results / len(test_data), time_to_test) RP_utils.save_model(model, "SL_" + str(epoch), model_id) test_output_file.write( str(epoch) + '\t' + str(test_results / len(test_data)) + '\t' + str(time_to_test) + '\n') test_output_file.flush() print("--------------------------") print("Starting epoch", epoch) epoch_start = time.perf_counter() for i in range(params.SL_num_training_data): d = data[i] profile = d[0] E_0 = self.profile_to_E0[profile] G = nx.DiGraph() G.add_nodes_from(self.I) G.add_edges_from(RP_utils.string2edges(d[1], self.I)) E = nx.DiGraph() E.add_nodes_from(self.I) E_edges = RP_utils.string2edges(d[2], self.I) for e in E_edges: E.add_edge(e[0], e[1], weight=E_0[e[0]][e[1]]['weight']) K = RP_utils.string2K(d[3]) actions_optimal = self.data_state_to_actions[d] # get legal actions at state legal_actions = self.get_legal_actions(G, E) # sanity check for a in actions_optimal: assert a not in G.edges() assert a in E.edges() assert a in legal_actions assert len(legal_actions) > 0 # find max q value action action_Q_vals = model( self.state_features(G, K, legal_actions, profile)) max_action = None max_action_val = float("-inf") for e in legal_actions: action_Q_val = action_Q_vals[self.edges_ordered[e]] if action_Q_val > max_action_val: max_action = e max_action_val = action_Q_val if max_action in set(actions_optimal): # selecting correctly # but still want to train for q vals num_correct += 1 # update action q vals (correct actions to 1, incorrect actions to -1) y = [0] * params.D_out for e in actions_optimal: y[self.edges_ordered[e]] = 1 for e in legal_actions: if e not in set(actions_optimal): y[self.edges_ordered[e]] = -1 loss = self.loss_fn(action_Q_vals, Variable(torch.FloatTensor(y))) model.zero_grad() loss.backward() with torch.no_grad(): for p in model.parameters(): p -= params.SL_optimal_action_learning_rate * p.grad running_loss += loss.item() # compute avg loss per action running_loss = running_loss / params.SL_num_training_data time_for_epoch = time.perf_counter() - epoch_start loss_output_file.write( str(epoch) + '\t' + str(running_loss) + '\t' + str(num_correct / params.SL_num_training_data) + '\t' + str(time_for_epoch) + '\n') loss_output_file.flush() print("Finished epoch", epoch) print("avg loss", running_loss) print("percent correct", num_correct / params.SL_num_training_data) print("time for epoch", time_for_epoch) # Final test test_start = time.perf_counter() test_results = self.test(test_data, model) time_to_test = time.perf_counter() - test_start print("Test final", test_results / len(test_data), time_to_test) RP_utils.save_model(model, "SL_" + str(params.SL_num_epochs), model_id) test_output_file.write( str(params.SL_num_epochs) + '\t' + str(test_results / len(test_data)) + '\t' + str(time_to_test) + '\n') test_output_file.flush() loss_output_file.close() test_output_file.close()