CoolFace
Datasetpublic

frankjc2022/semantic-history-search

Semantic History (Synthetic) Semantic History is a synthetic dataset for semantic history search research.It ships as three normalized Parquet tables: Split Description docs Search history records with url, title, description, frecency, last_visit_date, and tags. queries One row per query, tagged by profile and temporal/multi-label flags. qrels Relevance pairs linking queries ↔ docs with rank and relevance. All content is synthetic (no real browsing logs).… See the full description on the dataset page: https://huggingface.co/datasets/frankjc2022/semantic-history-search.

sourceHugging Facemitupdated 11mo agoView on Hugging Face
3likes76downloads
Dataset Card

Semantic History (Synthetic)

Semantic History is a synthetic dataset for semantic history search research. It ships as three normalized Parquet tables:

SplitDescription
docsSearch history records with url, title, description, frecency, last_visit_date, and tags.
queriesOne row per query, tagged by profile and temporal/multi-label flags.
qrelsRelevance pairs linking queries ↔ docs with rank and relevance.

All content is synthetic (no real browsing logs).


Temporal Variant

The dataset includes a temporal slice designed to test retrieval with time-aware queries (e.g., “yesterday”, “last week”, “on Black Friday”). Temporal queries in queries are tagged with variant="temporal" and carry a per-query reference time ref_datetime_iso, which is the anchor used to resolve relative phrases (e.g., “yesterday” → specific date range).

For reproducibility, we also publish the raw temporal profiles (one folder per profile) that were used to construct the Parquet release. Each temporal profile contains:

  • —history.csv — history rows with last_visit_date (µs epoch) and frecency
  • —query.csv — temporal queries and expected matches
  • —temporal_context.json — reference time and locale rules (e.g., timezone, weekend, date format)
See the detailed temporal documentation and per-locale notes here: https://huggingface.co/datasets/frankjc2022/semantic-history-search/blob/main/raw/profiles/temporal/README.md

Motivation

  • —User-oriented IR (per-profile history retrieval)
  • —Temporal-aware retrieval (e.g., profile histories with a reference time)
  • —Embedding & ranking evaluation on synthetic history traces

Data Layout

data/v1/
├── docs.parquet
├── queries.parquet
└── qrels.parquet

Columns

  • —docs: doc_id, url, title, description, frecency, last_visit_date, profile, profile_id, variant
  • —queries: query_id, search_query, profile, profile_id, is_temporal, is_multi, variant, ref_datetime_iso
  • —qrels: query_id, doc_id, profile_id, relevance, rank, variant
profile_id is a stable, hashed identifier per profile folder; variant can be temporal or other configured variants; is_multi indicates multi-label queries.

Firefox Places Background (schema context)

The dataset docs mimics Firefox’s Places DB:

  • —moz_places table schema: https://searchfox.org/firefox-main/source/toolkit/components/places/nsPlacesTables.h
  • —Length limits referenced in Places utils: title ≤ 4096 chars, description ≤ 256 https://searchfox.org/firefox-main/source/toolkit/components/places/PlacesUtils.sys.mjs#162
  • —title from DOM <title>: https://searchfox.org/firefox-main/source/dom/svg/SVGTitleElement.cpp
  • —description from prioritized page metadata: https://searchfox.org/firefox-main/source/toolkit/actors/ContentMetaChild.sys.mjs#12
Embedding text: we use `title + description`.

How to Load (HF Datasets)

python
from datasets import load_dataset

dataset_id = "frankjc2022/semantic-history-search"
docs_pd    = load_dataset(dataset_id, name="docs")["train"]
queries_pd = load_dataset(dataset_id, name="queries")["train"]
qrels_pd   = load_dataset(dataset_id, name="qrels")["train"]

Common Operations

HF Datasets Version

List available profiles
python
profiles = (docs.to_pandas()[["profile_id","profile","variant"]]
             .drop_duplicates()
             .sort_values(["profile","variant"]))
