def eval_most_similar(
    dataset,
    vectors_path,
    senses=None,
    exclude_senses=EVAL_EXCLUDE_SENSES,
    n_freq=100_000,
    n_similar=10,
    batch_size=5,
    eval_whole=False,
    eval_only=False,
    show_scores=False,
):
    """
    Evaluate a vectors model by looking at the most similar entries it returns
    for a random phrase and unselecting the mistakes.
    """
    log("RECIPE: Starting recipe sense2vec.eval-most-similar", locals())
    random.seed(0)
    s2v = Sense2Vec().from_disk(vectors_path)
    log("RECIPE: Loaded sense2vec vectors", vectors_path)
    seen = set()
    DB = connect()
    if dataset in DB:
        examples = DB.get_dataset(dataset)
        seen.update([eg["text"] for eg in examples if eg["answer"] == "accept"])
        log(f"RECIPE: Skipping {len(seen)} terms already in dataset")

    def get_html(key, score=None, large=False):
        word, sense = s2v.split_key(key)
        html_word = f"<span style='font-size: {30 if large else 20}px'>{word}</span>"
        html_sense = f"<strong style='opacity: 0.75; font-size: 14px; padding-left: 10px'>{sense}</strong>"
        html = f"{html_word} {html_sense}"
        if show_scores and score is not None:
            html += f" <span style='opacity: 0.75; font-size: 12px; padding-left: 10px'>{score:.4}</span>"
        return html

    def get_stream():
        keys = [key for key, _ in s2v.frequencies[:n_freq] if key not in seen]
        while len(keys):
            key = random.choice(keys)
            keys.remove(key)
            word, sense = s2v.split_key(key)
            if sense in exclude_senses or (senses is not None and sense not in senses):
                continue
            most_similar = s2v.most_similar(key, n=n_similar)
            options = [{"id": k, "html": get_html(k, s)} for k, s in most_similar]
            task_hash = murmurhash.hash(key)
            task = {
                "html": get_html(key, large=True),
                "text": key,
                "options": options,
                "accept": [key for key, _ in most_similar],  # pre-select all
                TASK_HASH_ATTR: task_hash,
                INPUT_HASH_ATTR: task_hash,
            }
            yield task

    def eval_dataset(set_id):
        DB = connect()
        data = DB.get_dataset(set_id)
        accepted = [eg for eg in data if eg["answer"] == "accept" and eg.get("accept")]
        rejected = [eg for eg in data if eg["answer"] == "reject"]
        ignored = [eg for eg in data if eg["answer"] == "ignore"]
        if not accepted and not rejected:
            msg.warn("No annotations collected", exits=1)
        total_count = 0
        agree_count = 0
        for eg in accepted:
            total_count += len(eg.get("options", []))
            agree_count += len(eg.get("accept", []))
        msg.info(f"Evaluating data from '{set_id}'")
        msg.text(f"You rejected {len(rejected)} and ignored {len(ignored)} pair(s)")
        pc = agree_count / total_count
        text = f"You agreed {agree_count} / {total_count} times ({pc:.0%})"
        if pc > 0.5:
            msg.good(text)
        else:
            msg.fail(text)

    def on_exit(ctrl):
        set_id = dataset if eval_whole else ctrl.session_id
        eval_dataset(set_id)

    if eval_only:
        eval_dataset(dataset)
        return None

    return {
        "view_id": "choice",
        "dataset": dataset,
        "stream": get_stream(),
        "on_exit": on_exit,
        "config": {"choice_style": "multiple", "batch_size": batch_size},
    }

    Evaluate a vectors model by looking at the most similar entries it returns
    for a random phrase and unselecting the mistakes.
    
sense2vec/prodigy_recipes.py