MonikaDvorackova commited on
Commit
5f0f11b
·
unverified ·
1 Parent(s): 2c87f1c

Train LLM response quality classifier

Browse files
Files changed (3) hide show
  1. .gitignore +4 -0
  2. model.joblib +3 -0
  3. train.py +54 -30
.gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ .DS_Store
model.joblib ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a23436e774c50aa25817e699197656880faaf46ab78c2f3847f5620db38134f4
3
+ size 44164
train.py CHANGED
@@ -5,11 +5,10 @@ import joblib
5
  import pandas as pd
6
  from sklearn.feature_extraction.text import TfidfVectorizer
7
  from sklearn.linear_model import LogisticRegression
8
- from sklearn.metrics import classification_report
9
- from sklearn.model_selection import LeaveOneOut, cross_val_predict
10
  from sklearn.pipeline import Pipeline
11
 
12
-
13
  DATA_PATH = Path("data/train.jsonl")
14
  MODEL_PATH = Path("model.joblib")
15
 
@@ -19,40 +18,29 @@ def load_data(path: Path) -> pd.DataFrame:
19
 
20
  with path.open("r", encoding="utf-8") as file:
21
  for line in file:
22
- records.append(json.loads(line))
 
23
 
24
  return pd.DataFrame(records)
25
 
26
 
27
- def main():
28
- df = load_data(DATA_PATH)
29
-
30
- # Combine the original prompt and response so that the classifier
31
- # can use information from both parts of the evaluation example.
32
- X = (
33
- "PROMPT: "
34
- + df["prompt"].astype(str)
35
- + "\nRESPONSE: "
36
- + df["response"].astype(str)
37
- )
38
-
39
- y = df["quality_label"]
40
-
41
- pipeline = Pipeline(
42
  [
43
  (
44
  "tfidf",
45
  TfidfVectorizer(
46
  ngram_range=(1, 2),
47
  lowercase=True,
48
- min_df=1,
 
49
  sublinear_tf=True,
50
  ),
51
  ),
52
  (
53
  "classifier",
54
  LogisticRegression(
55
- max_iter=1000,
56
  class_weight="balanced",
57
  random_state=42,
58
  ),
@@ -60,19 +48,40 @@ def main():
60
  ]
61
  )
62
 
63
- # With only 24 examples, a conventional train/test split would
64
- # provide an unstable and potentially misleading estimate.
65
- loo = LeaveOneOut()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
  predictions = cross_val_predict(
68
  pipeline,
69
  X,
70
  y,
71
- cv=loo,
72
  )
73
 
74
- print("Leave-One-Out Cross-Validation")
75
- print("=" * 40)
76
 
77
  print(
78
  classification_report(
@@ -83,13 +92,28 @@ def main():
83
  )
84
  )
85
 
86
- # Train the final demonstration model on all available examples.
 
 
 
 
 
 
 
 
 
 
 
 
87
  pipeline.fit(X, y)
88
 
89
- joblib.dump(pipeline, MODEL_PATH)
 
 
 
90
 
91
  print(f"Saved model to: {MODEL_PATH.resolve()}")
92
 
93
 
94
  if __name__ == "__main__":
95
- main()
 
5
  import pandas as pd
6
  from sklearn.feature_extraction.text import TfidfVectorizer
7
  from sklearn.linear_model import LogisticRegression
8
+ from sklearn.metrics import classification_report, confusion_matrix
9
+ from sklearn.model_selection import StratifiedKFold, cross_val_predict
10
  from sklearn.pipeline import Pipeline
11
 
 
12
  DATA_PATH = Path("data/train.jsonl")
13
  MODEL_PATH = Path("model.joblib")
14
 
 
18
 
19
  with path.open("r", encoding="utf-8") as file:
20
  for line in file:
21
+ if line.strip():
22
+ records.append(json.loads(line))
23
 
24
  return pd.DataFrame(records)
25
 
26
 
27
+ def build_pipeline() -> Pipeline:
28
+ return Pipeline(
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  [
30
  (
31
  "tfidf",
32
  TfidfVectorizer(
33
  ngram_range=(1, 2),
34
  lowercase=True,
35
+ min_df=2,
36
+ max_df=0.95,
37
  sublinear_tf=True,
38
  ),
39
  ),
40
  (
41
  "classifier",
42
  LogisticRegression(
43
+ max_iter=2000,
44
  class_weight="balanced",
45
  random_state=42,
46
  ),
 
48
  ]
49
  )
50
 
51
+
52
+ def main():
53
+ df = load_data(DATA_PATH)
54
+
55
+ X = (
56
+ "PROMPT: "
57
+ + df["prompt"].astype(str)
58
+ + "\nRESPONSE: "
59
+ + df["response"].astype(str)
60
+ )
61
+
62
+ y = df["quality_label"].astype(str)
63
+
64
+ print(f"Examples: {len(df)}")
65
+ print(y.value_counts().sort_index())
66
+ print()
67
+
68
+ cv = StratifiedKFold(
69
+ n_splits=5,
70
+ shuffle=True,
71
+ random_state=42,
72
+ )
73
+
74
+ pipeline = build_pipeline()
75
 
76
  predictions = cross_val_predict(
77
  pipeline,
78
  X,
79
  y,
80
+ cv=cv,
81
  )
82
 
83
+ print("Stratified 5-Fold Cross-Validation")
84
+ print("=" * 44)
85
 
86
  print(
87
  classification_report(
 
92
  )
93
  )
94
 
95
+ labels = sorted(y.unique())
96
+
97
+ matrix = confusion_matrix(
98
+ y,
99
+ predictions,
100
+ labels=labels,
101
+ )
102
+
103
+ print("Confusion matrix")
104
+ print(f"Labels: {labels}")
105
+ print(matrix)
106
+ print()
107
+
108
  pipeline.fit(X, y)
109
 
110
+ joblib.dump(
111
+ pipeline,
112
+ MODEL_PATH,
113
+ )
114
 
115
  print(f"Saved model to: {MODEL_PATH.resolve()}")
116
 
117
 
118
  if __name__ == "__main__":
119
+ main()