mkmanish/truthmark-api
0
1# predictor.py2 3import numpy as np4from model_loader import infer, tokenizer, MAX_LENGTH5 6 7def compute_breakdown_scores(text):8 tokens = [t.lower() for t in text.split() if t.isalpha() or t.isalnum()]9 n = max(1, len(tokens))10 11 trigrams = [' '.join(tokens[i:i+3]) for i in range(max(0, n-2))]12 repetition = 1 - (len(set(trigrams)) / max(1, len(trigrams)))13 14 types = len(set(tokens))15 ttr = types / n16 vocab_richness = 1 - ttr17 18 sentences = [s.strip() for s in text.replace('?', '.').replace('!', '.').split('.') if s.strip()]19 if len(sentences) <= 1:20 synt_var = 0.021 else:22 lens = [len(s.split()) for s in sentences]23 synt_var = 1 - (np.std(lens) / (np.mean(lens) + 1e-6))24 25 return {26 "repetition": round(np.clip(repetition, 0, 1) * 100, 2),27 "vocab_richness": round(np.clip(vocab_richness, 0, 1) * 100, 2),28 "syntactic_variation": round(np.clip(synt_var, 0, 1) * 100, 2)29 }30 31def verdict_from_prob(prob):32 score = round(prob * 100, 2)33 if score >= 70:34 return score, "Likely AI-Generated", "High", "red"35 elif score >= 40:36 return score, "Mixed/Uncertain", "Medium", "yellow"37 else:38 return score, "Likely Human-Created", "Low", "green"39 40def analyze_text(text: str):41 enc = tokenizer(42 [text],43 padding="max_length",44 truncation=True,45 max_length=128,46 return_tensors="tf"47 )48 49 outputs = infer(50 input_ids=enc["input_ids"],51 attention_mask=enc["attention_mask"]52 )53 54 raw_output = float(outputs[list(outputs.keys())[0]][0][0])55 56 57 # Convert safely to float and clamp58 prob_ai = float(np.clip(raw_output, 0.0, 1.0))59 60 score, verdict, confidence, badge_color = verdict_from_prob(prob_ai)61 breakdown = compute_breakdown_scores(text)62 63 return {64 "overall_ai_score": score,65 "overall_human_score": round(100 - score, 2),66 "verdict": verdict,67 "confidence": confidence,68 "badge_color": badge_color,69 70 "breakdown": {71 "Perplexity_proxy_Repetition": breakdown["repetition"],72 "Vocabulary_Richness_proxy": breakdown["vocab_richness"],73 "Syntactic_Variation_proxy": breakdown["syntactic_variation"]74 },75 "model_note": "This result is based on a probabilistic AI-vs-human classifier trained on multiple datasets.",76 77 78 "limitations": [79 "This system cannot guarantee 100% accuracy and should not be used as the only source to judge content authenticity ",80 "Text written by humans with very formal or repetitive style may sometimes appear AI-generated.",81 "AI-generated text that is heavily edited by humans may not be detected correctly.",82 "This tool does not identify which AI tool was used, only the likelihood of AI involvement."83 ]84 }85 