hsuvaskakoty commited on
Commit
cb58c8d
1 Parent(s): d2324b7

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +27 -13
  2. model_predict.py +150 -57
app.py CHANGED
@@ -2,25 +2,39 @@ import data_prep
2
  import model_predict
3
  import gradio as gr
4
 
 
 
 
 
 
 
 
5
  model_dict = {
6
- "BERT-Base": "research-dump/bert-base-uncased_deletion_multiclass_complete_Final",
7
- "BERT-Large": "research-dump/bert-large-uncased_deletion_multiclass_complete_final",
8
- "RoBERTa-Base": "research-dump/roberta-base_deletion_multiclass_complete_final",
9
- "RoBERTa-Large": "research-dump/roberta-large_deletion_multiclass_complete_final"
 
10
  }
11
 
12
- def process_url(url, model_key):
13
- model_name = model_dict[model_key]
14
  processed_text = data_prep.process_data(url)
15
  final_scores = model_predict.predict_text(processed_text, model_name)
16
- highest_prob_label = max(final_scores, key=final_scores.get)
17
- highest_prob = final_scores[highest_prob_label]
18
- progress_bars = {label: score for label, score in final_scores.items()}
19
 
20
- return processed_text, highest_prob_label, highest_prob, progress_bars #,highlighted_text
21
-
 
 
 
 
 
 
 
 
 
 
22
 
23
- title = 'Wikipedia Deletion Discussion Classifier Demo'
24
  desc = """ This demo is about classifying deletion discussions from Wikipedia about Wikipedia articles. Wikipedia community engages in discussions related to an article’s quality, and map potential issues to existing templates, or Wikipedia policies, which cover diverse areas, from low notability of sources to content implausibility or vandalism.
25
 
26
  To this end, we design a multiclass classifier to predict the outcome of a deletion discussion, without the need for human intervention. The classifier is trained on a dataset of deletion discussions from Wikipedia, and it predicts one of the following labels: delete, keep, merge, no consensus, speedy keep, speedy delete, redirect, or withdrawn. Each of these labels corresponds to a specific outcome of the deletion discussion as described below.
@@ -40,7 +54,7 @@ The input to the classifier is a URL of a Wikipedia deletion discussion page, an
40
 
41
 
42
  url_input = gr.Textbox(label="URL")
43
- model_name_input = gr.Dropdown(label="Model Name", choices=list(model_dict.keys()), value=list(model_dict.keys())[0])
44
  outputs = [
45
  gr.Textbox(label="Processed Text"),
46
  gr.Textbox(label="Label with Highest Probability"),
 
2
  import model_predict
3
  import gradio as gr
4
 
5
+ # model_dict = {
6
+ # "BERT-Base": "research-dump/bert-base-uncased_deletion_multiclass_complete_Final",
7
+ # "BERT-Large": "research-dump/bert-large-uncased_deletion_multiclass_complete_final",
8
+ # "RoBERTa-Base": "research-dump/roberta-base_deletion_multiclass_complete_final",
9
+ # "RoBERTa-Large": "research-dump/roberta-large_deletion_multiclass_complete_final"
10
+ # }
11
+
12
  model_dict = {
13
+ "Outcome Prediction": "outcome",
14
+ "Stance Detection": "stance",
15
+ "Policy Prediction": "policy",
16
+ "Sentiment Analysis": "sentiment",
17
+ "Offensive Language Detection": "offensive"
18
  }
19
 
20
+ def process_url(url, model_name):
 
21
  processed_text = data_prep.process_data(url)
22
  final_scores = model_predict.predict_text(processed_text, model_name)
 
 
 
23
 
24
+ if model_name == 'outcome':
25
+ highest_prob_item = max(final_scores, key=lambda x: x['score'])
26
+ highest_prob_label = highest_prob_item['outcome']
27
+ highest_prob = highest_prob_item['score']
28
+ progress_bars = {item['outcome']: item['score'] for item in final_scores}
29
+ else:
30
+ highest_prob_item = max(final_scores, key=lambda x: x['score'])
31
+ highest_prob_label = highest_prob_item[list(highest_prob_item.keys())[1]]
32
+ highest_prob = highest_prob_item['score']
33
+ progress_bars = {item[list(item.keys())[1]]: item['score'] for item in final_scores}
34
+
35
+ return processed_text, highest_prob_label, highest_prob, progress_bars
36
 
37
+ title = 'Wikipedia Deletion Discussion Analysis Suite'
38
  desc = """ This demo is about classifying deletion discussions from Wikipedia about Wikipedia articles. Wikipedia community engages in discussions related to an article’s quality, and map potential issues to existing templates, or Wikipedia policies, which cover diverse areas, from low notability of sources to content implausibility or vandalism.
