Spaces:
Runtime error
Runtime error
stefhooy commited on
Commit Β·
94abcb8
1
Parent(s): deefbae
Updating the Data Model : IBM Debater vs CMV, testing out CVM and check if it's good or not
Browse fileshttps://www.cs.cornell.edu/~cristian/pdfs/winning_arguments.pdf
https://convokit.cornell.edu/documentation/winning.html
- data/__init__.py +2 -1
- data/loaders/__init__.py +2 -1
- data/loaders/convokit_cmv.py +137 -0
- src/train.py +13 -6
data/__init__.py
CHANGED
|
@@ -1,11 +1,12 @@
|
|
| 1 |
from data.schema import Argument, Debate
|
| 2 |
-
from data.loaders import load_cmv, load_ibm, scrape_cmv
|
| 3 |
from data.preprocessing import clean_debates
|
| 4 |
|
| 5 |
__all__ = [
|
| 6 |
"Argument",
|
| 7 |
"Debate",
|
| 8 |
"load_cmv",
|
|
|
|
| 9 |
"load_ibm",
|
| 10 |
"scrape_cmv",
|
| 11 |
"clean_debates",
|
|
|
|
| 1 |
from data.schema import Argument, Debate
|
| 2 |
+
from data.loaders import load_cmv, load_convokit_cmv, load_ibm, scrape_cmv
|
| 3 |
from data.preprocessing import clean_debates
|
| 4 |
|
| 5 |
__all__ = [
|
| 6 |
"Argument",
|
| 7 |
"Debate",
|
| 8 |
"load_cmv",
|
| 9 |
+
"load_convokit_cmv",
|
| 10 |
"load_ibm",
|
| 11 |
"scrape_cmv",
|
| 12 |
"clean_debates",
|
data/loaders/__init__.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
| 1 |
from data.loaders.cmv import load_cmv
|
|
|
|
| 2 |
from data.loaders.ibm import load_ibm
|
| 3 |
from data.loaders.reddit import scrape_cmv
|
| 4 |
|
| 5 |
-
__all__ = ["load_cmv", "load_ibm", "scrape_cmv"]
|
|
|
|
| 1 |
from data.loaders.cmv import load_cmv
|
| 2 |
+
from data.loaders.convokit_cmv import load_convokit_cmv
|
| 3 |
from data.loaders.ibm import load_ibm
|
| 4 |
from data.loaders.reddit import scrape_cmv
|
| 5 |
|
| 6 |
+
__all__ = ["load_cmv", "load_convokit_cmv", "load_ibm", "scrape_cmv"]
|
data/loaders/convokit_cmv.py
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Loader for the ConvoKit Winning Arguments (CMV) corpus.
|
| 3 |
+
|
| 4 |
+
Source: Tan et al. 2016 β r/changemyview threads where OP awards
|
| 5 |
+
a delta to a reply that changed their view.
|
| 6 |
+
Corpus: Cornell ConvoKit winning-args-corpus (3,051 threads, 293k utts)
|
| 7 |
+
|
| 8 |
+
Download once:
|
| 9 |
+
python -c "from convokit import download; download('winning-args-corpus')"
|
| 10 |
+
|
| 11 |
+
Label mapping:
|
| 12 |
+
- root utterance (OP post) β claim
|
| 13 |
+
- meta['success'] == 1 β counter_claim (delta-awarded)
|
| 14 |
+
- meta['success'] == 0 β premise (argument, no delta)
|
| 15 |
+
- meta['success'] is None β unknown (not in a pair)
|
| 16 |
+
|
| 17 |
+
max_unknown caps the unknown class so it doesn't overwhelm training.
|
| 18 |
+
"""
|
| 19 |
+
|
| 20 |
+
import json
|
| 21 |
+
import random
|
| 22 |
+
from pathlib import Path
|
| 23 |
+
from typing import List
|
| 24 |
+
|
| 25 |
+
from data.schema import Argument, Debate
|
| 26 |
+
|
| 27 |
+
_CORPUS_PATH = (
|
| 28 |
+
Path.home() / ".convokit" / "saved-corpora" / "winning-args-corpus"
|
| 29 |
+
)
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
def load_convokit_cmv(
|
| 33 |
+
split: str = "train",
|
| 34 |
+
max_unknown: int = 15_000,
|
| 35 |
+
seed: int = 42,
|
| 36 |
+
) -> List[Debate]:
|
| 37 |
+
utterances_path = _CORPUS_PATH / "utterances.jsonl"
|
| 38 |
+
conversations_path = _CORPUS_PATH / "conversations.json"
|
| 39 |
+
|
| 40 |
+
if not utterances_path.exists():
|
| 41 |
+
raise FileNotFoundError(
|
| 42 |
+
f"ConvoKit corpus not found at {_CORPUS_PATH}.\n"
|
| 43 |
+
"Run: python -c "
|
| 44 |
+
"\"from convokit import download; "
|
| 45 |
+
"download('winning-args-corpus')\""
|
| 46 |
+
)
|
| 47 |
+
|
| 48 |
+
with open(conversations_path, encoding="utf-8") as f:
|
| 49 |
+
conv_meta = json.load(f)
|
| 50 |
+
|
| 51 |
+
valid_ids = {
|
| 52 |
+
conv_id
|
| 53 |
+
for conv_id, data in conv_meta.items()
|
| 54 |
+
if bool(data.get("meta", {}).get("train", True)) == (split == "train")
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
conv_utterances: dict = {}
|
| 58 |
+
with open(utterances_path, encoding="utf-8") as f:
|
| 59 |
+
for line in f:
|
| 60 |
+
utt = json.loads(line)
|
| 61 |
+
root = utt["root"]
|
| 62 |
+
if root not in valid_ids:
|
| 63 |
+
continue
|
| 64 |
+
conv_utterances.setdefault(root, []).append(utt)
|
| 65 |
+
|
| 66 |
+
rng = random.Random(seed)
|
| 67 |
+
|
| 68 |
+
debates = []
|
| 69 |
+
for conv_id, utterances in conv_utterances.items():
|
| 70 |
+
meta = conv_meta.get(conv_id, {}).get("meta", {})
|
| 71 |
+
title = meta.get("op-title", "")
|
| 72 |
+
|
| 73 |
+
root_utt = next((u for u in utterances if u["id"] == conv_id), None)
|
| 74 |
+
if root_utt is None:
|
| 75 |
+
continue
|
| 76 |
+
|
| 77 |
+
claim = Argument(
|
| 78 |
+
id=root_utt["id"],
|
| 79 |
+
text=str(root_utt.get("text") or meta.get("op-text-body", "")),
|
| 80 |
+
arg_type="claim",
|
| 81 |
+
author=root_utt.get("user"),
|
| 82 |
+
metadata={"title": title},
|
| 83 |
+
)
|
| 84 |
+
|
| 85 |
+
structured, unknowns = [claim], []
|
| 86 |
+
for utt in utterances:
|
| 87 |
+
if utt["id"] == conv_id:
|
| 88 |
+
continue
|
| 89 |
+
text = str(utt.get("text") or "")
|
| 90 |
+
if not text.strip():
|
| 91 |
+
continue
|
| 92 |
+
|
| 93 |
+
success = utt.get("meta", {}).get("success")
|
| 94 |
+
if success == 1:
|
| 95 |
+
arg_type = "counter_claim"
|
| 96 |
+
elif success == 0:
|
| 97 |
+
arg_type = "premise"
|
| 98 |
+
else:
|
| 99 |
+
arg_type = "unknown"
|
| 100 |
+
|
| 101 |
+
arg = Argument(
|
| 102 |
+
id=utt["id"],
|
| 103 |
+
text=text,
|
| 104 |
+
arg_type=arg_type,
|
| 105 |
+
parent_id=utt.get("reply-to"),
|
| 106 |
+
author=utt.get("user"),
|
| 107 |
+
score=utt.get("meta", {}).get("score"),
|
| 108 |
+
metadata={"success": success},
|
| 109 |
+
)
|
| 110 |
+
if arg_type == "unknown":
|
| 111 |
+
unknowns.append(arg)
|
| 112 |
+
else:
|
| 113 |
+
structured.append(arg)
|
| 114 |
+
|
| 115 |
+
debates.append(Debate(
|
| 116 |
+
id=conv_id,
|
| 117 |
+
title=title,
|
| 118 |
+
source="cmv",
|
| 119 |
+
arguments=structured,
|
| 120 |
+
metadata={"unknowns": unknowns},
|
| 121 |
+
))
|
| 122 |
+
|
| 123 |
+
# Collect all unknowns, sample down, distribute back
|
| 124 |
+
all_unknowns = [
|
| 125 |
+
u for d in debates for u in d.metadata.get("unknowns", [])
|
| 126 |
+
]
|
| 127 |
+
sampled = set(
|
| 128 |
+
u.id for u in rng.sample(
|
| 129 |
+
all_unknowns, min(max_unknown, len(all_unknowns))
|
| 130 |
+
)
|
| 131 |
+
)
|
| 132 |
+
for debate in debates:
|
| 133 |
+
kept = [u for u in debate.metadata["unknowns"] if u.id in sampled]
|
| 134 |
+
debate.arguments.extend(kept)
|
| 135 |
+
del debate.metadata["unknowns"]
|
| 136 |
+
|
| 137 |
+
return debates
|
src/train.py
CHANGED
|
@@ -70,16 +70,23 @@ def train(
|
|
| 70 |
print(f" CMV (file): {len(cmv)} debates (total: {len(debates)})")
|
| 71 |
except FileNotFoundError:
|
| 72 |
try:
|
| 73 |
-
from data import
|
| 74 |
-
print(" CMV file missing β
|
| 75 |
-
cmv = clean_debates(
|
| 76 |
if cmv:
|
| 77 |
debates += cmv
|
| 78 |
-
print(
|
|
|
|
|
|
|
|
|
|
| 79 |
else:
|
| 80 |
-
print("
|
| 81 |
except Exception as e2:
|
| 82 |
-
print(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
except Exception as e:
|
| 84 |
print(f" CMV load error ({e}) β training on IBM only")
|
| 85 |
|
|
|
|
| 70 |
print(f" CMV (file): {len(cmv)} debates (total: {len(debates)})")
|
| 71 |
except FileNotFoundError:
|
| 72 |
try:
|
| 73 |
+
from data import load_convokit_cmv
|
| 74 |
+
print(" CMV file missing β loading ConvoKit corpusβ¦")
|
| 75 |
+
cmv = clean_debates(load_convokit_cmv("train"))
|
| 76 |
if cmv:
|
| 77 |
debates += cmv
|
| 78 |
+
print(
|
| 79 |
+
f" CMV (ConvoKit): {len(cmv)} debates"
|
| 80 |
+
f" (total: {len(debates)})"
|
| 81 |
+
)
|
| 82 |
else:
|
| 83 |
+
print(" ConvoKit returned 0 debates β IBM only")
|
| 84 |
except Exception as e2:
|
| 85 |
+
print(
|
| 86 |
+
f" CMV not available"
|
| 87 |
+
f" ({e2.__class__.__name__}: {e2})"
|
| 88 |
+
f" β training on IBM only"
|
| 89 |
+
)
|
| 90 |
except Exception as e:
|
| 91 |
print(f" CMV load error ({e}) β training on IBM only")
|
| 92 |
|