sashtech commited on
Commit
bf4908b
·
verified ·
1 Parent(s): 5de59e7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +201 -73
app.py CHANGED
@@ -5,36 +5,32 @@ import spacy
5
  import subprocess
6
  import nltk
7
  from nltk.corpus import wordnet
8
- from gramformer import Gramformer
 
9
 
10
  # Initialize the English text classification pipeline for AI detection
11
  pipeline_en = pipeline(task="text-classification", model="Hello-SimpleAI/chatgpt-detector-roberta")
12
 
13
- # Function to predict the label and score for English text (AI Detection)
14
- def predict_en(text):
15
- res = pipeline_en(text)[0]
16
- return res['label'], res['score']
17
 
18
- # Ensure necessary NLTK data is downloaded for Humanifier
19
  nltk.download('wordnet')
20
  nltk.download('omw-1.4')
21
 
22
- # Ensure the SpaCy model is installed for Humanifier
23
  try:
24
  nlp = spacy.load("en_core_web_sm")
25
  except OSError:
26
  subprocess.run(["python", "-m", "spacy", "download", "en_core_web_sm"])
27
  nlp = spacy.load("en_core_web_sm")
28
 
29
- # Initialize Gramformer for grammar correction
30
- gf = Gramformer(models=1, use_gpu=False) # You can set use_gpu=True if running on a machine with a GPU
31
-
32
- # Function to correct grammar using Gramformer
33
- def correct_grammar(text):
34
- corrections = gf.correct(text)
35
- return ' '.join(corrections)
36
 
37
- # Function to get synonyms using NLTK WordNet (Humanifier)
38
  def get_synonyms_nltk(word, pos):
39
  synsets = wordnet.synsets(word, pos=pos)
40
  if synsets:
@@ -42,7 +38,14 @@ def get_synonyms_nltk(word, pos):
42
  return [lemma.name() for lemma in lemmas]
43
  return []
44
 
45
- # Function to capitalize the first letter of sentences and proper nouns (Humanifier)
 
 
 
 
 
 
 
46
  def capitalize_sentences_and_nouns(text):
47
  doc = nlp(text)
48
  corrected_text = []
@@ -60,75 +63,200 @@ def capitalize_sentences_and_nouns(text):
60
 
61
  return ' '.join(corrected_text)
62
 
63
- # Paraphrasing function using SpaCy and NLTK (Humanifier)
64
- def paraphrase_with_spacy_nltk(text):
 
 
 
 
 
 
65
  doc = nlp(text)
66
- paraphrased_words = []
 
 
 
 
 
 
 
 
 
 
 
 
67
 
68
  for token in doc:
69
- # Map SpaCy POS tags to WordNet POS tags
70
- pos = None
71
- if token.pos_ in {"NOUN"}:
72
- pos = wordnet.NOUN
73
- elif token.pos_ in {"VERB"}:
74
- pos = wordnet.VERB
75
- elif token.pos_ in {"ADJ"}:
76
- pos = wordnet.ADJ
77
- elif token.pos_ in {"ADV"}:
78
- pos = wordnet.ADV
79
-
80
- synonyms = get_synonyms_nltk(token.text.lower(), pos) if pos else []
81
-
82
- # Replace with a synonym only if it makes sense
83
- if synonyms and token.pos_ in {"NOUN", "VERB", "ADJ", "ADV"} and synonyms[0] != token.text.lower():
84
- paraphrased_words.append(synonyms[0])
85
  else:
86
- paraphrased_words.append(token.text)
87
 
88
- # Join the words back into a sentence
89
- paraphrased_sentence = ' '.join(paraphrased_words)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
- # Capitalize sentences and proper nouns
92
- corrected_text = capitalize_sentences_and_nouns(paraphrased_sentence)
93
 
94
- return corrected_text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
 
96
- # Combined function: Paraphrase -> Capitalization (Humanifier)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  def paraphrase_and_correct(text):
98
- # Step 1: Paraphrase the text
99
- paraphrased_text = paraphrase_with_spacy_nltk(text)
100
 
101
- # Step 2: Capitalize sentences and proper nouns
102
- final_text = capitalize_sentences_and_nouns(paraphrased_text)
103
-
104
- return final_text
105
 
