
    g'                         d Z ddlZddlmZ ddlmZ ddlmZ ddlm	Z	 ddl
mZ ddl
mZ dd	l
mZ dd
l
mZ ddlmZ  G d d      Zy)z
A SentimentAnalyzer is a tool to implement and facilitate Sentiment Analysis tasks
using NLTK features and classifiers, especially for teaching and demonstrative
purposes.
    N)defaultdict)accuracy)apply_features)BigramCollocationFinder)BigramAssocMeasures)	f_measure)	precision)recall)FreqDistc                       e Zd ZdZddZddZddZddZddej                  fdZ
d	 Zd
 Zd ZddZd Z	 	 	 	 	 	 ddZy)SentimentAnalyzerzI
    A Sentiment Analysis tool based on machine learning approaches.
    Nc                 :    t        t              | _        || _        y N)r   listfeat_extractors
classifier)selfr   s     V/var/www/openai/venv/lib/python3.12/site-packages/nltk/sentiment/sentiment_analyzer.py__init__zSentimentAnalyzer.__init__!   s    *40$    c                     g }||xr t        |d   t              }|r|D ]  \  }}|j                  |        |S |s|D ]  }|j                  |        |S )a  
        Return all words/tokens from the documents (with duplicates).

        :param documents: a list of (words, label) tuples.
        :param labeled: if `True`, assume that each document is represented by a
            (words, label) tuple: (list(str), str). If `False`, each document is
            considered as being a simple list of strings: list(str).
        :rtype: list(str)
        :return: A list of all words/tokens in `documents`.
        r   )
isinstancetupleextend)r   	documentslabeled	all_wordswords
_sentiments         r   r   zSentimentAnalyzer.all_words%   sn     	?CJy|U$CG%.!z  ' &/
  "  ' #r   c                 0    t        | j                  ||      S )a  
        Apply all feature extractor functions to the documents. This is a wrapper
        around `nltk.classify.util.apply_features`.

        If `labeled=False`, return featuresets as:
            [feature_func(doc) for doc in documents]
        If `labeled=True`, return featuresets as:
            [(feature_func(tok), label) for (tok, label) in toks]

        :param documents: a list of documents. `If labeled=True`, the method expects
            a list of (words, label) tuples.
        :rtype: LazyMap
        )r   extract_features)r   r   r   s      r   r   z SentimentAnalyzer.apply_features;   s     d33YHHr   c                     t        d |D              }|j                  |      D cg c]  \  }}||   |kD  r| c}}S c c}}w )a7  
        Return most common top_n word features.

        :param words: a list of words/tokens.
        :param top_n: number of best words/tokens to use, sorted by frequency.
        :rtype: list(str)
        :return: A list of `top_n` words/tokens (with no duplicates) sorted by
            frequency.
        c              3       K   | ]  }|  y wr    ).0words     r   	<genexpr>z7SentimentAnalyzer.unigram_word_feats.<locals>.<genexpr>V   s     &>ts   )r   most_common)r   r   top_nmin_frequnigram_feats_freqswfs          r   unigram_word_featsz$SentimentAnalyzer.unigram_word_featsK   sX     '&>&>> ,77>
