mahmoudsaber0 commited on
Commit
2af06ff
·
verified ·
1 Parent(s): 2debab9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +56 -13
app.py CHANGED
@@ -365,6 +365,7 @@ def split_content_in_half(text: str) -> tuple:
365
  def analyze_content_halves(model_manager, text: str, overall_result: Dict = None) -> Dict:
366
  """
367
  Analyze text by splitting it into two halves after cleaning
 
368
 
369
  Args:
370
  model_manager: The ModelManager instance
@@ -387,11 +388,13 @@ def analyze_content_halves(model_manager, text: str, overall_result: Dict = None
387
  # Split into halves
388
  first_half, second_half = split_content_in_half(cleaned_text)
389
 
390
- # Analyze first half
 
391
  first_half_result = model_manager.classify_text(first_half)
392
  first_half_words = len(first_half.split())
393
 
394
- # Analyze second half
 
395
  second_half_result = model_manager.classify_text(second_half)
396
  second_half_words = len(second_half.split())
397
 
@@ -401,6 +404,10 @@ def analyze_content_halves(model_manager, text: str, overall_result: Dict = None
401
  first_model = first_half_result["predicted_model"]
402
  second_model = second_half_result["predicted_model"]
403
 
 
 
 
 
404
  # Calculate average AI score from both halves
405
  avg_halves_ai_score = (first_ai + second_ai) / 2
406
 
@@ -410,6 +417,16 @@ def analyze_content_halves(model_manager, text: str, overall_result: Dict = None
410
  # Overall AI probability (use overall_result if provided, otherwise calculate)
411
  overall_ai_prob = overall_result["ai_percentage"] / 100 if overall_result else avg_halves_ai_score / 100
412
 
 
 
 
 
 
 
 
 
 
 
413
  # ===== FINAL DECISION LOGIC =====
414
  verdict = None
415
  confidence = None
@@ -420,17 +437,19 @@ def analyze_content_halves(model_manager, text: str, overall_result: Dict = None
420
  verdict = "HUMAN"
421
  confidence = "High" if variance_between_halves < 15 else "Medium"
422
  reasoning = (
423
- f"Both halves scored below 50% AI probability (First: {first_ai}%, Second: {second_ai}%). "
 
424
  f"The second half was classified as human-written. "
425
  f"Variance between halves is {variance_between_halves:.2f}%, indicating "
426
- f"{'consistent human patterns' if variance_between_halves < 15 else 'some variation but still human-like'}."
 
427
  )
428
 
429
  # Condition 2: Both halves > 50% AI AND second_half predicted_model is NOT "human"
430
  elif first_ai > 50 and second_ai > 50 and second_model.lower() != "human":
431
  verdict = "AI"
432
 
433
- # Determine confidence based on scores
434
  if first_ai > 80 and second_ai > 80:
435
  confidence = "Very High"
436
  elif first_ai > 70 and second_ai > 70:
@@ -438,11 +457,21 @@ def analyze_content_halves(model_manager, text: str, overall_result: Dict = None
438
  else:
439
  confidence = "Medium"
440
 
 
 
 
 
 
 
 
441
  reasoning = (
442
- f"Both halves scored above 50% AI probability (First: {first_ai}%, Second: {second_ai}%). "
 
443
  f"The pattern matches {second_model} outputs. "
 
444
  f"Variance between halves is {variance_between_halves:.2f}%, "
445
- f"{'showing consistent AI patterns throughout' if variance_between_halves < 20 else 'with some variation in AI generation style'}."
 
446
  )
447
 
448
  # Condition 3: Mixed results - one half AI, one half human
@@ -450,7 +479,8 @@ def analyze_content_halves(model_manager, text: str, overall_result: Dict = None
450
  verdict = "MIXED"
451
  confidence = "Low"
452
  reasoning = (
453
- f"Mixed signals detected. First half: {first_ai}% AI, Second half: {second_ai}% AI. "
 
454
  f"One portion appears AI-generated while the other seems human-written. "
455
  f"This could indicate: partial AI assistance, human editing of AI content, "
456
  f"or AI completion of human-started text. High variance of {variance_between_halves:.2f}% supports mixed authorship."
@@ -463,7 +493,8 @@ def analyze_content_halves(model_manager, text: str, overall_result: Dict = None
463
  verdict = "LIKELY_HUMAN"
464
  confidence = "Low"
465
  reasoning = (
466
- f"Borderline case with scores near 50% threshold (First: {first_ai}%, Second: {second_ai}%). "
 
467
  f"Second half classified as human-written. The text shows characteristics of both "
468
  f"human and AI writing. Variance: {variance_between_halves:.2f}%."
469
  )
@@ -471,12 +502,13 @@ def analyze_content_halves(model_manager, text: str, overall_result: Dict = None
471
  verdict = "LIKELY_AI"
472
  confidence = "Low"
473
  reasoning = (
474
- f"Borderline case with scores near 50% threshold (First: {first_ai}%, Second: {second_ai}%). "
 
475
  f"Pattern suggests {second_model} but confidence is low. "
476
  f"Variance: {variance_between_halves:.2f}%."
477
  )
478
 
479
- # Prepare final decision structure
480
  final_decision = {
481
  "verdict": verdict,
482
  "confidence": confidence,
@@ -489,7 +521,9 @@ def analyze_content_halves(model_manager, text: str, overall_result: Dict = None
489
  "variance_between_halves": round(variance_between_halves, 2),
490
  "first_half_model": first_model,
491
  "second_half_model": second_model,
492
- "models_agree": first_model == second_model
 
 
493
  }
494
  }
495
 
@@ -505,12 +539,21 @@ def analyze_content_halves(model_manager, text: str, overall_result: Dict = None
505
  "human_percentage": first_half_result["human_percentage"],
506
  "predicted_model": first_model,
507
  "word_count": first_half_words,
508
- "preview": first_half[:200] + "..." if len(first_half) > 200 else first_half
 
 
509
  },
510
  "second_half": {
511
  "ai_percentage": second_ai,
512
  "human_percentage": second_half_result["human_percentage"],
513
  "predicted_model": second_model,
 
 
 
 
 
 
 
514
  "word_count": second_half_words,
515
  "preview": second_half[:200] + "..." if len(second_half) > 200 else second_half
516
  },
 
365
  def analyze_content_halves(model_manager, text: str, overall_result: Dict = None) -> Dict:
366
  """
