humanizer-ai / app.py
conversantech's picture
Create app.py
f974a84 verified
raw
history blame
14.9 kB
import gradio as gr
import random
import re
import nltk
from nltk.tokenize import sent_tokenize, word_tokenize
from nltk.corpus import stopwords
from nltk.tag import pos_tag
import string
from textstat import flesch_reading_ease, flesch_kincaid_grade
import spacy
from transformers import pipeline, AutoTokenizer, AutoModelForSequenceClassification
import torch
# Download required NLTK data
try:
nltk.download('punkt', quiet=True)
nltk.download('averaged_perceptron_tagger', quiet=True)
nltk.download('stopwords', quiet=True)
nltk.download('wordnet', quiet=True)
except:
pass
class AIContentHumanizer:
def __init__(self):
self.setup_models()
self.setup_humanization_patterns()
def setup_models(self):
"""Initialize AI detection and paraphrasing models"""
try:
# Load spaCy model
self.nlp = spacy.load("en_core_web_sm")
except:
# Fallback if spaCy model not available
self.nlp = None
# Paraphrasing patterns and synonyms
self.synonyms = {
'however': ['but', 'yet', 'though', 'nevertheless', 'still'],
'therefore': ['so', 'thus', 'hence', 'as a result', 'consequently'],
'furthermore': ['also', 'moreover', 'additionally', 'besides', 'plus'],
'nevertheless': ['however', 'yet', 'still', 'but', 'though'],
'consequently': ['therefore', 'so', 'thus', 'as a result', 'hence'],
'significant': ['important', 'major', 'notable', 'considerable', 'substantial'],
'utilize': ['use', 'employ', 'apply', 'make use of', 'take advantage of'],
'demonstrate': ['show', 'prove', 'display', 'exhibit', 'reveal'],
'numerous': ['many', 'several', 'various', 'countless', 'multiple'],
'substantial': ['significant', 'considerable', 'large', 'major', 'important']
}
def setup_humanization_patterns(self):
"""Setup patterns for humanizing text"""
self.ai_phrases = [
r'\b(it is important to note that|it should be noted that|it is worth noting that)\b',
r'\b(in conclusion|to conclude|in summary|to summarize)\b',
r'\b(furthermore|moreover|additionally|in addition)\b',
r'\b(however|nevertheless|nonetheless|on the other hand)\b',
r'\b(therefore|consequently|as a result|thus)\b',
r'\b(various|numerous|several|multiple)\b',
r'\b(significant|substantial|considerable|notable)\b',
r'\b(utilize|implement|demonstrate|facilitate)\b'
]
self.human_replacements = {
'it is important to note that': ['worth mentioning', 'notably', 'interestingly'],
'it should be noted that': ['keep in mind', 'remember', 'note that'],
'furthermore': ['also', 'plus', 'what\'s more', 'on top of that'],
'moreover': ['also', 'besides', 'what\'s more', 'and'],
'however': ['but', 'though', 'yet', 'still'],
'therefore': ['so', 'that\'s why', 'which means'],
'consequently': ['so', 'as a result', 'that\'s why'],
'numerous': ['many', 'lots of', 'plenty of', 'tons of'],
'significant': ['big', 'major', 'important', 'key'],
'utilize': ['use', 'make use of', 'work with'],
'demonstrate': ['show', 'prove', 'make clear'],
'facilitate': ['help', 'make easier', 'enable']
}
self.contraction_map = {
'it is': 'it\'s', 'that is': 'that\'s', 'there is': 'there\'s',
'we are': 'we\'re', 'they are': 'they\'re', 'you are': 'you\'re',
'i am': 'I\'m', 'he is': 'he\'s', 'she is': 'she\'s',
'will not': 'won\'t', 'cannot': 'can\'t', 'do not': 'don\'t',
'does not': 'doesn\'t', 'did not': 'didn\'t', 'have not': 'haven\'t',
'has not': 'hasn\'t', 'had not': 'hadn\'t', 'would not': 'wouldn\'t',
'should not': 'shouldn\'t', 'could not': 'couldn\'t'
}
def add_human_errors(self, text):
"""Add subtle human-like imperfections"""
sentences = sent_tokenize(text)
humanized_sentences = []
for sentence in sentences:
# Occasionally add filler words
if random.random() < 0.3:
fillers = ['actually', 'basically', 'really', 'pretty much', 'kind of', 'sort of']
filler = random.choice(fillers)
words = sentence.split()
if len(words) > 3:
insert_pos = random.randint(1, min(3, len(words)-1))
words.insert(insert_pos, filler)
sentence = ' '.join(words)
# Occasionally use more casual phrasing
if random.random() < 0.2:
sentence = sentence.replace(' and ', ' & ')
humanized_sentences.append(sentence)
return ' '.join(humanized_sentences)
def vary_sentence_structure(self, text):
"""Vary sentence structures to appear more human"""
sentences = sent_tokenize(text)
varied_sentences = []
for i, sentence in enumerate(sentences):
# Randomly combine short sentences
if i < len(sentences) - 1 and len(sentence.split()) < 8 and len(sentences[i+1].split()) < 8:
if random.random() < 0.4:
connectors = [' and ', ', ', ' - ', ' but ']
connector = random.choice(connectors)
combined = sentence.rstrip('.') + connector + sentences[i+1].lower()
varied_sentences.append(combined)
sentences[i+1] = "" # Skip next sentence
continue
if sentence: # Only add non-empty sentences
varied_sentences.append(sentence)
return ' '.join(varied_sentences)
def replace_formal_words(self, text):
"""Replace formal words with casual alternatives"""
for formal, casual_options in self.human_replacements.items():
if formal in text.lower():
replacement = random.choice(casual_options)
text = re.sub(r'\b' + re.escape(formal) + r'\b', replacement, text, flags=re.IGNORECASE)
return text
def add_contractions(self, text):
"""Add contractions to make text more conversational"""
for full_form, contraction in self.contraction_map.items():
text = re.sub(r'\b' + re.escape(full_form) + r'\b', contraction, text, flags=re.IGNORECASE)
return text
def adjust_punctuation(self, text):
"""Adjust punctuation for more natural flow"""
# Replace some periods with commas for flow
sentences = sent_tokenize(text)
if len(sentences) > 2:
# Occasionally use semicolons
if random.random() < 0.3:
idx = random.randint(0, len(sentences)-2)
if len(sentences[idx].split()) > 6:
sentences[idx] = sentences[idx].rstrip('.') + ';'
sentences[idx+1] = sentences[idx+1][0].lower() + sentences[idx+1][1:]
return ' '.join(sentences)
def add_personal_touches(self, text):
"""Add personal touches and opinions"""
personal_phrases = [
"I think", "In my opinion", "From what I've seen", "Personally,",
"I believe", "It seems to me", "From my experience"
]
sentences = sent_tokenize(text)
if len(sentences) > 1 and random.random() < 0.4:
# Add personal phrase to a random sentence
idx = random.randint(0, len(sentences)-1)
personal_phrase = random.choice(personal_phrases)
sentences[idx] = personal_phrase + " " + sentences[idx].lower()
return ' '.join(sentences)
def paraphrase_with_synonyms(self, text):
"""Replace words with synonyms"""
words = word_tokenize(text)
new_words = []
for word in words:
lower_word = word.lower()
if lower_word in self.synonyms and random.random() < 0.3:
synonym = random.choice(self.synonyms[lower_word])
new_words.append(synonym)
else:
new_words.append(word)
return ' '.join(new_words)
def humanize_text(self, text, intensity="medium"):
"""Main humanization function"""
if not text or not text.strip():
return "Please provide text to humanize."
# Clean input
text = text.strip()
# Apply humanization techniques based on intensity
if intensity == "light":
text = self.add_contractions(text)
text = self.replace_formal_words(text)
elif intensity == "medium":
text = self.replace_formal_words(text)
text = self.add_contractions(text)
text = self.paraphrase_with_synonyms(text)
text = self.vary_sentence_structure(text)
else: # heavy
text = self.replace_formal_words(text)
text = self.add_contractions(text)
text = self.paraphrase_with_synonyms(text)
text = self.vary_sentence_structure(text)
text = self.add_human_errors(text)
text = self.adjust_punctuation(text)
text = self.add_personal_touches(text)
return text
def get_readability_score(self, text):
"""Calculate readability metrics"""
try:
flesch_score = flesch_reading_ease(text)
fk_grade = flesch_kincaid_grade(text)
if flesch_score >= 90:
level = "Very Easy"
elif flesch_score >= 80:
level = "Easy"
elif flesch_score >= 70:
level = "Fairly Easy"
elif flesch_score >= 60:
level = "Standard"
elif flesch_score >= 50:
level = "Fairly Difficult"
elif flesch_score >= 30:
level = "Difficult"
else:
level = "Very Difficult"
return f"Flesch Score: {flesch_score:.1f} ({level})\nGrade Level: {fk_grade:.1f}"
except:
return "Could not calculate readability"
def create_interface():
humanizer = AIContentHumanizer()
def process_text(input_text, intensity):
if not input_text:
return "Please enter some text to humanize.", ""
humanized = humanizer.humanize_text(input_text, intensity)
readability = humanizer.get_readability_score(humanized)
return humanized, readability
# Custom CSS for better UI
css = """
.gradio-container {
font-family: 'Inter', sans-serif;
}
.main-header {
text-align: center;
margin-bottom: 30px;
}
.feature-box {
border: 1px solid #e1e5e9;
border-radius: 8px;
padding: 15px;
margin: 10px 0;
background: #f8f9fa;
}
"""
with gr.Blocks(css=css, title="AI Content Humanizer") as interface:
gr.HTML("""
<div class="main-header">
<h1>πŸ€–βž‘οΈπŸ‘€ AI Content Humanizer</h1>
<p>Transform AI-generated content into natural, human-like text</p>
</div>
""")
with gr.Row():
with gr.Column(scale=2):
input_text = gr.Textbox(
label="πŸ“ Enter AI-generated text",
placeholder="Paste your AI-generated content here...",
lines=10,
max_lines=20
)
intensity = gr.Radio(
choices=["light", "medium", "heavy"],
value="medium",
label="πŸŽ›οΈ Humanization Intensity",
info="Light: Basic changes | Medium: Moderate restructuring | Heavy: Extensive humanization"
)
humanize_btn = gr.Button("✨ Humanize Text", variant="primary", size="lg")
with gr.Column(scale=2):
output_text = gr.Textbox(
label="βœ… Humanized Text",
lines=10,
max_lines=20,
interactive=False
)
readability_info = gr.Textbox(
label="πŸ“Š Readability Analysis",
lines=3,
interactive=False
)
gr.HTML("""
<div class="feature-box">
<h3>🎯 Features:</h3>
<ul>
<li><strong>Smart Paraphrasing:</strong> Replaces formal AI language with natural expressions</li>
<li><strong>Sentence Restructuring:</strong> Varies sentence patterns for human-like flow</li>
<li><strong>Casual Contractions:</strong> Adds natural contractions and informal language</li>
<li><strong>Personal Touch:</strong> Incorporates personal opinions and experiences</li>
<li><strong>Readability Analysis:</strong> Provides readability scores and grade levels</li>
</ul>
</div>
""")
# Example texts
examples = [
["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"],
["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"],
["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"]
]
gr.Examples(
examples=examples,
inputs=[input_text, intensity],
label="πŸ“š Try these examples:"
)
humanize_btn.click(
fn=process_text,
inputs=[input_text, intensity],
outputs=[output_text, readability_info]
)
return interface
if __name__ == "__main__":
interface = create_interface()
interface.launch()