Script Analisi Testi AI

Nel campo sempre in evoluzione della programmazione e dell’intelligenza artificiale, è emerso uno script Python che segna un notevole passo in avanti nell’analisi testuale. Questo script, che incorpora librerie Python di rilievo come NLTK, Spacy, TextBlob e Textstat, è stato progettato con un obiettivo preciso: fornire un’analisi testuale dettagliata e identificare i contenuti generati da intelligenza artificiale.

import nltk
from nltk.tokenize import sent_tokenize, word_tokenize
from nltk.probability import FreqDist
from nltk.sentiment import SentimentIntensityAnalyzer
from nltk import pos_tag
from textstat.textstat import textstatistics
import string
from textblob import TextBlob
from textblob.exceptions import NotTranslated
from nltk.tokenize import word_tokenize
import spacy
import numpy as np 

# Carica il modello italiano di SpaCy
nlp = spacy.load('it_core_news_sm')

def calculate_total_words_and_characters(text):
    words = word_tokenize(text)
    total_words = len(words)
    total_characters = len(text)
    return total_words, total_characters

def analyze_sentiment(text):
    try:
        blob = TextBlob(text)
        try:
            # Prova a tradurre in inglese
            translated_blob = blob.translate(to='en')
            text_to_analyze = translated_blob.string
        except Exception:
            # In caso di errore, utilizza il testo originale
            text_to_analyze = blob.string

        # Analisi del sentiment sul testo tradotto o originale
        return TextBlob(text_to_analyze).sentiment
    except Exception as e:
        print(f"Errore durante l'analisi del sentiment: {e}")
        return None

def unique_word_count(words):
    return len(set(words))

def frequent_nouns_and_verbs(text):
    # Assicurati che `text` sia una stringa
    if not isinstance(text, str):
        raise ValueError("Il testo deve essere una stringa.")

    doc = nlp(text)
    nouns = [token.text for token in doc if token.pos_ == 'NOUN']
    verbs = [token.text for token in doc if token.pos_ == 'VERB']
    freq_nouns = FreqDist(nouns).most_common(5)
    freq_verbs = FreqDist(verbs).most_common(5)
    return freq_nouns, freq_verbs

def difficult_words_count(text):
    return textstatistics().difficult_words(text)

def proper_nouns_density(text):
    words = word_tokenize(text)
    tagged_words = pos_tag(words)
    proper_nouns = [word for word, tag in tagged_words if tag == 'NNP']
    return len(proper_nouns) / len(words) * 100

def analyze_text(text):
    if not text:
        raise ValueError("Il testo fornito è vuoto.")

    sentences = sent_tokenize(text)
    words = word_tokenize(text)

    if len(sentences) == 0 or len(words) == 0:
        raise ValueError("Il testo non contiene frasi o parole valide per l'analisi.")

    freq_dist = FreqDist(words)
    top_words = freq_dist.most_common(10)
    readability_index = textstatistics().flesch_reading_ease(text)
    avg_sentence_length = sum(len(sentence.split()) for sentence in sentences) / len(sentences)
    avg_word_length = sum(len(word) for word in words) / len(words)
    punctuation_probability = calculate_punctuation_probability(text)
    
    # Passa il testo originale a frequent_nouns_and_verbs
    freq_nouns, freq_verbs = frequent_nouns_and_verbs(text)
    
    # Chiamata alle nuove funzioni
    sentiment_scores = analyze_sentiment(text)
    unique_words = unique_word_count(words)
    difficult_words = difficult_words_count(text)
    proper_nouns_percentage = proper_nouns_density(text)

    return {
        "Parole più frequenti": top_words,
        "Indice di Leggibilità": readability_index,
        "Lunghezza Media delle Frasi": avg_sentence_length,
        "Lunghezza Media delle Parole": avg_word_length,
        "Probabilità di Punteggiatura": punctuation_probability,
        "Punteggi del Sentiment": sentiment_scores,
        "Conteggio Parole Uniche": unique_words,
        "Conteggio Parole Difficili": difficult_words,
        "Densità dei Nomi Propri (%)": proper_nouns_percentage,
        "Verbi": freq_verbs,
        "Nomi": freq_nouns,        
    }

def calculate_punctuation_probability(text):
    common_punctuation = string.punctuation
    punctuation_count = sum(text.count(char) for char in common_punctuation)
    text_length = len(text)
    return (punctuation_count / text_length * 100) if text_length > 0 else 0

def ai_generated_text_probability_calculation(analysis_results):
    # Nuovi pesi per ciascun fattore
    weights = {
        'top_words': 0.15,  # Maggiore importanza alle parole più frequenti
        'readability_index': 0.10,  # Minore importanza all'indice di leggibilità
        'avg_sentence_length': 0.10,
        'avg_word_length': 0.10,
        'punctuation_probability': 0.10,
        'sentiment_scores': 0.20,  # Maggiore importanza ai punteggi di sentiment
        'unique_words': 0.15,  # Maggiore importanza al conteggio delle parole uniche
        'difficult_words': 0.05,
        'proper_nouns_percentage': 0.05  # Minore importanza alla densità dei nomi propri
    }

    # Calcolo modificato dei punteggi
    scores = {
        'top_words': len(analysis_results["Parole più frequenti"]) / 20,
        'readability_index': (100 - analysis_results["Indice di Leggibilità"]) / 100,  # Inversione del punteggio
        'avg_sentence_length': 1 - abs(analysis_results["Lunghezza Media delle Frasi"] - 20) / 20,  # Punta a una lunghezza media di 20 parole
        'avg_word_length': 1 - abs(analysis_results["Lunghezza Media delle Parole"] - 5) / 5,  # Punta a una lunghezza media di 5 lettere
        'punctuation_probability': analysis_results["Probabilità di Punteggiatura"] / 10,
        'sentiment_scores': (1 - abs(analysis_results["Punteggi del Sentiment"].polarity)) * (1 - abs(analysis_results["Punteggi del Sentiment"].subjectivity)),  # Valuta sia la polarità che la soggettività
        'unique_words': analysis_results["Conteggio Parole Uniche"] / 1000,
        'difficult_words': analysis_results["Conteggio Parole Difficili"] / 500,
        'proper_nouns_percentage': analysis_results["Densità dei Nomi Propri (%)"] / 100
    }

    # Calcolo del punteggio complessivo
    total_score = sum(weights[key] * scores[key] for key in weights)

    # Normalizzazione del punteggio su una scala da 0 a 100
    ai_probability_score = total_score * 100

    return ai_probability_score