367
  Analyze text by splitting it into two halves after cleaning
368
+ Uses BOTH models for ensemble predictions on each half for improved accuracy
369
 
370
  Args:
371
  model_manager: The ModelManager instance
 
388
  # Split into halves
389
  first_half, second_half = split_content_in_half(cleaned_text)
390
 
391
+ # Analyze first half using BOTH models (ensemble prediction)
392
+ logger.info("🔍 Analyzing first half with both models...")
393
  first_half_result = model_manager.classify_text(first_half)
394
  first_half_words = len(first_half.split())
395
 
396
+ # Analyze second half using BOTH models (ensemble prediction)
397
+ logger.info("🔍 Analyzing second half with both models...")
398
  second_half_result = model_manager.classify_text(second_half)
399
  second_half_words = len(second_half.split())
400
 
 
404
  first_model = first_half_result["predicted_model"]
405
  second_model = second_half_result["predicted_model"]
406
 
407
+ # Get top predictions from both halves for comparison
408
+ first_top5 = first_half_result.get("top_5_predictions", [])
409
+ second_top5 = second_half_result.get("top_5_predictions", [])
410
+
411
  # Calculate average AI score from both halves
412
  avg_halves_ai_score = (first_ai + second_ai) / 2
413
 
 
417
  # Overall AI probability (use overall_result if provided, otherwise calculate)
418
  overall_ai_prob = overall_result["ai_percentage"] / 100 if overall_result else avg_halves_ai_score / 100
419
 
420
+ # Check model consistency across halves
421
+ models_agree = first_model == second_model
422
+
423
+ # Calculate confidence boost from using both models
424
+ models_used = first_half_result.get("models_used", 1)
425
+ ensemble_confidence_boost = "High" if models_used > 1 else "Low"
426
+
427
+ logger.info(f"✅ First half: {first_ai}% AI ({first_model}) | Second half: {second_ai}% AI ({second_model})")
428
+ logger.info(f"📊 Models used per half: {models_used} | Agreement: {models_agree}")
429
+
430
  # ===== FINAL DECISION LOGIC =====
431
  verdict = None
432
  confidence = None
 
437
  verdict = "HUMAN"
438
  confidence = "High" if variance_between_halves < 15 else "Medium"
439
  reasoning = (
440
+ f"Both halves scored below 50% AI probability (First: {first_ai}%, Second: {second_ai}%) "
441
+ f"using ensemble prediction from {models_used} model(s). "
442
  f"The second half was classified as human-written. "
443
  f"Variance between halves is {variance_between_halves:.2f}%, indicating "
444
+ f"{'consistent human patterns' if variance_between_halves < 15 else 'some variation but still human-like'}. "
445
+ f"Model predictions {'agree' if models_agree else 'differ'} across halves."
446
  )