106
- # Gradio app setup with three tabs
107
- with gr.Blocks() as demo:
108
- with gr.Tab("AI Detection"):
109
- t1 = gr.Textbox(lines=5, label='Text')
110
- button1 = gr.Button("🤖 Predict!")
111
- label1 = gr.Textbox(lines=1, label='Predicted Label 🎃')
112
- score1 = gr.Textbox(lines=1, label='Prob')
113
 
114
- # Connect the prediction function to the button
115
- button1.click(predict_en, inputs=[t1], outputs=[label1, score1], api_name='predict_en')
116
-
117
- with gr.Tab("Humanifier"):
118
- text_input = gr.Textbox(lines=5, label="Input Text")
119
- paraphrase_button = gr.Button("Paraphrase & Correct")
120
- output_text = gr.Textbox(label="Paraphrased Text")
121
 
122
- # Connect the paraphrasing function to the button
123
- paraphrase_button.click(paraphrase_and_correct, inputs=text_input, outputs=output_text)
124
-
125
- with gr.Tab("Grammar Correction"):
126
- grammar_input = gr.Textbox(lines=5, label="Input Text")
127
- grammar_button = gr.Button("Correct Grammar")
128
- grammar_output = gr.Textbox(label="Corrected Text")
129
 
130
- # Connect the grammar correction function to the button
131
- grammar_button.click(correct_grammar, inputs=grammar_input, outputs=grammar_output)
 
 
 
 
 
 
132
 
133
- # Launch the app with all functionalities
134
- demo.launch()
 
5
  import subprocess
6
  import nltk
7
  from nltk.corpus import wordnet
8
+ from spellchecker import SpellChecker
9
+ import re
10
 
11
  # Initialize the English text classification pipeline for AI detection
12
  pipeline_en = pipeline(task="text-classification", model="Hello-SimpleAI/chatgpt-detector-roberta")
13
 
14
+ # Initialize the spell checker
15
+ spell = SpellChecker()
 
 
16
 
17
+ # Ensure necessary NLTK data is downloaded
18
  nltk.download('wordnet')
19
  nltk.download('omw-1.4')
20
 
21
+ # Ensure the SpaCy model is installed
22
  try:
23
  nlp = spacy.load("en_core_web_sm")
24
  except OSError:
25
  subprocess.run(["python", "-m", "spacy", "download", "en_core_web_sm"])
26
  nlp = spacy.load("en_core_web_sm")
27
 
28
+ # Function to predict the label and score for English text (AI Detection)
29
+ def predict_en(text):
30
+ res = pipeline_en(text)[0]
31
+ return res['label'], res['score']
 
 
 
32
 
33
+ # Function to get synonyms using NLTK WordNet
34
  def get_synonyms_nltk(word, pos):
35
  synsets = wordnet.synsets(word, pos=pos)
36
  if synsets:
 
38
  return [lemma.name() for lemma in lemmas]
39
  return []
40
 
41
+ # Function to remove redundant and meaningless words
42
+ def remove_redundant_words(text):
43
+ doc = nlp(text)
44
+ meaningless_words = {"actually", "basically", "literally", "really", "very", "just"}
45
+ filtered_text = [token.text for token in doc if token.text.lower() not in meaningless_words]
46
+ return ' '.join(filtered_text)
47
+
48
+ # Function to capitalize the first letter of sentences and proper nouns
49
  def capitalize_sentences_and_nouns(text):
50
  doc = nlp(text)
51
  corrected_text = []
 
63
 
64
  return ' '.join(corrected_text)
65
 
66
+ # Function to force capitalization of the first letter of every sentence
67
+ def force_first_letter_capital(text):
68
+ sentences = text.split(". ") # Split by period to get each sentence
69
+ capitalized_sentences = [sentence[0].capitalize() + sentence[1:] if sentence else "" for sentence in sentences]
70
+ return ". ".join(capitalized_sentences)
71
+
72
+ # Function to correct tense errors in a sentence
73
+ def correct_tense_errors(text):
74
  doc = nlp(text)
