CoolFace
Datasetpublic

NLP-UniBW/tweets_about_NBA_players_in_playoffs_april_june_2025

Tweets about NBA Players in the 2025 Playoffs (Pseudonymized) A corpus of 1,428,813 English tweets about 244 NBA players, collected daily throughout the 2025 NBA postseason (18 April – 24 June 2025, 68 consecutive days), covering the play‑in tournament through the NBA Finals. All author-identifying fields have been replaced with keyed, consistent pseudonyms so the corpus can be used for scientific research. Pseudonyms are stable across the whole dataset, so reply graphs, quote… See the full description on the dataset page: https://huggingface.co/datasets/NLP-UniBW/tweets_about_NBA_players_in_playoffs_april_june_2025.

sourceHugging Faceotherupdated 1mo agoView on Hugging Face
0likes24downloads
Dataset Card

Tweets about NBA Players in the 2025 Playoffs (Pseudonymized)

A corpus of 1,428,813 English tweets about 244 NBA players, collected daily throughout the 2025 NBA postseason (18 April – 24 June 2025, 68 consecutive days), covering the play‑in tournament through the NBA Finals.

All author-identifying fields have been replaced with keyed, consistent pseudonyms so the corpus can be used for scientific research. Pseudonyms are stable across the whole dataset, so reply graphs, quote graphs and author-level aggregation remain fully analyzable without exposing any real account.

Private scientific use only — no redistribution. All rights in the underlying content lie with X Corp. See Licensing before use.
python
from datasets import load_dataset

ds = load_dataset("NLP-UniBW/tweets_about_NBA_players_in_playoffs_april_june_2025", split="train")
print(ds[0])

Dataset at a glance

Tweets1,428,813
Distinct pseudonymous authors332,857 (handle-based) / 328,458 (profile-based)
Players queried (search_term)244
Period2025‑04‑18 → 2025‑06‑24 (68 days)
LanguageEnglish only (language == "en" for every row)
Splitssingle train split
FormatParquet, 2 shards

Content statistics

PropertyCountShare
Tweets that are replies (replying-to non-empty)457,14532.0 %
Tweets with an attached image137,1039.6 %
Tweets quoting another post134,0789.4 %
Tweets with a GIF40,0782.8 %
Authors using the default profile picture14,5811.0 %
Authors with exactly one tweet in the corpus189,01056.8 % of authors

Engagement totals across the corpus: 84,408,437 likes, 5,092,748 retweets, 2,710,265 comments, 1,402,918 quotes. Likes are heavily skewed (mean 59.1, median 1, p95 64, max 278,075).

Most frequent search terms: LeBron James (64,513), Jalen Green (49,990), Jayson Tatum (40,340), Aaron Gordon (38,551), Anthony Edwards (37,569), Jalen Brunson (35,450), Tyrese Haliburton (32,148), Josh Hart (32,142), James Harden (30,665), Jaylen Brown (29,848).

Busiest day: 2025‑04‑27 (50,016 tweets, first-round Sunday slate).

Fields

FieldTypePseudonymizedNotes
search_termstring—Player name whose query retrieved the tweet (244 values)
languagestring—Always "en"
idstringyest_<16 hex>
linkstringyesRebuilt as https://twitter.com/user_<hex>/status/t_<hex>#m; does not resolve
textstringpartlyVerbatim, except handle/permalink/contact substitutions described below
namestringyesDisplay name → user_<12 hex>
usernamestringyes@user_<12 hex>
profile_idstringyesp_<16 hex>; empty string for 14,581 rows where the source had none
avatarstringyes/pic/profile_images/p_<hex>/<hex>_bigger.<ext>; image is unreachable
datestring—UTC, minute resolution (seconds always 00)
is-retweetbool—Constant `false` for every row
is-pinnedbool—Constant `false` for every row
external-linkstring—Always empty
replying-tolist\<string\>yesEvery entry pseudonymized (780,760 entries)
quoted-poststructyeslink, text and nested user.{name,username,profile_id,avatar} all pseudonymized
comments retweets quotes likesint64—Engagement counters at scrape time
pictureslist\<string\>—Live pbs.twimg.com URLs (see limitations)
videoslist\<null\>—Always empty — no video was captured
gifslist\<string\>—Live video.twimg.com URLs

Pseudonymization method

Every pseudonym is HMAC-SHA256(key, domain ‖ real_value) truncated to hex, under a single 32-byte cryptographically random key. ‖ denotes concatenation: the message actually hashed for handle grinderstaff is the byte string handle|grinderstaff.

This is the exact construction that was applied:

python
import hashlib
import hmac
import secrets

# Generated once, held privately by the data controller, never published.
# A plain SHA-256 of a handle would be trivially reversible: the space of Twitter
# handles is small and enumerable, so an attacker could hash a public handle list
# and look every pseudonym up. The secret key is what prevents that.
KEY = secrets.token_bytes(32)


