deep-ranker / app.py
helliun's picture
Update app.py
2b1a636 verified
import gradio as gr
import pandas as pd
import re
import csv
def update_scores(winner, loser, k_factor=100):
score_difference = int(k_factor / (winner / loser))
winner += score_difference
loser -= score_difference
return winner, loser
def vote_startup_criteria(criteria_df):
if len(criteria_df) > 1:
sample = criteria_df.sample(n=2)
first_string = sample.iloc[0]["criteria"]
second_string = sample.iloc[1]["criteria"]
return f"Is '{first_string}' more important than '{second_string}'?", first_string, second_string, display_criteria_rankings(criteria_df)
else:
return "Add more criteria to start ranking!", "", "", display_criteria_rankings(criteria_df)
def vote_startup_opponents(opponents_df, criteria_df):
try:
opponents_df = opponents_df[["descriptor", "opponent"] + [f"{c}_score" for c in criteria_df["criteria"]] + ["overall_score"]]
except:
opponents_df = pd.DataFrame(columns=["descriptor", "opponent"] + [f"{c}_score" for c in criteria_df["criteria"]] + ["overall_score"])
if len(opponents_df) > 0:
if len(opponents_df) > 10:
slice_size = 4
slice = int(len(opponents_df) / slice_size)
sample = opponents_df[slice:(slice_size - 1) * slice].sample(frac=1).iloc[0]
opponent, descriptor = sample["opponent"], sample["descriptor"]
else:
sample = opponents_df.sample(frac=1).iloc[0]
opponent, descriptor = sample["opponent"], sample["descriptor"]
if len(opponents_df) > 1:
sample = opponents_df.sample(frac=1)
comparison_opponent = sample.iloc[0]
if comparison_opponent['opponent'] == opponent and comparison_opponent['descriptor'] == descriptor:
comparison_opponent = sample.iloc[1]
first_df = opponents_df[opponents_df["opponent"] == opponent][opponents_df["descriptor"] == descriptor]
first_string = first_df["opponent"].tolist()[0] + " - " + first_df["descriptor"].tolist()[0]
second_df = comparison_opponent
second_string = second_df["opponent"] + " - " + second_df["descriptor"]
criteria = criteria_df.sample(n=1)["criteria"].values[0]
return f"Which opponent better represents '{criteria}': '{descriptor} - {opponent}' or '{comparison_opponent['descriptor']} - {comparison_opponent['opponent']}'?", first_string, second_string, criteria, display_rankings(opponents_df, criteria_df)
else:
return "Add some opponents to start voting!", "", "", "", display_rankings(opponents_df, criteria_df)
def clean_string(string):
string = string.strip().replace(" ", " ").lower()
string = " ".join([x[0].upper() + x[1:] for x in string.split()])
return string
def add_and_compare(descriptor, opponent, opponents_df, criteria_df):
try:
opponents_df = opponents_df[["descriptor", "opponent"] + [f"{c}_score" for c in criteria_df["criteria"]] + ["overall_score"]]
except:
opponents_df = pd.DataFrame(columns=["descriptor", "opponent"] + [f"{c}_score" for c in criteria_df["criteria"]] + ["overall_score"])
if descriptor != "" and opponent != "":
descriptor = clean_string(descriptor)
opponent = clean_string(opponent)
new_opponent = pd.DataFrame({'descriptor': [descriptor], 'opponent': [opponent]})
for c in criteria_df["criteria"]:
new_opponent[f"{c}_score"] = 1000
new_opponent["overall_score"] = 1000
opponents_df = pd.concat([opponents_df, new_opponent], ignore_index=True)
opponents_df.to_csv("opponents_df.csv")
opponents_df = opponents_df[["descriptor", "opponent"] + [f"{c}_score" for c in criteria_df["criteria"]] + ["overall_score"]]
return "", "", display_rankings(opponents_df, criteria_df)
def update_ratings_pos(first_string, second_string, criteria, opponents_df, criteria_df):
try:
opponents_df = opponents_df[["descriptor", "opponent"] + [f"{c}_score" for c in criteria_df["criteria"]] + ["overall_score"]]
except:
opponents_df = pd.DataFrame(columns=["descriptor", "opponent"] + [f"{c}_score" for c in criteria_df["criteria"]] + ["overall_score"])
if len(opponents_df) == 0:
return "Add some opponents to start voting!", "", "", "", display_rankings(opponents_df, criteria_df)
if first_string != "":
opponents_df["combined"] = opponents_df["opponent"] + " - " + opponents_df["descriptor"]
loser = opponents_df[opponents_df["combined"] == second_string]
winner = opponents_df[opponents_df["combined"] == first_string]
winner_score, loser_score = update_scores(winner[f"{criteria}_score"].values[0], loser[f"{criteria}_score"].values[0])
opponents_df.at[winner.index[0], f"{criteria}_score"] = winner_score
opponents_df.at[loser.index[0], f"{criteria}_score"] = loser_score
opponents_df = calculate_overall_scores(opponents_df, criteria_df)
opponents_df.to_csv("opponents_df.csv")
return vote_startup_opponents(opponents_df, criteria_df)
def update_ratings_neg(first_string, second_string, criteria, opponents_df, criteria_df):
try:
opponents_df = opponents_df[["descriptor", "opponent"] + [f"{c}_score" for c in criteria_df["criteria"]] + ["overall_score"]]
except:
opponents_df = pd.DataFrame(columns=["descriptor", "opponent"] + [f"{c}_score" for c in criteria_df["criteria"]] + ["overall_score"])
if len(opponents_df) == 0:
return "Add some opponents to start voting!", "", "", "", display_rankings(opponents_df, criteria_df)
if first_string != "":
opponents_df["combined"] = opponents_df["opponent"] + " - " + opponents_df["descriptor"]
loser = opponents_df[opponents_df["combined"] == first_string]
winner = opponents_df[opponents_df["combined"] == second_string]
winner_score, loser_score = update_scores(winner[f"{criteria}_score"].values[0], loser[f"{criteria}_score"].values[0])
opponents_df.at[winner.index[0], f"{criteria}_score"] = winner_score
opponents_df.at[loser.index[0], f"{criteria}_score"] = loser_score
opponents_df = calculate_overall_scores(opponents_df, criteria_df)
opponents_df.to_csv("opponents_df.csv")
return vote_startup_opponents(opponents_df, criteria_df)
def display_rankings(opponents_df, criteria_df):
opponents_df = opponents_df.sort_values(by='overall_score', ascending=False)
opponents_df = opponents_df[["descriptor", "opponent"] + [f"{c}_score" for c in criteria_df["criteria"]] + ["overall_score"]]
opponents_df.to_csv("opponents_df.csv")
return opponents_df
def export_csv(opponents_df):
save_df = opponents_df
save_df.to_csv("opponents_df.csv")
return "opponents_df.csv"
def import_csv(file, opponents_df, criteria_df):
if file is not None:
new_df = pd.read_csv(file)
try:
opponents_df = opponents_df[["descriptor", "opponent"] + [f"{c}_score" for c in criteria_df["criteria"]] + ["overall_score"]]
except:
opponents_df = pd.DataFrame(columns=["descriptor", "opponent"] + [f"{c}_score" for c in criteria_df["criteria"]] + ["overall_score"])
new_df = new_df[["descriptor", "opponent"] + [f"{c}_score" for c in criteria_df["criteria"]] + ["overall_score"]]
opponents_df = pd.concat([opponents_df, new_df])
opponents_df = opponents_df.drop_duplicates(subset=['descriptor', 'opponent'])
return opponents_df
def remove_opponent(descriptor, opponent, opponents_df):
descriptor = clean_string(descriptor)
opponent = clean_string(opponent)
opponents_df = opponents_df[~((opponents_df["descriptor"] == descriptor) & (opponents_df["opponent"] == opponent))]
return opponents_df[["descriptor", "opponent"] + [f"{c}_score" for c in criteria_df["criteria"]] + ["overall_score"]]
def reset_rankings(opponents_df, criteria_df):
for c in criteria_df["criteria"]:
opponents_df[f"{c}_score"] = 1000
opponents_df["overall_score"] = 1000
opponents_df = opponents_df[["descriptor", "opponent"] + [f"{c}_score" for c in criteria_df["criteria"]] + ["overall_score"]]
return display_rankings(opponents_df, criteria_df)
def clear_rankings(opponents_df, criteria_df):
opponents_df = pd.DataFrame(columns=["descriptor", "opponent"] + [f"{c}_score" for c in criteria_df["criteria"]] + ["overall_score"])
return display_rankings(opponents_df, criteria_df)
def add_criteria(criteria, criteria_df):
if criteria != "":
criteria = clean_string(criteria)
new_criteria = pd.DataFrame({'criteria': [criteria], 'score': [1000]})
criteria_df = pd.concat([criteria_df, new_criteria], ignore_index=True)
criteria_df.to_csv("criteria_df.csv")
criteria_df = criteria_df[["score", "criteria"]]
criteria_df = criteria_df.dropna()
return "", display_criteria_rankings(criteria_df)
def remove_criteria(criteria, criteria_df):
criteria = clean_string(criteria)
criteria_df = criteria_df[criteria_df["criteria"] != criteria]
return display_criteria_rankings(criteria_df)
def update_criteria_ratings_pos(first_string, second_string, criteria_df):
if len(criteria_df) == 0:
return "Add some criteria to start ranking!", "", "", display_criteria_rankings(criteria_df)
if first_string != "":
loser = criteria_df[criteria_df["criteria"] == second_string]
winner = criteria_df[criteria_df["criteria"] == first_string]
winner_score, loser_score = update_scores(winner['score'].values[0], loser['score'].values[0])
criteria_df.at[winner.index[0], 'score'] = winner_score
criteria_df.at[loser.index[0], 'score'] = loser_score
criteria_df = criteria_df.sort_values(by='score', ascending=False)
criteria_df.to_csv("criteria_df.csv")
return vote_startup_criteria(criteria_df)
def update_criteria_ratings_neg(first_string, second_string, criteria_df):
if len(criteria_df) == 0:
return "Add some criteria to start ranking!", "", "", display_criteria_rankings(criteria_df)
if first_string != "":
loser = criteria_df[criteria_df["criteria"] == first_string]
winner = criteria_df[criteria_df["criteria"] == second_string]
winner_score, loser_score = update_scores(winner['score'].values[0], loser['score'].values[0])
criteria_df.at[winner.index[0], 'score'] = winner_score
criteria_df.at[loser.index[0], 'score'] = loser_score
criteria_df = criteria_df.sort_values(by='score', ascending=False)
criteria_df.to_csv("criteria_df.csv")
return vote_startup_criteria(criteria_df)
def display_criteria_rankings(criteria_df):
criteria_df = criteria_df.sort_values(by='score', ascending=False)
criteria_df = criteria_df[["score", "criteria"]]
criteria_df.to_csv("criteria_df.csv")
return criteria_df
def calculate_overall_scores(opponents_df, criteria_df):
criteria_scores = criteria_df.set_index("criteria")["score"]
new_scores = []
for _, row in opponents_df.iterrows():
overall_score = 0
total_weight = 0
for c in criteria_df["criteria"]:
weight = criteria_scores[c]
score = row[f"{c}_score"]
overall_score += weight * score
total_weight += weight
# opponents_df.at[row.name, "overall_score"] = overall_score / total_weight
score = overall_score / total_weight
new_scores.append(score)
opponents_df["overall_score"] = new_scores
return opponents_df
theme = gr.themes.Soft(primary_hue="red", secondary_hue="blue")
with gr.Blocks(theme=theme) as app:
gr.Markdown(
"""## Preference-based Elo Ranker
This tool helps you create **accurate rankings** of things based on your personal preferences.
It does this by asking you questions comparing a random pair of your inputs, and then using your
answers to calculate Elo scores for ranking.
"""
)
with gr.Tab("Criteria Ranking"):
gr.Markdown(
"""### Rank Criteria
Add and rank the criteria that will be used to evaluate the opponents.
"""
)
with gr.Row():
criteria_input = gr.Textbox(label="Criteria")
add_criteria_button = gr.Button("Add Criteria")
with gr.Row():
remove_criteria_input = gr.Textbox(label="Criteria")
remove_criteria_button = gr.Button("Remove Criteria")
criteria_df = pd.DataFrame(columns=['score', 'criteria'])
criteria_rankings = gr.DataFrame(value=criteria_df, interactive=False, headers=["Score", "Criteria"])
with gr.Row():
criteria_compare_output = gr.Textbox("Add some criteria to start ranking!", label="Comparison", interactive=False)
with gr.Row():
criteria_yes_button = gr.Button("Yes", variant="secondary")
criteria_no_button = gr.Button("No", variant="primary")
with gr.Row():
with gr.Column():
criteria_compare_index_1 = gr.Textbox(label="", interactive=False, visible=False)
with gr.Column():
criteria_compare_index_2 = gr.Textbox(label="", interactive=False, visible=False)
criteria_new_vote = gr.Button("New Vote")
add_criteria_button.click(add_criteria, inputs=[criteria_input, criteria_rankings], outputs=[criteria_input, criteria_rankings])
remove_criteria_button.click(remove_criteria, inputs=[remove_criteria_input, criteria_rankings], outputs=criteria_rankings)
criteria_yes_button.click(update_criteria_ratings_pos, inputs=[criteria_compare_index_1, criteria_compare_index_2, criteria_rankings], outputs=[criteria_compare_output, criteria_compare_index_1, criteria_compare_index_2, criteria_rankings])
criteria_no_button.click(update_criteria_ratings_neg, inputs=[criteria_compare_index_1, criteria_compare_index_2, criteria_rankings], outputs=[criteria_compare_output, criteria_compare_index_1, criteria_compare_index_2, criteria_rankings])
criteria_new_vote.click(vote_startup_criteria, inputs=[criteria_rankings], outputs=[criteria_compare_output, criteria_compare_index_1, criteria_compare_index_2, criteria_rankings])
with gr.Tab("Opponent Ranking"):
with gr.Row():
previews_df = pd.DataFrame(columns=["descriptor", "opponent"] + [f"{c}_score" for c in criteria_df["criteria"]] + ["overall_score"])
previews = gr.DataFrame(value=previews_df, interactive=False, visible=False)
with gr.Column():
gr.Markdown(
"""### Vote to Rank
"""
)
with gr.Row():
compare_output = gr.Textbox("Add some options to start voting!", label="Comparison", interactive=False)
with gr.Row():
yes_button = gr.Button("1", variant="secondary")
no_button = gr.Button("2", variant="primary")
with gr.Row():
criteria_output = gr.Textbox(label="Criteria", interactive=False)
new_vote = gr.Button("New Vote")
with gr.Row():
with gr.Column():
compare_index_1 = gr.Textbox(label="", interactive=False, visible=False)
with gr.Column():
compare_index_2 = gr.Textbox(label="", interactive=False, visible=False)
with gr.Column():
gr.Markdown(
"""### Rankings
"""
)
opponents_df = pd.DataFrame(columns=["descriptor", "opponent"] + [f"{c}_score" for c in criteria_df["criteria"]] + ["overall_score"])
rankings = gr.DataFrame(value=opponents_df, interactive=False, headers=["Descriptor", "Opponent"] + [f"{c} Score" for c in criteria_df["criteria"]] + ["Overall Score"])
gr.Markdown(
"""### Add Opponents
"""
)
with gr.Row():
descriptor_input = gr.Textbox(label="Descriptor")
opponent_input = gr.Textbox(label="Opponent")
add_button = gr.Button("Add Opponent")
add_button.click(add_and_compare, inputs=[descriptor_input, opponent_input, rankings, criteria_rankings], outputs=[descriptor_input, opponent_input, rankings])
gr.Markdown(
"""### Remove Opponents
"""
)
with gr.Row():
remove_descriptor_input = gr.Textbox(label="Descriptor")
remove_opponent_input = gr.Textbox(label="Opponent")
remove_button = gr.Button("Remove Opponent")
remove_button.click(remove_opponent, inputs=[remove_descriptor_input, remove_opponent_input, rankings], outputs=rankings)
gr.Markdown(
"""### Import and Export Rankings
"""
)
with gr.Row():
import_button = gr.File(label="Import CSV", file_count="single")
import_button.change(fn=import_csv, inputs=[import_button, rankings, criteria_rankings], outputs=[rankings])
with gr.Column():
export_link = gr.File(label="Download CSV", file_count="single")
export_button = gr.Button("Export as CSV")
export_button.click(fn=export_csv, inputs=[rankings], outputs=export_link)
gr.Markdown("### Reset Data")
with gr.Row():
reset_button = gr.Button("Reset Scores")
reset_button.click(reset_rankings, inputs=[rankings, criteria_rankings], outputs=rankings)
clear_button = gr.Button("Clear Table", variant="primary")
clear_button.click(clear_rankings, inputs=[rankings, criteria_rankings], outputs=rankings)
yes_button.click(update_ratings_pos, inputs=[compare_index_1, compare_index_2, criteria_output, rankings, criteria_rankings], outputs=[compare_output, compare_index_1, compare_index_2, criteria_output, rankings])
no_button.click(update_ratings_neg, inputs=[compare_index_1, compare_index_2, criteria_output, rankings, criteria_rankings], outputs=[compare_output, compare_index_1, compare_index_2, criteria_output, rankings])
new_vote.click(vote_startup_opponents, inputs=[rankings, criteria_rankings], outputs=[compare_output, compare_index_1, compare_index_2, criteria_output, rankings])
app.launch(share=False)