def plot_synergies(): synergies = np.loadtxt('pretrained/synergies_all.csv') for i in range(114): synergies[i, i] = 0.5 hero_dict = get_hero_dict() x_labels = [] for i in range(114): if i != 23: x_labels.append(hero_dict[i + 1]) synergies = np.delete(synergies, [23], 0) synergies = np.delete(synergies, [23], 1) trace = go.Heatmap(z=synergies, x=x_labels, y=x_labels, colorscale='Viridis') layout = go.Layout(title='Hero synergies', width=1000, height=1000, xaxis=dict(ticks='', nticks=114, tickfont=dict(size=8, color='black')), yaxis=dict(ticks='', nticks=114, tickfont=dict(size=8, color='black'))) data = [trace] fig = go.Figure(data=data, layout=layout) py.iplot(fig, filename='heatmap_synergies')
def pick_statistics(dataset_df, mmr_info): x_data, y_data = dataset_df wins = np.zeros(114) games = np.zeros(114) pick_rate = np.zeros(114) for idx, game in enumerate(x_data): for i in range(228): if game[i] == 1: games[i % 114] += 1 if y_data[idx] == 1: if i < 114: wins[i] += 1 else: if i >= 114: wins[i - 114] += 1 pick_rate = games / np.sum(games) pick_rate_dict = dict() hero_dict = get_hero_dict() for i in range(114): if i != 23: pick_rate_dict[hero_dict[i + 1]] = pick_rate[i] sorted_pickrates = sorted(pick_rate_dict.items(), key=operator.itemgetter(1)) x_plot_data = [x[0] for x in sorted_pickrates] y_plot_data = [x[1] for x in sorted_pickrates] title = 'Hero pick rates at ' + mmr_info + ' MMR' data = [go.Bar(y=x_plot_data, x=y_plot_data * 100, orientation='h')] layout = go.Layout(title=title, width=1000, height=1400, yaxis=dict(title='hero', ticks='', nticks=114, tickfont=dict(size=8, color='black')), xaxis=dict(title='pick rate', nticks=30, tickfont=dict(size=10, color='black'))) fig = go.Figure(data=data, layout=layout) py.iplot(fig, filename='hero_pickrates_' + mmr_info)
def plot_hero_map(csv_path, batch_size=128, embedding_size=25, window_size=2, neg_samples=64, num_steps=30001, low_mmr=0, high_mmr=9000): """ Creates a 2D plot of the heroes based on their similarity obtained with word2vec. The result is uploaded to plotly. Args: csv_path: path to the training dataset csv batch_size: size of the batch to be used in training embedding_size: number of dimensions when creating word embeddings window_size: word2vec window size hyperparameter neg_samples: word2vec negative samples hyperparameter num_steps: number of steps to train for at (at least 10k should be fine) low_mmr: lower bound of the MMRs filtered for plotting high_mmr: upper bound of the MMRs filtered for plotting """ patch = get_last_patch() heroes_dict = get_hero_dict() dataset = pd.read_csv(csv_path) # filter the games by MMR and transform the dataset to a numpy array dataset = dataset[(dataset.avg_mmr > low_mmr) & (dataset.avg_mmr < high_mmr)].values vocabulary_size = patch['heroes_released'] + 1 words = [] # create corpus by separating each team and adding padding for match in dataset: radiant_list = match[2].split(',') dire_list = match[3].split(',') words.extend(radiant_list) words.append('PAD') words.append('PAD') words.extend(dire_list) words.append('PAD') words.append('PAD') # create vocabulary using the corpus data, count, dictionary, reverse_dictionary = _build_vocabulary(words, vocabulary_size) logger.info('Most common heroes (+UNK): %s', count[:5]) logger.info('Sample data: %s', data[:10]) # free unused memory del words final_embeddings = _train_word2vec(data, batch_size, vocabulary_size, embedding_size, neg_samples, window_size, num_steps, reverse_dictionary, heroes_dict) _plot_similarities(final_embeddings, heroes_dict, reverse_dictionary)
def _query_missing(model, scaler, radiant_heroes, dire_heroes, synergies, counters, similarities, heroes_released): """ Query the best missing hero that can be picked given 4 heroes in one team and 5 heroes in the other. Args: model: estimator that has fitted the data scaler: the scaler used for fitting the data radiant_heroes: list of hero IDs from radiant team dire_heroes: list of hero IDs from dire team synergies: matrix defining the synergy scores between heroes counters: matrix defining the counter scores between heroes similarities: matrix defining similarities between heroes heroes_released: number of heroes released in the queried patch Returns: list of variable length containing hero suggestions """ all_heroes = radiant_heroes + dire_heroes base_similarity_radiant = 0 base_similarity_dire = 0 radiant = len(radiant_heroes) == 4 for i in range(4): for j in range(4): if i > j: base_similarity_radiant += similarities[radiant_heroes[i], radiant_heroes[j]] base_similarity_dire += similarities[dire_heroes[i], dire_heroes[j]] query_base = np.zeros((heroes_released, 2 * heroes_released + 3)) for i in range(heroes_released): if radiant: radiant_heroes.append(i + 1) else: dire_heroes.append(i + 1) for j in range(5): query_base[i][radiant_heroes[j] - 1] = 1 query_base[i][dire_heroes[j] - 1 + heroes_released] = 1 query_base[i][-3:] = augment_with_advantages(synergies, counters, radiant_heroes, dire_heroes) if radiant: del radiant_heroes[-1] else: del dire_heroes[-1] if radiant: probabilities = model.predict_proba(scaler.transform(query_base))[:, 1] else: probabilities = model.predict_proba(scaler.transform(query_base))[:, 0] heroes_dict = get_hero_dict() similarities_list = [] results_dict = {} for i, prob in enumerate(probabilities): if i + 1 not in all_heroes and i != 23: if radiant: similarity_new = base_similarity_radiant for j in range(4): similarity_new += similarities[i + 1][radiant_heroes[j]] similarities_list.append(similarity_new) else: similarity_new = base_similarity_dire for j in range(4): similarity_new += similarities[i + 1][dire_heroes[j]] similarities_list.append(similarity_new) results_dict[heroes_dict[i + 1]] = (prob, similarity_new) results_list = sorted(results_dict.items(), key=operator.itemgetter(1), reverse=True) similarities_list.sort() max_similarity_allowed = similarities_list[len(similarities_list) / 4] filtered_list = [ x for x in results_list if x[1][1] < max_similarity_allowed ] return filtered_list
def query(mmr, radiant_heroes, dire_heroes, synergies, counters, similarities): if mmr < 0 or mmr > 10000: logger.error("MMR should be a number between 0 and 10000") return if mmr < 2000: model_dict = joblib.load(os.path.join("pretrained", "2000-.pkl")) logger.info("Using 0-2000 MMR model") elif mmr > 5000: model_dict = joblib.load(os.path.join("pretrained", "5000+.pkl")) logger.info("Using 5000-10000 MMR model") else: file_list = [ int(valid_file[:4]) for valid_file in listdir('pretrained') if '.pkl' in valid_file ] file_list.sort() min_distance = 10000 final_mmr = -1000 for model_mmr in file_list: if abs(mmr - model_mmr) < min_distance: min_distance = abs(mmr - model_mmr) final_mmr = model_mmr print "Using closest model available: %d MMR model" % final_mmr model_dict = joblib.load( os.path.join("pretrained", str(final_mmr) + ".pkl")) scaler = model_dict['scaler'] model = model_dict['model'] if len(radiant_heroes) + len(dire_heroes) == 10: features = np.zeros(231) for i in range(5): features[radiant_heroes[i] - 1] = 1 features[dire_heroes[i] - 1 + 114] = 1 extra_data = augment_with_advantages(synergies, counters, radiant_heroes, dire_heroes) features[-3:] = extra_data features_reshaped = features.reshape(1, -1) features_final = scaler.transform(features_reshaped) probability = model.predict_proba(features_final)[:, 1] * 100 logger.info("Radiant chance to win: %.3f%%", probability) logger.info("Dire chance to win: %.3f%%", (100 - probability)) else: all_heroes = radiant_heroes + dire_heroes base_similarity_radiant = 0 base_similarity_dire = 0 radiant = len(radiant_heroes) == 4 for i in range(4): for j in range(4): if i > j: base_similarity_radiant += similarities[radiant_heroes[i], radiant_heroes[j]] base_similarity_dire += similarities[dire_heroes[i], dire_heroes[j]] query_base = np.zeros((114, 231)) for i in range(114): if radiant: radiant_heroes.append(i + 1) else: dire_heroes.append(i + 1) for j in range(5): query_base[i][radiant_heroes[j] - 1] = 1 query_base[i][dire_heroes[j] - 1 + 114] = 1 query_base[i][-3:] = augment_with_advantages( synergies, counters, radiant_heroes, dire_heroes) if radiant: del radiant_heroes[-1] else: del dire_heroes[-1] np.set_printoptions(suppress=True) if radiant: probs = model.predict_proba(scaler.transform(query_base))[:, 1] else: probs = model.predict_proba(scaler.transform(query_base))[:, 0] heroes_dict = get_hero_dict() similarities_list = [] results_dict = {} for i, prob in enumerate(probs): if i + 1 not in all_heroes and i != 23: if radiant: similarity_new = base_similarity_radiant for j in range(4): similarity_new += similarities[i + 1][radiant_heroes[j]] similarities_list.append(similarity_new) else: similarity_new = base_similarity_dire for j in range(4): similarity_new += similarities[i + 1][dire_heroes[j]] similarities_list.append(similarity_new) results_dict[heroes_dict[i + 1]] = (prob, similarity_new) results_list = sorted(results_dict.items(), key=operator.itemgetter(1), reverse=True) similarities_list.sort() max_similarity_allowed = similarities_list[len(similarities_list) / 4] new_list = [ x for x in results_list if x[1][1] < max_similarity_allowed ] for element in new_list: print element