75
+ corrected_text = []
76
+ for token in doc:
77
+ if token.pos_ == "VERB" and token.dep_ in {"aux", "auxpass"}:
78
+ lemma = wordnet.morphy(token.text, wordnet.VERB) or token.text
79
+ corrected_text.append(lemma)
80
+ else:
81
+ corrected_text.append(token.text)
82
+ return ' '.join(corrected_text)
83
+
84
+ # Function to correct singular/plural errors
85
+ def correct_singular_plural_errors(text):
86
+ doc = nlp(text)
87
+ corrected_text = []
88
 
89
  for token in doc:
90
+ if token.pos_ == "NOUN":
91
+ if token.tag_ == "NN": # Singular noun
92
+ if any(child.text.lower() in ['many', 'several', 'few'] for child in token.head.children):
93
+ corrected_text.append(token.lemma_ + 's')
94
+ else:
95
+ corrected_text.append(token.text)
96
+ elif token.tag_ == "NNS": # Plural noun
97
+ if any(child.text.lower() in ['a', 'one'] for child in token.head.children):
98
+ corrected_text.append(token.lemma_)
99
+ else:
100
+ corrected_text.append(token.text)
 
 
 
 
 
101
  else:
102
+ corrected_text.append(token.text)
103
 
104
+ return ' '.join(corrected_text)
105
+
106
+ # Function to check and correct article errors
107
+ def correct_article_errors(text):
108
+ doc = nlp(text)
109
+ corrected_text = []
110
+ for token in doc:
111
+ if token.text in ['a', 'an']:
112
+ next_token = token.nbor(1)
113
+ if token.text == "a" and next_token.text[0].lower() in "aeiou":
114
+ corrected_text.append("an")
115
+ elif token.text == "an" and next_token.text[0].lower() not in "aeiou":
116
+ corrected_text.append("a")
117
+ else:
118
+ corrected_text.append(token.text)
119
+ else:
120
+ corrected_text.append(token.text)
121
+ return ' '.join(corrected_text)
122
+
123
+ # Function to get the correct synonym while maintaining verb form
124
+ def replace_with_synonym(token):
125
+ pos = None
126
+ if token.pos_ == "VERB":
127
+ pos = wordnet.VERB
128
+ elif token.pos_ == "NOUN":
129
+ pos = wordnet.NOUN
130
+ elif token.pos_ == "ADJ":
131
+ pos = wordnet.ADJ
132
+ elif token.pos_ == "ADV":
133
+ pos = wordnet.ADV
134
 
135
+ synonyms = get_synonyms_nltk(token.lemma_, pos)
 
136
 
137
+ if synonyms:
138
+ synonym = synonyms[0]
139
+ if token.tag_ == "VBG": # Present participle
140
+ synonym += 'ing'
141
+ elif token.tag_ == "VBD" or token.tag_ == "VBN": # Past tense or past participle
142
+ synonym += 'ed'
143
+ elif token.tag_ == "VBZ": # Third-person singular present
144
+ synonym += 's'
145
+ return synonym
146
+ return token.text
147
+
148
+ # Function to check for and avoid double negatives
149
+ def correct_double_negatives(text):
150
+ doc = nlp(text)
151
+ corrected_text = []
152
+ for token in doc:
153
+ if token.text.lower() == "not" and any(child.text.lower() == "never" for child in token.head.children):
154
+ corrected_text.append("always")
155
+ else:
156
+ corrected_text.append(token.text)
157
+ return ' '.join(corrected_text)
158
 