def _mac(domain: str, value: str, n: int) -> str:
    """HMAC-SHA256(key, domain ‖ value), truncated to n hex characters.

    The domain string keeps the namespaces apart. Tweet ids and profile ids are both
    19-digit snowflake numbers drawn from the same space, so without it the same digits
    occurring as both would collide and imply a link that does not exist.
    """
    return hmac.new(KEY, domain.encode() + b"|" + value.encode("utf-8"),
                    hashlib.sha256).hexdigest()[:n]


def pseudo_handle(handle: str) -> str:
    """'@SomeHandle' -> 'user_<12 hex>'. Lowercased first, because Twitter handles
    are case-insensitive and '@Foo' / '@foo' are the same account."""
    return "user_" + _mac("handle", handle.lstrip("@").lower(), 12)


def pseudo_profile_id(profile_id: str) -> str:
    """19-digit numeric profile id -> 'p_<16 hex>'."""
    return "p_" + _mac("profile_id", profile_id, 16)


def pseudo_tweet_id(tweet_id: str) -> str:
    """19-digit numeric snowflake tweet id -> 't_<16 hex>'."""
    return "t_" + _mac("tweet_id", tweet_id, 16)

The composite fields are rebuilt from those primitives, which is why they stay mutually consistent — an author's username, name, link and avatar all agree, and a quoted-post.link agrees with the quoted-post.user.username beside it:

python
username = "@" + pseudo_handle(username)          # '@SomeHandle' -> '@user_<12 hex>'
name     = pseudo_handle(username)                # display name  ->  'user_<12 hex>'

link     = f"https://twitter.com/{pseudo_handle(handle)}/status/{pseudo_tweet_id(tweet_id)}#m"

# /pic/profile_images/<profile_id>/VVZNWPTb_bigger.jpg
#   -> /pic/profile_images/p_<hex>/<hex>_bigger.jpg
# The whole original filename is hashed; the size suffix and extension are carried over
# so the "custom vs. default profile picture" signal survives.
avatar   = f"/pic/profile_images/{pseudo_profile_id(profile_id)}/" \
           f"{_mac('avatar', filename, 12)}_{size}.{ext}"

Note that name is derived from the handle, not from the original display name. Display names are free text and frequently contain a real name, so nothing derived from them is retained.

Properties of this construction:

  • —Deterministic — the same real value always maps to the same pseudonym, everywhere in the corpus. An author appearing as a tweet author, as a reply target, as a quoted user and as an in-text mention receives one identical pseudonym in all four places.
  • —Domain-separated — handles, profile ids, tweet ids and avatar hashes occupy separate namespaces and cannot be cross-correlated.
  • —Keyed — the mapping cannot be recomputed or brute-forced without the key. The key is held privately by the data controller and is not published.
  • —Case-insensitive for handles — @Foo and @foo are the same account and collapse to the same pseudonym.

Pseudonym shapes are deliberately non-numeric so they can never be mistaken for, or collide with, a real Twitter/X snowflake id: t_<16 hex> (tweet), p_<16 hex> (profile), @user_<12 hex> (handle).

Transformations applied to free text

text and quoted-post.text are otherwise byte-identical to the source. Only these substitutions were made:

SubstitutionCount
@mentions of accounts that are data subjects of this corpus → pseudonym112,500
@mentions of accounts that are not data subjects → left intact38,720
Handles inside profile/permalink URLs (nitter.net/<handle>, x.com/<handle>)878
Status ids inside permalinks (/status/<id>, incl. /i/status/, /i/web/status/)1,361
Corpus ids pasted as bare digits or query parameters (?id=, threadreader links)14
E-mail addresses → [EMAIL]87
Phone numbers → [PHONE]385

Mentions of public organizations and public figures that never authored a tweet in this corpus (@NBA, @espn, @YouTube, @grok, team accounts) are preserved on purpose — they are discourse content rather than data subjects of this dataset, and removing them would destroy substantial semantic signal. Note that a handle belonging to a public account which also authored a tweet in the corpus is pseudonymized, because it is a data subject here.

News and section URLs are untouched: a host-blind rewrite would have corrupted thousands of legitimate links such as espn.com/nba or clutchpoints.com/nba, since nba is itself a registered handle.

Verification

The release was checked row-by-row against the source. All 1,428,813 rows passed:

  • —every identifier field matches its expected synthetic shape;
  • —a value missing in the source stays missing (no pseudonym is invented);
  • —no original handle, tweet id or profile id survives anywhere — including inside free text, URLs and query strings;
  • —the handle mapping is a strict bijection: 332,857 distinct handles → 332,857 distinct pseudonyms, zero collisions; likewise 1,428,813 distinct tweet-id pseudonyms;
  • —all 13 non-identifying fields (search_term, language, date, engagement counters, media lists, …) are byte-identical to the source.

Privacy: residual risk