39
 
40
  To this end, we design a multiclass classifier to predict the outcome of a deletion discussion, without the need for human intervention. The classifier is trained on a dataset of deletion discussions from Wikipedia, and it predicts one of the following labels: delete, keep, merge, no consensus, speedy keep, speedy delete, redirect, or withdrawn. Each of these labels corresponds to a specific outcome of the deletion discussion as described below.
 
54
 
55
 
56
  url_input = gr.Textbox(label="URL")
57
+ model_name_input = gr.Dropdown(label="Choose the Task", choices=list(model_dict.keys()), value=list(model_dict.keys())[0])
58
  outputs = [
59
  gr.Textbox(label="Processed Text"),
60
  gr.Textbox(label="Label with Highest Probability"),
model_predict.py CHANGED
@@ -1,19 +1,21 @@
1
  #using pipeline to predict the input text
 
2
  from transformers import pipeline, AutoTokenizer
3
- import torch
4
-
5
- label_mapping = {
6
- 'delete': [0, 'LABEL_0'],
7
- 'keep': [1, 'LABEL_1'],
8
- 'merge': [2, 'LABEL_2'],
9
- 'no consensus': [3, 'LABEL_3'],
10
- 'speedy keep': [4, 'LABEL_4'],
11
- 'speedy delete': [5, 'LABEL_5'],
12
- 'redirect': [6, 'LABEL_6'],
13
- 'withdrawn': [7, 'LABEL_7']
14
- }
15
 
16
- def predict_text(text, model_name):
 
 
 
 
 
 
 
 
 
 
 
 
17
  tokenizer = AutoTokenizer.from_pretrained(model_name)
18
  model = pipeline("text-classification", model=model_name, return_all_scores=True)
19
 
@@ -22,62 +24,153 @@ def predict_text(text, model_name):
22
  truncated_text = tokenizer.decode(tokens['input_ids'], skip_special_tokens=True)
23
 
24
  results = model(truncated_text)
25
- final_scores = {key: 0.0 for key in label_mapping}
26
 
 
27
  for result in results[0]:
28
  for key, value in label_mapping.items():
29
  if result['label'] == value[1]:
30
- final_scores[key] = result['score']
31
  break
32
 
33
- return final_scores
34
-
35
 
36
- # from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline
37
- # import torch
38
 
39
- # label_mapping = {
40
- # 'delete': [0, 'LABEL_0'],
41
- # 'keep': [1, 'LABEL_1'],
42
- # 'merge': [2, 'LABEL_2'],
43
- # 'no consensus': [3, 'LABEL_3'],
44
- # 'speedy keep': [4, 'LABEL_4'],
45
- # 'speedy delete': [5, 'LABEL_5'],
46
- # 'redirect': [6, 'LABEL_6'],
47
- # 'withdrawn': [7, 'LABEL_7']
48
- # }
49
 
50
- # def predict_text(text, model_name):
51
- # tokenizer = AutoTokenizer.from_pretrained(model_name)
52
- # model = AutoModelForSequenceClassification.from_pretrained(model_name, output_attentions=True)
53
 
54
- # inputs = tokenizer(text, return_tensors="pt", truncation=True, padding=True)
55
- # outputs = model(**inputs)
56
- # predictions = torch.nn.functional.softmax(outputs.logits, dim=-1)
57
 
58
- # final_scores = {key: 0.0 for key in label_mapping}
59
- # for i, score in enumerate(predictions[0]):
60
- # for key, value in label_mapping.items():
61
- # if i == value[0]:
62
- # final_scores[key] = score.item()
63
- # break
64
 
65
- # # Calculate average attention
66
- # attentions = outputs.attentions
67
- # avg_attentions = torch.mean(torch.stack(attentions), dim=1) # Average over all layers
68
- # avg_attentions = avg_attentions.mean(dim=1)[0] # Average over heads
69
- # token_importance = avg_attentions.mean(dim=0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
- # # Decode tokens and highlight important ones
72
- # tokens = tokenizer.convert_ids_to_tokens(inputs['input_ids'][0])
73
- # highlighted_text = []
74
- # for token, importance in zip(tokens, token_importance):
75
- # if importance > token_importance.mean():
76
- # highlighted_text.append(f"<b>{token}</b>") #
77
- # else:
78
- # highlighted_text.append(token)
79
 
80
- # highlighted_text = " ".join(highlighted_text)
81
- # highlighted_text = highlighted_text.replace("##", "")
 
 
 
 
82
 
83
- # return final_scores, highlighted_text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  #using pipeline to predict the input text
2
+ import pandas as pd
3
  from transformers import pipeline, AutoTokenizer
4
+ import pysbd
 
 
 
 
 
 
 
 
 
 
 
5
 
6
+ #-----------------Outcome Prediction-----------------
7
+ def outcome(text):
8
+ label_mapping = {
9
+ 'delete': [0, 'LABEL_0'],
10
+ 'keep': [1, 'LABEL_1'],
11
+ 'merge': [2, 'LABEL_2'],
12
+ 'no consensus': [3, 'LABEL_3'],
13
+ 'speedy keep': [4, 'LABEL_4'],
14
+ 'speedy delete': [5, 'LABEL_5'],
15
+ 'redirect': [6, 'LABEL_6'],
16
+ 'withdrawn': [7, 'LABEL_7']
17
+ }
18
+ model_name = "research-dump/roberta-large_deletion_multiclass_complete_final"
19
  tokenizer = AutoTokenizer.from_pretrained(model_name)
20
  model = pipeline("text-classification", model=model_name, return_all_scores=True)
21
 
 
24
  truncated_text = tokenizer.decode(tokens['input_ids'], skip_special_tokens=True)
25
 
26
  results = model(truncated_text)
 
27
 
28
+ res_list = []
29
  for result in results[0]:
30
  for key, value in label_mapping.items():
31
  if result['label'] == value[1]:
32
+ res_list.append({'sentence': truncated_text, 'outcome': key, 'score': result['score']})
33
  break
34
 
35
+ return res_list
 
36
 
37
+ #-----------------Stance Prediction-----------------
 
38
 
39
+ def extract_response(text, model_name, label_mapping):
40
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
41
+ pipe = pipeline("text-classification", model=model_name, tokenizer=tokenizer, top_k=None)
 
 
 
 
 
 
 
42
 
43
+ tokens = tokenizer(text, truncation=True, max_length=512)
44
+ truncated_text = tokenizer.decode(tokens['input_ids'], skip_special_tokens=True)
 
45
 
46
+ results = pipe(truncated_text)
 
 
47
 
48
+ final_scores = {key: 0.0 for key in label_mapping}
49
+ for result in results[0]:
50
+ for key, value in label_mapping.items():
51
+ if result['label'] == f'LABEL_{value}':
52
+ final_scores[key] = result['score']
53
+ break
54
 
55
+ return final_scores
56
+
57
+
58
+ def get_stance(text):
59
+ label_mapping = {
60
+ 'delete': 0,
61
+ 'keep': 1,
62
+ 'merge': 2,
63
+ 'comment': 3
64
+ }
65
+ seg = pysbd.Segmenter(language="en", clean=False)
66
+ text_list = seg.segment(text)
67
+ model = 'research-dump/bert-large-uncased_wikistance_v1'
68
+ res_list = []
69
+ for t in text_list:
70
+ res = extract_response(t, model,label_mapping) #, access_token)
71
+ highest_key = max(res, key=res.get)
72
+ highest_score = res[highest_key]
73
+ result = {'sentence':t,'stance': highest_key, 'score': highest_score}
74
+ res_list.append(result)
75
+
76
+ return res_list
77
+
78
+
79
+ #-----------------Policy Prediction-----------------
80
+ def get_policy(text):
81
+ label_mapping = {'Wikipedia:Notability': 0,
82
+ 'Wikipedia:What Wikipedia is not': 1,
83
+ 'Wikipedia:Neutral point of view': 2,
84
+ 'Wikipedia:Verifiability': 3,
85
+ 'Wikipedia:Wikipedia is not a dictionary': 4,
86
+ 'Wikipedia:Wikipedia is not for things made up one day': 5,
87
+ 'Wikipedia:Criteria for speedy deletion': 6,
88
+ 'Wikipedia:Deletion policy': 7,
89
+ 'Wikipedia:No original research': 8,
90
+ 'Wikipedia:Biographies of living persons': 9,
91
+ 'Wikipedia:Arguments to avoid in deletion discussions': 10,
92
+ 'Wikipedia:Conflict of interest': 11,
93
+ 'Wikipedia:Articles for deletion': 12
94
+ }
95
 
96
+
97
+ seg = pysbd.Segmenter(language="en", clean=False)
98
+ text_list = seg.segment(text)
99
+ model = 'research-dump/bert-large-uncased_wikistance_policy_v1'
100
+ res_list = []
 
 
 
101
 
102
+ for t in text_list:
103
+ res = extract_response(t, model,label_mapping)
104
+ highest_key = max(res, key=res.get)
105
+ highest_score = res[highest_key]
106
+ result = {'sentence': t, 'policy': highest_key, 'score': highest_score}
107
+ res_list.append(result)
108
 
109
+ return res_list
110
+
111
+
112
+
113
+ #-----------------Sentiment Analysis-----------------
114
+
115
+ def extract_highest_score_label(res):
116
+ flat_res = [item for sublist in res for item in sublist]
117
+ highest_score_item = max(flat_res, key=lambda x: x['score'])
118
+ highest_score_label = highest_score_item['label']
119
+ highest_score_value = highest_score_item['score']
120
+ return highest_score_label, highest_score_value
121
+
122
+
123
+ def get_sentiment(text):
124
+ #sentiment analysis
125
+ model_name = "cardiffnlp/twitter-roberta-base-sentiment-latest"
126
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
127
+ model = pipeline("text-classification", model=model_name, top_k= None)
128
+
129
+ #sentence tokenize the text using pysbd
130
+ seg = pysbd.Segmenter(language="en", clean=False)
131
+ text_list = seg.segment(text)
132
+
133
+ res = []
134
+ for t in text_list:
135
+ results = model(t)
136
+ highest_label, highest_score = extract_highest_score_label(results)
137
+ result = {'sentence': t,'sentiment': highest_label, 'score': highest_score}
138
+ res.append(result)
139
+ return res
140
+
141
+
142
+ #-----------------Toxicity Prediction-----------------
143
+
144
+ def get_offensive_label(text):
145
+ #offensive language detection model
146
+ model_name = "cardiffnlp/twitter-roberta-base-offensive"
147
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
148
+ model = pipeline("text-classification", model=model_name, top_k= None)
149
+
150
+ #sentence tokenize the text using pysbd
151
+ seg = pysbd.Segmenter(language="en", clean=False)
152
+ text_list = seg.segment(text)
153
+
154
+ res = []
155
+ for t in text_list:
156
+ results = model(t)
157
+ highest_label, highest_score = extract_highest_score_label(results)
158
+ result = {'sentence': t,'offensive_label': highest_label, 'score': highest_score}
159
+ res.append(result)
160
+ return res
161
+
162
+
163
+ #create the anchor function
164
+ def predict_text(text, model_name):
165
+ if model_name == 'outcome':
166
+ return outcome(text)
167
+ elif model_name == 'stance':
168
+ return get_stance(text)
169
+ elif model_name == 'policy':
170
+ return get_policy(text)
171
+ elif model_name == 'sentiment':
172
+ return get_sentiment(text)
173
+ elif model_name == 'offensive':
174
+ return get_offensive_label(text)
175
+ else:
176
+ return "Invalid Task name"