>1"1%0 >
 	
 
s   ?   c                 r    t        j                  |      }|j                  |       |j                  ||      S )ai  
        Return `top_n` bigram features (using `assoc_measure`).
        Note that this method is based on bigram collocations measures, and not
        on simple bigram frequency.

        :param documents: a list (or iterable) of tokens.
        :param top_n: number of best words/tokens to use, sorted by association
            measure.
        :param assoc_measure: bigram association measure to use as score function.
        :param min_freq: the minimum number of occurrencies of bigrams to take
            into consideration.

        :return: `top_n` ngrams scored by the given association measure.
        )r   from_documentsapply_freq_filternbest)r   r   r)   r*   assoc_measurefinders         r   bigram_collocation_featsz*SentimentAnalyzer.bigram_collocation_feats]   s3    " )77	B  *||M511r   c                 f    | j                  |gd      }| j                  j                  |d         S )a	  
        Classify a single instance applying the features that have already been
        stored in the SentimentAnalyzer.

        :param instance: a list (or iterable) of tokens.
        :return: the classification result given by applying the classifier.
        F)r   r   )r   r   classify)r   instanceinstance_featss      r   r8   zSentimentAnalyzer.classifyr   s5     ,,hZ,G''q(9::r   c                 @    | j                   |   j                  |       y)aG  
        Add a new function to extract features from a document. This function will
        be used in extract_features().
        Important: in this step our kwargs are only representing additional parameters,
        and NOT the document we have to parse. The document will always be the first
        parameter in the parameter list, and it will be added in the extract_features()
        function.

        :param function: the extractor function to add to the list of feature extractors.
        :param kwargs: additional parameters required by the `function` function.
        N)r   append)r   functionkwargss      r   add_feat_extractorz$SentimentAnalyzer.add_feat_extractor}   s     	X&--f5r   c                     i }| j                   D ]0  }| j                   |   D ]  } ||fi |} |j                         2 |S )ak  
        Apply extractor functions (and their parameters) to the present document.
        We pass `document` as the first parameter of the extractor functions.
        If we want to use the same extractor function multiple times, we have to
        add it to the extractors with `add_feat_extractor` using multiple sets of
        parameters (one for each call of the extractor function).

        :param document: the document that will be passed as argument to the
            feature extractor functions.
        :return: A dictionary of populated features extracted from the document.
        :rtype: dict
        )r   update)r   documentall_features	extractor	param_setfeatss         r   r!   z"SentimentAnalyzer.extract_features   sS     --I!11)<	!(8i8 =& . r   c                     t        d        ||fi || _        |r| j                  | j                  |       | j                  S )a  
        Train classifier on the training set, optionally saving the output in the
        file specified by `save_classifier`.
        Additional arguments depend on the specific trainer used. For example,
        a MaxentClassifier can use `max_iter` parameter to specify the number
        of iterations, while a NaiveBayesClassifier cannot.

        :param trainer: `train` method of a classifier.
            E.g.: NaiveBayesClassifier.train
        :param training_set: the training set to be passed as argument to the
            classifier `train` method.
        :param save_classifier: the filename of the file where the classifier
            will be stored (optional).
        :param kwargs: additional parameters that will be passed as arguments to
            the classifier `train` function.
        :return: A classifier instance trained on the training set.
        :rtype:
        zTraining classifier)printr   	save_file)r   trainertraining_setsave_classifierr>   s        r   trainzSentimentAnalyzer.train   s=    & 	#$!,9&9NN4??O<r   c                     t        d|t        j                         t        |d      5 }ddl}|j                  ||d       ddd       y# 1 sw Y   yxY w)zZ
        Store `content` in `filename`. Can be used to store a SentimentAnalyzer.
        Saving)filewbr   N   )protocol)rH   sysstderropenpickledump)r   contentfilenamestorage_filerW   s        r   rI   zSentimentAnalyzer.save_file   sC     	hszz2(D!\ KKK:	 "!!s   AAc                    || j                   }t        dt        |      j                   d       i }|rt	        ||      }	|	|d<   t        t              }
t        t              }t               }t        |      D ]R  \  }\  }}|j                  |       |
|   j                  |       |j                  |      }||   j                  |       T |D ]Z  }|rt        |
|   ||         }||d| d<   |rt        |
|   ||         }||d| d<   |s@t        |
|   ||         }||d| d<   \ |r#t        |      D ]  }t        | d||            |S )	a0  
        Evaluate and print classifier performance on the test set.

        :param test_set: A list of (tokens, label) tuples to use as gold set.
        :param classifier: a classifier instance (previously trained).
        :param accuracy: if `True`, evaluate classifier accuracy.
        :param f_measure: if `True`, evaluate classifier f_measure.
        :param precision: if `True`, evaluate classifier precision.
        :param recall: if `True`, evaluate classifier recall.
        :return: evaluation results.
        :rtype: dict(str): float
        zEvaluating z results...AccuracyzPrecision []zRecall [zF-measure [z: )r   rH   type__name__eval_accuracyr   set	enumerateaddr8   eval_precisioneval_recalleval_f_measuresorted)r   test_setr   r   r   r	   r
   verbosemetrics_resultsaccuracy_scoregold_resultstest_resultslabelsirF   labelobservedprecision_scorerecall_scoref_measure_scoreresults                        r   evaluatezSentimentAnalyzer.evaluate   s   , JD,556kBC*:x@N*8OJ'"3'"3'!*8!4A~uJJu##A&!**51H"&&q)	 "5 E"0 'e)<# ;J+eWA 67*<+>U@ST7C(5' 34"0 'e)<# ;J+eWA 67    1?6#:";<= 2 r   r   )Nr   )NTTTTF)r`   
__module____qualname____doc__r   r   r   r.   r   pmir6   r8   r?   r!   rM   rI   rw   r$   r   r   r   r      sc    %,I 
&  $a?R?V?V2*	;6(4	; ;r   r   )rz   rT   collectionsr   nltk.classify.utilr   ra   r   nltk.collocationsr   nltk.metricsr   r   rg   r	   re   r
   rf   nltk.probabilityr   r   r$   r   r   <module>r      s6     # 8 - 5 , 4 4 . %c cr   