This dataset is pseudonymized, not irreversibly anonymized. Anyone using it for research involving human subjects should account for the following:

  1. 1.Tweet text is verbatim and therefore searchable. Pasting a tweet from this corpus into a search engine may recover the original post and its author. This is inherent to any tweet corpus that preserves text, and it is the dominant residual re-identification vector — larger than anything the identifier pseudonymization addresses.
  2. 2.Media URLs are live. pictures and video.twimg.com links in gifs contain no handle or profile id, but they point at real hosted media and can be reverse-searched. They were kept because they are required for multimodal work.
  3. 3.Self-disclosed identity in text is not removed. Real names, external profile links (e.g. twitch.tv/<name>), locations and affiliations written by users into their own tweets remain.
  4. 4.Mentions of non-data-subject accounts remain, by design (see above).
  5. 5.A pseudonymization key exists. It is not published, but its existence means the mapping is in principle reversible by the key holder. Under GDPR this is pseudonymization within the meaning of Art. 4(5) / Recital 26, not anonymization.
  6. 6.Author-level linkage is preserved by design. All tweets by one author share a pseudonym, so an author's full posting history within the corpus is reconstructible, which can itself support re-identification through writing style or self-disclosure.

Intended uses

Suitable for sports-related NLP and computational social science: sentiment and emotion analysis, stance and toxicity detection, event detection around games, topic modelling, engagement prediction, reply/quote network analysis, temporal discourse dynamics, and multimodal work using the retained media links.

Out of scope

  • —Identifying, profiling, contacting or targeting individual account holders, or attempting to reverse the pseudonymization.
  • —Treating the corpus as a representative sample of Twitter/X, of NBA fans, or of public opinion.
  • —Any use that violates the Twitter/X Terms of Service or applicable data-protection law in the user's jurisdiction.
  • —Redistribution in any form, and any commercial use — see Licensing.

Limitations and biases

  • —Query-driven sampling. Tweets were retrieved by searching 244 player names, so coverage is skewed toward heavily discussed players and away from posts that discuss the playoffs without naming a player.
  • —One `search_term` per tweet. The corpus is deduplicated by tweet id, so a tweet naming several players is attributed to a single query term. Do not treat search_term as a complete label of which players a tweet discusses — parse text instead.
  • —English only, so non-English discourse about the same events is absent.
  • —Scrape-time engagement counters. Likes/retweets/quotes/comments are snapshots from collection time, not final values, and tweets collected near their posting time are systematically under-counted.
  • —Minute-resolution timestamps; ordering within a minute is not recoverable.
  • —Constant and empty columns: is-retweet and is-pinned are false everywhere, external-link is always empty, and videos is always empty. They are retained only for schema compatibility with the source dataset.
  • —Collection is frontend-mediated (Nitter), so deleted, protected, rate-limited or intermittently unavailable posts are missing in ways that are not random.
  • —Not a random sample — no inference about base rates in the wider population is supported.

Provenance

Collected daily throughout the 2025 NBA postseason by querying 244 player names against a Nitter frontend, then deduplicated by tweet id. The pseudonymization described above was applied to that collection as a single transformation pass: no rows were added, removed or reordered, and the schema is unchanged.

Licensing

Private scientific use only. No redistribution.

All rights in the underlying tweet content lie with X Corp. (formerly Twitter, Inc.). No ownership of that content is claimed or transferred by this release, and access to this dataset grants you no rights in it.

This dataset is made available solely for non-commercial scientific research carried out privately by the individual recipient. By accessing or using it, you agree to:

  • —use the data only for private, non-commercial scientific research;
  • —not redistribute, republish, resell, mirror, or otherwise make available the dataset or any substantial part of it — in original, modified or derived form — to any third party;
  • —not use it for any commercial purpose, including training models offered as a commercial product or service;
  • —not attempt to re-identify, contact, profile or target any account holder, and not attempt to reverse the pseudonymization;
  • —delete your copy when your research purpose ends, or on request.

Publishing aggregate results, statistics, and short non-identifying illustrative examples derived from the data is permitted and expected in scientific work. Publishing the dataset itself, or any extract that would serve as a substitute for it, is not.

These terms are additional to, and do not override, the X Terms of Service and applicable data-protection law. Where those are stricter, they govern. Each recipient is responsible for their own compliance.

Citation

bibtex
@misc{tweets_nba_playoffs_2025,
  title  = {Tweets about NBA Players in the 2025 Playoffs (Pseudonymized)},
  author = {Schneider, Sinclair},
  year   = {2025},
  howpublished = {\url{https://huggingface.co/datasets/NLP-UniBW/tweets_about_NBA_players_in_playoffs_april_june_2025}},
  note   = {NLP Group, Universit\"at der Bundeswehr M\"unchen}
}

Contact

NLP Group, Universität der Bundeswehr München — <sinclair.schneider@unibw.de>