Spaces:
Sleeping
Sleeping
hsuvaskakoty
commited on
Commit
•
cb58c8d
1
Parent(s):
d2324b7
Upload 2 files
Browse files- app.py +27 -13
- 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 |
-
"
|
7 |
-
"
|
8 |
-
"
|
9 |
-
"
|
|
|
10 |
}
|
11 |
|
12 |
-
def process_url(url,
|
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 |
-
|
21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
|
23 |
-
title = 'Wikipedia Deletion Discussion
|
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="
|
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
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
31 |
break
|
32 |
|
33 |
-
return
|
34 |
-
|
35 |
|
36 |
-
|
37 |
-
# import torch
|
38 |
|
39 |
-
|
40 |
-
|
41 |
-
|
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 |
-
|
51 |
-
|
52 |
-
# model = AutoModelForSequenceClassification.from_pretrained(model_name, output_attentions=True)
|
53 |
|
54 |
-
|
55 |
-
# outputs = model(**inputs)
|
56 |
-
# predictions = torch.nn.functional.softmax(outputs.logits, dim=-1)
|
57 |
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
# highlighted_text.append(f"<b>{token}</b>") #
|
77 |
-
# else:
|
78 |
-
# highlighted_text.append(token)
|
79 |
|
80 |
-
|
81 |
-
|
|
|
|
|
|
|
|
|
82 |
|
83 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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"
|