Filter by profile
python
pid = "262e49ec20c32c41"
p_docs    = docs.filter(lambda x: x["profile_id"] == pid)
p_queries = queries.filter(lambda x: x["profile_id"] == pid)
p_qrels   = qrels.filter(lambda x: x["profile_id"] == pid)
Temporal / multi-label slices
python
q_temporal = queries.filter(lambda x: x["variant"] == "temporal")
q_multi    = queries.filter(lambda x: x["is_multi"])

Pandas Version

python
import pandas as pd
from datasets import load_dataset

dataset_id = "frankjc2022/semantic-history-search"
docs_pd    = load_dataset(dataset_id, name="docs")["train"].to_pandas()
queries_pd = load_dataset(dataset_id, name="queries")["train"].to_pandas()
qrels_pd   = load_dataset(dataset_id, name="qrels")["train"].to_pandas()

q = queries_pd[["query_id","search_query","profile_id","variant","is_multi"]].set_index("query_id")
r = qrels_pd[["query_id","doc_id","rank","relevance"]].set_index("query_id")
d = docs_pd[["doc_id","url","title"]].set_index("doc_id")

# Reconstruct (query <-> doc/url) pairs
qr = r.join(q, how="inner").reset_index()
query_pairs = (qr.join(d, on="doc_id", how="left")
                 .sort_values(["query_id","rank"])
                 .reset_index(drop=True))

Evaluation

This dataset is intended for retrieval evaluation. Please see the repository for the evaluation scripts/notebooks and metric implementations:

  • —Precision@k, Recall@k, nDCG@k
  • —Reciprocal Rank (RR), Average Precision (AP)
  • —On-Topic Rate@k

Synthetic Data Generation

All profiles, queries, and qrels are synthetic. The pipeline creates per-profile histories and LLM-judged relevance pairs from public English documents.

Overview

  1. 1.Source: MS MARCO documents (msmarco-docs.tsv); keep top 500k rows with docid,url,title,body (English).
  1. 1.Normalize: build a unified table with url,title,description,topic,lang,domain,combined_text
  2. 2.description = first 300 chars of body
  3. 3.filter titles to length 5-200
  4. 4.combined_text = title + " " + description
  1. 1.Sample: draw ~50k examples (English-only for this HF release).
  1. 1.Profiles: create 25 synthetic profiles; for each, sample 1k-5k items aligned with profile themes; set random frecency (100-5000) and incremental last_visit_date.
  1. 1.Queries & qrels: generate profile-specific queries with an LLM; judge relevance over the profile history; export qrels with rank and relevance=1 and concise query.csv per profile.

Code (full scripts & notebooks):

  • —https://github.com/mozilla/smartsearch/tree/temporalawareness/preprocessing/generate_profiles
  • —https://github.com/mozilla/smartsearch/blob/temporalawareness/notebooks/generate_history.ipynb

Additional Dataset

We also include a second dataset built from publicly available synthetic histories:

  • —Source repo: https://github.com/komosny/synthetic-browsing-history
  • —Details/paper: https://pmc.ncbi.nlm.nih.gov/articles/PMC11754914/

Countries (English-focused): Australia, Canada, United Kingdom, United States.

Preprocessing

  • —Deduplicate by URL.
  • —Fetch title and description with priorities:
  • —title: <title> → meta[property=og:title] → meta[name=twitter:title] → <h1>
  • —description: meta[name=description] → meta[property=og:description] → meta[name=twitter:description] → summary
  • —Enforce Firefox-style limits: title ≤ 4096, description ≤ 256.
  • —Drop records with no title and no description.

Query Construction

  • —For each profile, randomly sample 50 URLs.
  • —Use an LLM (gpt-5-mini) to generate 50 semantic search queries that should retrieve the given URL, conditioning on its title and description.

Raw Layer

We maintain a reference raw/ tree for repro, but the canonical interface is the Parquet layer:

raw/profiles/<variant>/<single|multi-label>/<profile>/
  ├── history.csv
  ├── query.csv
  └── temporal_context.json  # only for temporal
Use Parquet for all experiments. raw/ is reference-only; no remote execution loaders.