159
+ # Function to ensure subject-verb agreement
160
+ def ensure_subject_verb_agreement(text):
161
+ doc = nlp(text)
162
+ corrected_text = []
163
+ for token in doc:
164
+ if token.dep_ == "nsubj" and token.head.pos_ == "VERB":
165
+ if token.tag_ == "NN" and token.head.tag_ != "VBZ": # Singular noun, should use singular verb
166
+ corrected_text.append(token.head.lemma_ + "s")
167
+ elif token.tag_ == "NNS" and token.head.tag_ == "VBZ": # Plural noun, should not use singular verb
168
+ corrected_text.append(token.head.lemma_)
169
+ corrected_text.append(token.text)
170
+ return ' '.join(corrected_text)
171
+
172
+ # Function to correct spelling errors
173
+ def correct_spelling(text):
174
+ words = text.split()
175
+ corrected_words = []
176
+ for word in words:
177
+ corrected_word = spell.correction(word)
178
+ corrected_words.append(corrected_word if corrected_word else word)
179
+ return ' '.join(corrected_words)
180
+
181
+ # Function to correct punctuation issues
182
+ def correct_punctuation(text):
183
+ # Fix spacing before punctuation
184
+ text = re.sub(r'\s([?.!,";:])', r'\1', text)
185
+ # Add missing commas in compound sentences
186
+ text = re.sub(r'(\w+)\s+and\s+(\w+)', r'\1, and \2', text)
187
+ return text
188
+
189
+ # Function to rephrase text and replace words with their synonyms while maintaining form
190
+ def rephrase_with_synonyms(text):
191
+ doc = nlp(text)
192
+ rephrased_text = []
193
+
194
+ for token in doc:
195
+ pos_tag = None
196
+ if token.pos_ == "NOUN":
197
+ pos_tag = wordnet.NOUN
198
+ elif token.pos_ == "VERB":
199
+ pos_tag = wordnet.VERB
200
+ elif token.pos_ == "ADJ":
201
+ pos_tag = wordnet.ADJ
202
+ elif token.pos_ == "ADV":
203
+ pos_tag = wordnet.ADV
204
+
205
+ if pos_tag:
206
+ synonyms = get_synonyms_nltk(token.text, pos_tag)
207
+ if synonyms:
208
+ synonym = synonyms[0] # Just using the first synonym for simplicity
209
+ if token.pos_ == "VERB":
210
+ if token.tag_ == "VBG": # Present participle
211
+ synonym += 'ing'
212
+ elif token.tag_ == "VBD" or token.tag_ == "VBN": # Past tense or past participle
213
+ synonym += 'ed'
214
+ elif token.tag_ == "VBZ": # Third-person singular present
215
+ synonym += 's'
216
+ elif token.pos_ == "NOUN" and token.tag_ == "NNS": # Plural nouns
217
+ synonym += 's' if not synonym.endswith('s') else ""
218
+ rephrased_text.append(synonym)
219
+ else:
220
+ rephrased_text.append(token.text)
221
+ else:
222
+ rephrased_text.append(token.text)
223
+
224
+ return ' '.join(rephrased_text)
225
+
226
+ # Function to paraphrase and correct grammar with enhanced accuracy
227
  def paraphrase_and_correct(text):
228
+ # Remove meaningless or redundant words first
229
+ cleaned_text = remove_redundant_words(text)
230
 
231
+ # Capitalize sentences and nouns
232
+ paraphrased_text = capitalize_sentences_and_nouns(cleaned_text)
 
 
233
 
234
+ # Correct tense and singular/plural errors
235
+ paraphrased_text = correct_tense_errors(paraphrased_text)
236
+ paraphrased_text = correct_singular_plural_errors(paraphrased_text)
237
+ paraphrased_text = correct_article_errors(paraphrased_text)
238
+ paraphrased_text = correct_double_negatives(paraphrased_text)
239
+ paraphrased_text = ensure_subject_verb_agreement(paraphrased_text)
 
240
 
241
+ # Correct spelling and punctuation
242
+ paraphrased_text = correct_spelling(paraphrased_text)
243
+ paraphrased_text = correct_punctuation(paraphrased_text)
 
 
 
 
244
 
245
+ # Rephrase with synonyms
246
+ paraphrased_text = rephrase_with_synonyms(paraphrased_text)
247
+
248
+ # Force capitalization of the first letter of each sentence
249
+ final_text = force_first_letter_capital(paraphrased_text)
250
+
251
+ return final_text
252
 
253
+ # Gradio interface
254
+ iface = gr.Interface(
255
+ fn=paraphrase_and_correct,
256
+ inputs=gr.Textbox(label="Input Text", lines=5, placeholder="Enter text here..."),
257
+ outputs=gr.Textbox(label="Output Text", lines=5),
258
+ title="Text Paraphraser and Grammar Corrector",
259
+ description="This tool paraphrases the input text, corrects grammar, improves punctuation, and enhances overall clarity."
260
+ )
261
 
262
+ iface.launch()