human
I am working on the file "Machine Learning/Query Optimization/notebooks/Appendix B - Combining queries.ipynb".
The first task is:
So that's the same as without tuning. What's going on?
Debugging
Plot scores from each sub-query to determine why we don't really see an improvement over individual queries.
Can you write Python code for it?
 ... Write me a Python code to determine why we don't really see an improvement over individual queries?
assistant
#Here is Python code to determine why we don't really see an improvement over individual queries.

import matplotlib.pyplot as plt
from itertools import chain

from qopt.notebooks import ROOT_DIR
from qopt.search import temporary_search_template, search_template
from qopt.trec import load_queries_as_tuple_list, load_qrels

def collect_scores():
    
    def _search(template_id, query_string, params, doc_id):
        res = search_template(es, index, template_id, query={
            'id': 0,
            'params': {
                'query_string': query_string,
                **params,
            },
        })
        return [hit['score'] for hit in res['hits'] if hit['id'] == doc_id]

    queries = load_queries_as_tuple_list(os.path.join(ROOT_DIR, 'data', 'msmarco-document-sampled-queries.1000.tsv'))
    qrels = load_qrels(os.path.join(ROOT_DIR, 'data', 'msmarco', 'document', 'msmarco-doctrain-qrels.tsv'))
    template_file = os.path.join(ROOT_DIR, 'config', 'msmarco-document-templates.json')
    size = 100
    
    cross_field_scores = []
    best_field_scores = []
    
    with temporary_search_template(es, template_file, 'cross_fields', size) as cross_fields_template_id:
        with temporary_search_template(es, template_file, 'best_fields', size) as best_fields_template_id:
            for query in queries:
                doc_id = list(qrels[query[0]].keys())[0]
                
                cfs = _search(cross_fields_template_id, query[1], cross_fields_params, doc_id)
                bfs = _search(best_fields_template_id, query[1], best_fields_params, doc_id)

                # keep just n scores to make sure the lists are the same length
                length = min(len(cfs), len(bfs))
                cross_field_scores.append(cfs[:length])
                best_field_scores.append(bfs[:length])

    return cross_field_scores, best_field_scores

cfs, bfs = collect_scores()

# plot scores
cfs_flat = list(chain(*cfs))
bfs_flat = list(chain(*bfs))

plt.scatter(cfs_flat, bfs_flat)
plt.show()