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 files

https://www.cs.cornell.edu/~cristian/pdfs/winning_arguments.pdf

https://convokit.cornell.edu/documentation/winning.html

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 scrape_cmv
74
- print(" CMV file missing β€” scraping live from Reddit (limit=150)…")
75
- cmv = clean_debates(scrape_cmv(limit=150, sort="top", time_filter="all"))
76
  if cmv:
77
  debates += cmv
78
- print(f" CMV (Reddit live): {len(cmv)} debates (total: {len(debates)})")
 
 
 
79
  else:
80
- print(" Reddit scraper returned 0 debates β€” training on IBM only")
81
  except Exception as e2:
82
- print(f" CMV not available ({e2.__class__.__name__}: {e2}) β€” training on IBM only")
 
 
 
 
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