conversantech commited on
Commit
f974a84
Β·
verified Β·
1 Parent(s): 2958018

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +354 -0
app.py ADDED
@@ -0,0 +1,354 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import random
3
+ import re
4
+ import nltk
5
+ from nltk.tokenize import sent_tokenize, word_tokenize
6
+ from nltk.corpus import stopwords
7
+ from nltk.tag import pos_tag
8
+ import string
9
+ from textstat import flesch_reading_ease, flesch_kincaid_grade
10
+ import spacy
11
+ from transformers import pipeline, AutoTokenizer, AutoModelForSequenceClassification
12
+ import torch
13
+
14
+ # Download required NLTK data
15
+ try:
16
+ nltk.download('punkt', quiet=True)
17
+ nltk.download('averaged_perceptron_tagger', quiet=True)
18
+ nltk.download('stopwords', quiet=True)
19
+ nltk.download('wordnet', quiet=True)
20
+ except:
21
+ pass
22
+
23
+ class AIContentHumanizer:
24
+ def __init__(self):
25
+ self.setup_models()
26
+ self.setup_humanization_patterns()
27
+
28
+ def setup_models(self):
29
+ """Initialize AI detection and paraphrasing models"""
30
+ try:
31
+ # Load spaCy model
32
+ self.nlp = spacy.load("en_core_web_sm")
33
+ except:
34
+ # Fallback if spaCy model not available
35
+ self.nlp = None
36
+
37
+ # Paraphrasing patterns and synonyms
38
+ self.synonyms = {
39
+ 'however': ['but', 'yet', 'though', 'nevertheless', 'still'],
40
+ 'therefore': ['so', 'thus', 'hence', 'as a result', 'consequently'],
41
+ 'furthermore': ['also', 'moreover', 'additionally', 'besides', 'plus'],
42
+ 'nevertheless': ['however', 'yet', 'still', 'but', 'though'],
43
+ 'consequently': ['therefore', 'so', 'thus', 'as a result', 'hence'],
44
+ 'significant': ['important', 'major', 'notable', 'considerable', 'substantial'],
45
+ 'utilize': ['use', 'employ', 'apply', 'make use of', 'take advantage of'],
46
+ 'demonstrate': ['show', 'prove', 'display', 'exhibit', 'reveal'],
47
+ 'numerous': ['many', 'several', 'various', 'countless', 'multiple'],
48
+ 'substantial': ['significant', 'considerable', 'large', 'major', 'important']
49
+ }
50
+
51
+ def setup_humanization_patterns(self):
52
+ """Setup patterns for humanizing text"""
53
+ self.ai_phrases = [
54
+ r'\b(it is important to note that|it should be noted that|it is worth noting that)\b',
55
+ r'\b(in conclusion|to conclude|in summary|to summarize)\b',
56
+ r'\b(furthermore|moreover|additionally|in addition)\b',
57
+ r'\b(however|nevertheless|nonetheless|on the other hand)\b',
58
+ r'\b(therefore|consequently|as a result|thus)\b',
59
+ r'\b(various|numerous|several|multiple)\b',
60
+ r'\b(significant|substantial|considerable|notable)\b',
61
+ r'\b(utilize|implement|demonstrate|facilitate)\b'
62
+ ]
63
+
64
+ self.human_replacements = {
65
+ 'it is important to note that': ['worth mentioning', 'notably', 'interestingly'],
66
+ 'it should be noted that': ['keep in mind', 'remember', 'note that'],
67
+ 'furthermore': ['also', 'plus', 'what\'s more', 'on top of that'],
68
+ 'moreover': ['also', 'besides', 'what\'s more', 'and'],
69
+ 'however': ['but', 'though', 'yet', 'still'],
70
+ 'therefore': ['so', 'that\'s why', 'which means'],
71
+ 'consequently': ['so', 'as a result', 'that\'s why'],
72
+ 'numerous': ['many', 'lots of', 'plenty of', 'tons of'],
73
+ 'significant': ['big', 'major', 'important', 'key'],
74
+ 'utilize': ['use', 'make use of', 'work with'],
75
+ 'demonstrate': ['show', 'prove', 'make clear'],
76
+ 'facilitate': ['help', 'make easier', 'enable']
77
+ }
78
+
79
+ self.contraction_map = {
80
+ 'it is': 'it\'s', 'that is': 'that\'s', 'there is': 'there\'s',
81
+ 'we are': 'we\'re', 'they are': 'they\'re', 'you are': 'you\'re',
82
+ 'i am': 'I\'m', 'he is': 'he\'s', 'she is': 'she\'s',
83
+ 'will not': 'won\'t', 'cannot': 'can\'t', 'do not': 'don\'t',
84
+ 'does not': 'doesn\'t', 'did not': 'didn\'t', 'have not': 'haven\'t',
85
+ 'has not': 'hasn\'t', 'had not': 'hadn\'t', 'would not': 'wouldn\'t',
86
+ 'should not': 'shouldn\'t', 'could not': 'couldn\'t'
87
+ }
88
+
89
+ def add_human_errors(self, text):
90
+ """Add subtle human-like imperfections"""
91
+ sentences = sent_tokenize(text)
92
+ humanized_sentences = []
93
+
94
+ for sentence in sentences:
95
+ # Occasionally add filler words
96
+ if random.random() < 0.3:
97
+ fillers = ['actually', 'basically', 'really', 'pretty much', 'kind of', 'sort of']
98
+ filler = random.choice(fillers)
99
+ words = sentence.split()
100
+ if len(words) > 3:
101
+ insert_pos = random.randint(1, min(3, len(words)-1))
102
+ words.insert(insert_pos, filler)
103
+ sentence = ' '.join(words)
104
+
105
+ # Occasionally use more casual phrasing
106
+ if random.random() < 0.2:
107
+ sentence = sentence.replace(' and ', ' & ')
108
+
109
+ humanized_sentences.append(sentence)
110
+
111
+ return ' '.join(humanized_sentences)
112
+
113
+ def vary_sentence_structure(self, text):
114
+ """Vary sentence structures to appear more human"""
115
+ sentences = sent_tokenize(text)
116
+ varied_sentences = []
117
+
118
+ for i, sentence in enumerate(sentences):
119
+ # Randomly combine short sentences
120
+ if i < len(sentences) - 1 and len(sentence.split()) < 8 and len(sentences[i+1].split()) < 8:
121
+ if random.random() < 0.4:
122
+ connectors = [' and ', ', ', ' - ', ' but ']
123
+ connector = random.choice(connectors)
124
+ combined = sentence.rstrip('.') + connector + sentences[i+1].lower()
125
+ varied_sentences.append(combined)
126
+ sentences[i+1] = "" # Skip next sentence
127
+ continue
128
+
129
+ if sentence: # Only add non-empty sentences
130
+ varied_sentences.append(sentence)
131
+
132
+ return ' '.join(varied_sentences)
133
+
134
+ def replace_formal_words(self, text):
135
+ """Replace formal words with casual alternatives"""
136
+ for formal, casual_options in self.human_replacements.items():
137
+ if formal in text.lower():
138
+ replacement = random.choice(casual_options)
139
+ text = re.sub(r'\b' + re.escape(formal) + r'\b', replacement, text, flags=re.IGNORECASE)
140
+
141
+ return text
142
+
143
+ def add_contractions(self, text):
144
+ """Add contractions to make text more conversational"""
145
+ for full_form, contraction in self.contraction_map.items():
146
+ text = re.sub(r'\b' + re.escape(full_form) + r'\b', contraction, text, flags=re.IGNORECASE)
147
+
148
+ return text
149
+
150
+ def adjust_punctuation(self, text):
151
+ """Adjust punctuation for more natural flow"""
152
+ # Replace some periods with commas for flow
153
+ sentences = sent_tokenize(text)
154
+ if len(sentences) > 2:
155
+ # Occasionally use semicolons
156
+ if random.random() < 0.3:
157
+ idx = random.randint(0, len(sentences)-2)
158
+ if len(sentences[idx].split()) > 6:
159
+ sentences[idx] = sentences[idx].rstrip('.') + ';'
160
+ sentences[idx+1] = sentences[idx+1][0].lower() + sentences[idx+1][1:]
161
+
162
+ return ' '.join(sentences)
163
+
164
+ def add_personal_touches(self, text):
165
+ """Add personal touches and opinions"""
166
+ personal_phrases = [
167
+ "I think", "In my opinion", "From what I've seen", "Personally,",
168
+ "I believe", "It seems to me", "From my experience"
169
+ ]
170
+
171
+ sentences = sent_tokenize(text)
172
+ if len(sentences) > 1 and random.random() < 0.4:
173
+ # Add personal phrase to a random sentence
174
+ idx = random.randint(0, len(sentences)-1)
175
+ personal_phrase = random.choice(personal_phrases)
176
+ sentences[idx] = personal_phrase + " " + sentences[idx].lower()
177
+
178
+ return ' '.join(sentences)
179
+
180
+ def paraphrase_with_synonyms(self, text):
181
+ """Replace words with synonyms"""
182
+ words = word_tokenize(text)
183
+ new_words = []
184
+
185
+ for word in words:
186
+ lower_word = word.lower()
187
+ if lower_word in self.synonyms and random.random() < 0.3:
188
+ synonym = random.choice(self.synonyms[lower_word])
189
+ new_words.append(synonym)
190
+ else:
191
+ new_words.append(word)
192
+
193
+ return ' '.join(new_words)
194
+
195
+ def humanize_text(self, text, intensity="medium"):
196
+ """Main humanization function"""
197
+ if not text or not text.strip():
198
+ return "Please provide text to humanize."
199
+
200
+ # Clean input
201
+ text = text.strip()
202
+
203
+ # Apply humanization techniques based on intensity
204
+ if intensity == "light":
205
+ text = self.add_contractions(text)
206
+ text = self.replace_formal_words(text)
207
+ elif intensity == "medium":
208
+ text = self.replace_formal_words(text)
209
+ text = self.add_contractions(text)
210
+ text = self.paraphrase_with_synonyms(text)
211
+ text = self.vary_sentence_structure(text)
212
+ else: # heavy
213
+ text = self.replace_formal_words(text)
214
+ text = self.add_contractions(text)
215
+ text = self.paraphrase_with_synonyms(text)
216
+ text = self.vary_sentence_structure(text)
217
+ text = self.add_human_errors(text)
218
+ text = self.adjust_punctuation(text)
219
+ text = self.add_personal_touches(text)
220
+
221
+ return text
222
+
223
+ def get_readability_score(self, text):
224
+ """Calculate readability metrics"""
225
+ try:
226
+ flesch_score = flesch_reading_ease(text)
227
+ fk_grade = flesch_kincaid_grade(text)
228
+
229
+ if flesch_score >= 90:
230
+ level = "Very Easy"
231
+ elif flesch_score >= 80:
232
+ level = "Easy"
233
+ elif flesch_score >= 70:
234
+ level = "Fairly Easy"
235
+ elif flesch_score >= 60:
236
+ level = "Standard"
237
+ elif flesch_score >= 50:
238
+ level = "Fairly Difficult"
239
+ elif flesch_score >= 30:
240
+ level = "Difficult"
241
+ else:
242
+ level = "Very Difficult"
243
+
244
+ return f"Flesch Score: {flesch_score:.1f} ({level})\nGrade Level: {fk_grade:.1f}"
245
+ except:
246
+ return "Could not calculate readability"
247
+
248
+ def create_interface():
249
+ humanizer = AIContentHumanizer()
250
+
251
+ def process_text(input_text, intensity):
252
+ if not input_text:
253
+ return "Please enter some text to humanize.", ""
254
+
255
+ humanized = humanizer.humanize_text(input_text, intensity)
256
+ readability = humanizer.get_readability_score(humanized)
257
+
258
+ return humanized, readability
259
+
260
+ # Custom CSS for better UI
261
+ css = """
262
+ .gradio-container {
263
+ font-family: 'Inter', sans-serif;
264
+ }
265
+ .main-header {
266
+ text-align: center;
267
+ margin-bottom: 30px;
268
+ }
269
+ .feature-box {
270
+ border: 1px solid #e1e5e9;
271
+ border-radius: 8px;
272
+ padding: 15px;
273
+ margin: 10px 0;
274
+ background: #f8f9fa;
275
+ }
276
+ """
277
+
278
+ with gr.Blocks(css=css, title="AI Content Humanizer") as interface:
279
+ gr.HTML("""
280
+ <div class="main-header">
281
+ <h1>πŸ€–βž‘οΈπŸ‘€ AI Content Humanizer</h1>
282
+ <p>Transform AI-generated content into natural, human-like text</p>
283
+ </div>
284
+ """)
285
+
286
+ with gr.Row():
287
+ with gr.Column(scale=2):
288
+ input_text = gr.Textbox(
289
+ label="πŸ“ Enter AI-generated text",
290
+ placeholder="Paste your AI-generated content here...",
291
+ lines=10,
292
+ max_lines=20
293
+ )
294
+
295
+ intensity = gr.Radio(
296
+ choices=["light", "medium", "heavy"],
297
+ value="medium",
298
+ label="πŸŽ›οΈ Humanization Intensity",
299
+ info="Light: Basic changes | Medium: Moderate restructuring | Heavy: Extensive humanization"
300
+ )
301
+
302
+ humanize_btn = gr.Button("✨ Humanize Text", variant="primary", size="lg")
303
+
304
+ with gr.Column(scale=2):
305
+ output_text = gr.Textbox(
306
+ label="βœ… Humanized Text",
307
+ lines=10,
308
+ max_lines=20,
309
+ interactive=False
310
+ )
311
+
312
+ readability_info = gr.Textbox(
313
+ label="πŸ“Š Readability Analysis",
314
+ lines=3,
315
+ interactive=False
316
+ )
317
+
318
+ gr.HTML("""
319
+ <div class="feature-box">
320
+ <h3>🎯 Features:</h3>
321
+ <ul>
322
+ <li><strong>Smart Paraphrasing:</strong> Replaces formal AI language with natural expressions</li>
323
+ <li><strong>Sentence Restructuring:</strong> Varies sentence patterns for human-like flow</li>
324
+ <li><strong>Casual Contractions:</strong> Adds natural contractions and informal language</li>
325
+ <li><strong>Personal Touch:</strong> Incorporates personal opinions and experiences</li>
326
+ <li><strong>Readability Analysis:</strong> Provides readability scores and grade levels</li>
327
+ </ul>
328
+ </div>
329
+ """)
330
+
331
+ # Example texts
332
+ examples = [
333
+ ["Artificial intelligence has numerous applications in various industries. It is important to note that AI can significantly enhance productivity and efficiency. Furthermore, machine learning algorithms can process vast amounts of data to generate valuable insights.", "medium"],
334
+ ["The implementation of sustainable practices is crucial for environmental conservation. Organizations must utilize innovative technologies to facilitate eco-friendly operations. Moreover, it is essential to demonstrate commitment to reducing carbon footprint.", "heavy"],
335
+ ["In conclusion, the research demonstrates that renewable energy sources are becoming increasingly viable. Therefore, governments should implement policies that promote clean energy adoption. It is worth noting that this transition requires substantial investment.", "light"]
336
+ ]
337
+
338
+ gr.Examples(
339
+ examples=examples,
340
+ inputs=[input_text, intensity],
341
+ label="πŸ“š Try these examples:"
342
+ )
343
+
344
+ humanize_btn.click(
345
+ fn=process_text,
346
+ inputs=[input_text, intensity],
347
+ outputs=[output_text, readability_info]
348
+ )
349
+
350
+ return interface
351
+
352
+ if __name__ == "__main__":
353
+ interface = create_interface()
354
+ interface.launch()