447
 
448
  # Condition 2: Both halves > 50% AI AND second_half predicted_model is NOT "human"
449
  elif first_ai > 50 and second_ai > 50 and second_model.lower() != "human":
450
  verdict = "AI"
451
 
452
+ # Determine confidence based on scores and model agreement
453
  if first_ai > 80 and second_ai > 80:
454
  confidence = "Very High"
455
  elif first_ai > 70 and second_ai > 70:
 
457
  else:
458
  confidence = "Medium"
459
 
460
+ # Boost confidence if models agree
461
+ if models_agree and confidence != "Very High":
462
+ confidence_levels = ["Low", "Medium", "High", "Very High"]
463
+ current_idx = confidence_levels.index(confidence)
464
+ if current_idx < len(confidence_levels) - 1:
465
+ confidence = f"{confidence} (boosted by model agreement)"
466
+
467
  reasoning = (
468
+ f"Both halves scored above 50% AI probability (First: {first_ai}%, Second: {second_ai}%) "
469
+ f"using ensemble prediction from {models_used} model(s). "
470
  f"The pattern matches {second_model} outputs. "
471
+ f"First half suggests {first_model} while second half suggests {second_model}. "
472
  f"Variance between halves is {variance_between_halves:.2f}%, "
473
+ f"{'showing consistent AI patterns throughout' if variance_between_halves < 20 else 'with some variation in AI generation style'}. "
474
+ f"{'Both halves agree on the AI model type, strengthening confidence' if models_agree else 'Different AI models detected in each half'}."
475
  )
476
 
477
  # Condition 3: Mixed results - one half AI, one half human
 
479
  verdict = "MIXED"
480
  confidence = "Low"
481
  reasoning = (
482
+ f"Mixed signals detected using {models_used} model(s) for ensemble prediction. "
483
+ f"First half: {first_ai}% AI ({first_model}), Second half: {second_ai}% AI ({second_model}). "
484
  f"One portion appears AI-generated while the other seems human-written. "
485
  f"This could indicate: partial AI assistance, human editing of AI content, "
486
  f"or AI completion of human-started text. High variance of {variance_between_halves:.2f}% supports mixed authorship."
 
493
  verdict = "LIKELY_HUMAN"
494
  confidence = "Low"
495
  reasoning = (
496
+ f"Borderline case with scores near 50% threshold (First: {first_ai}%, Second: {second_ai}%) "
497
+ f"analyzed using {models_used} model(s). "
498
  f"Second half classified as human-written. The text shows characteristics of both "
499
  f"human and AI writing. Variance: {variance_between_halves:.2f}%."
500
  )
 
502
  verdict = "LIKELY_AI"
503
  confidence = "Low"
504
  reasoning = (
505
+ f"Borderline case with scores near 50% threshold (First: {first_ai}%, Second: {second_ai}%) "
506
+ f"analyzed using {models_used} model(s). "
507
  f"Pattern suggests {second_model} but confidence is low. "
508
  f"Variance: {variance_between_halves:.2f}%."
509
  )
510
 
511
+ # Prepare final decision structure with enhanced model information
512
  final_decision = {
513
  "verdict": verdict,
514
  "confidence": confidence,
 
521
  "variance_between_halves": round(variance_between_halves, 2),
522
  "first_half_model": first_model,
523
  "second_half_model": second_model,
524
+ "models_agree": models_agree,
525
+ "ensemble_models_used": models_used,
526
+ "ensemble_confidence": ensemble_confidence_boost
527
  }
528
  }
529
 
 
539
  "human_percentage": first_half_result["human_percentage"],
540
  "predicted_model": first_model,
541
  "word_count": first_half_words,
542
+ "preview": first_half[:200] + "..." if len(first_half) > 200 else first_half,
543
+ "top_5_predictions": first_top5,
544
+ "models_used": models_used
545
  },
546
  "second_half": {
547
  "ai_percentage": second_ai,
548
  "human_percentage": second_half_result["human_percentage"],
549
  "predicted_model": second_model,
550
+ "word_count": second_half_words,
551
+ "preview": second_half[:200] + "..." if len(second_half) > 200 else second_half,
552
+ "top_5_predictions": second_top5,
553
+ "models_used": models_used
554
+ },
555
+ "final_decision": final_decision
556
+ }
557
  "word_count": second_half_words,
558
  "preview": second_half[:200] + "..." if len(second_half) > 200 else second_half
559
  },