def calculate_ai_probability(tokens, readability, avg_sentence_length, avg_word_length, punctuation_prob, unique_words, difficult_words, proper_nouns_percentage):
    # Normalizzazione
    normalized_readability = readability / 100
    normalized_avg_sentence_length = avg_sentence_length / 50
    normalized_avg_word_length = avg_word_length / 10
    normalized_punctuation_prob = punctuation_prob / 10
    normalized_unique_words = unique_words / 500
    normalized_difficult_words = difficult_words / 200
    normalized_proper_nouns_percentage = proper_nouns_percentage / 100

    # Pesi (esempi)
    weights = {
        'tokens': 0.1,
        'readability': 0.15,
        'avg_sentence_length': 0.2,
        'avg_word_length': 0.15,
        'punctuation_prob': 0.1,
        'unique_words': 0.1,
        'difficult_words': 0.1,
        'proper_nouns_percentage': 0.1
    }

    # Calcolo del punteggio complessivo
    score = (
        weights['tokens'] * tokens + 
        weights['readability'] * normalized_readability + 
        weights['avg_sentence_length'] * normalized_avg_sentence_length +
        weights['avg_word_length'] * normalized_avg_word_length +
        weights['punctuation_prob'] * normalized_punctuation_prob +
        weights['unique_words'] * normalized_unique_words +
        weights['difficult_words'] * normalized_difficult_words +
        weights['proper_nouns_percentage'] * normalized_proper_nouns_percentage
    )

    # Normalizzazione del punteggio su una scala da 0 a 1
    normalized_score = score / sum(weights.values())

    # Conversione in probabilità percentuale
    ai_probability = normalized_score * 100

    return ai_probability

def count_tokens(text):

    # Crea un oggetto Doc con il testo fornito
    doc = nlp(text)

    # Conta i token nel Doc
    token_count = len(doc)

    return token_count

# Testo di esempio

text = """Inserire qui il testo da analizzare"""

total_words, total_characters = calculate_total_words_and_characters(text)
num_tokens = count_tokens(text)

try:
    analysis_results = analyze_text(text)

    ai_probability = ai_generated_text_probability_calculation(analysis_results)
    
    print("Analisi del testo:")
    for key, value in analysis_results.items():
        print(f"{key}: {value}")
    print(f"Probabilità: {ai_probability}")
    print(f"Numero di token nel testo: {num_tokens}")
except ValueError as e:
    print(f"Errore: {e}")

La prima funzionalità degna di nota è l’analisi testuale di base. Lo script non solo calcola il numero totale di parole e caratteri, ma va oltre identificando la frequenza delle parole, i sostantivi e i verbi più comuni, e la densità dei nomi propri. Queste metriche sono fondamentali per chiunque voglia approfondire la struttura e il contenuto del proprio testo.

Un’altra caratteristica distintiva è l’analisi del sentiment, resa possibile dall’utilizzo di TextBlob. Questa funzione valuta il sentiment del testo, avvalendosi di una traduzione preliminare in inglese qualora necessario. Questo passaggio fornisce un’analisi più profonda del tono emotivo del testo, sia in termini di polarità che di soggettività, offrendo così una visione preziosa non solo del “cosa” ma anche del “come” viene comunicato un messaggio.

L’attenzione dello script si estende anche alla valutazione della complessità del testo. Determina la difficoltà delle parole e calcola l’indice di leggibilità, fornendo un quadro chiaro della complessità e dell’accessibilità del testo analizzato. Questa caratteristica è particolarmente utile per chi deve adeguare il proprio stile di scrittura a un pubblico specifico.

Forse l’aspetto più innovativo dello script è la sua capacità di stimare la probabilità che il testo sia stato generato da un’intelligenza artificiale. Attraverso un’analisi ponderata di vari fattori testuali, lo script fornisce una stima di questa probabilità, rendendolo uno strumento indispensabile in un’epoca in cui il contenuto generato automaticamente sta diventando sempre più comune.

Ma quali sono le applicazioni reali di questo script? Si estendono ben oltre l’ambito accademico o di ricerca. Gli editori, i redattori di contenuti e i professionisti del marketing possono utilizzare questo strumento per migliorare la qualità e l’impatto del loro lavoro. In ambito educativo, lo script può essere utilizzato come strumento didattico per insegnare i concetti di base della linguistica computazionale e dell’analisi del testo.

In conclusione, questo script rappresenta un’innovazione significativa nel panorama degli strumenti di analisi testuale. La sua capacità di analizzare testi complessi e di stimare la probabilità di contenuto generato da AI lo rende estremamente rilevante nell’era moderna dell’informazione digitale. Con le sue potenzialità e applicazioni pratiche, questo script è senza dubbio un baluardo nella programmazione Python rivolta all’analisi del linguaggio naturale.