2
votes

PNL - Comment ajouter plus de fonctionnalités?

Je souhaite utiliser un classificateur sklearn pour entraîner un modèle à classer les entrées de données (oui, non) à l'aide d'une fonctionnalité de texte (contenu), d'une fonctionnalité numérique (population) et d'une fonctionnalité catégorielle (emplacement).

 entrez la description de l'image ici

Le modèle ci-dessous utilise uniquement les données textuelles pour classer chaque entrée. Le texte est converti avec TF-IDF en une matrice clairsemée avant d'être importé dans le classificateur.

Existe-t-il un moyen d'ajouter / d'utiliser également les autres fonctionnalités? Ces fonctionnalités ne sont pas au format de matrice clairsemée, donc je ne sais pas comment les combiner avec la matrice clairsemée de texte.

    #import libraries
    import string, re, nltk
    import pandas as pd
    from pandas import Series, DataFrame
    from nltk.corpus import stopwords
    from nltk.stem.porter import PorterStemmer
    from sklearn.feature_extraction.text import CountVectorizer
    from sklearn.feature_extraction.text import TfidfTransformer
    from sklearn.model_selection import train_test_split
    from sklearn.metrics import classification_report
    from sklearn.pipeline import Pipeline

    # read data and remove empty lines
    dataset = pd.read_csv('sample_data.txt',
                           sep='\t',
                           names=['content','location','population','target'])
                           .dropna(how='all')
                           .dropna(subset=['target'])

    df = dataset[1:]

    #reset dataframe index
    df.reset_index(inplace = True)

    #add an extra column which is the length of text
    df['length'] = df['content'].apply(len)

    #create a dataframe that contains only two columns the text and the target class
    df_cont = df.copy()
    df_cont = df_cont.drop(
        ['location','population','length'],axis = 1)

    # function that takes in a string of text, removes all punctuation, stopwords and returns a list of cleaned text

    def text_process(mess):
        # lower case for string
        mess = mess.lower()

        # check characters and removes URLs
       nourl = re.sub(r'http\S+', ' ', mess)

        # check characters and removes punctuation
        nopunc = [char for char in nourl if char not in string.punctuation]

        # join the characters again to form the string and removes numbers
        nopunc = ''.join([i for i in nopunc if not i.isdigit()])

        # remove stopwords
        return [ps.stem(word) for word in nopunc.split() if word not in set(stopwords.words('english'))]

    #split the data in train and test set and train/test the model

    cont_train, cont_test, target_train, target_test = train_test_split(df_cont['content'],df_cont['target'],test_size = 0.2,shuffle = True, random_state = 1)


    pipeline = Pipeline([('bag_of_words',CountVectorizer(analyzer=text_process)),
                         ('tfidf',TfidfTransformer()),
                         ('classifier',MultinomialNB())])

    pipeline.fit(cont_train,target_train)
    predictions = pipeline.predict(cont_test)

    print(classification_report(predictions,target_test))

Le modèle devrait renvoyer les éléments suivants: précision, précision, rappel, score f1


1 commentaires

vous pouvez utiliser Neural Network pour utiliser à la fois du texte et des données numériques pour la classification.


3 Réponses :


0
votes

Il ne semble pas que nous puissions encoder directement du texte en tant que fonctionnalité. Vous devez donc probablement le normaliser. Vous pouvez choisir l'une des lignes de texte et la définir comme standard. Utilisez TFIDF pour calculer le score de correspondance entre votre texte standard et le texte de chaque ligne. Vous pouvez ensuite encoder ce pourcentage en tant qu'entité. Je me rends compte que c'est une façon très détournée d'encoder, mais en fonction du texte que vous choisissez comme norme, cela peut fonctionner.


0 commentaires

0
votes

Vous pouvez convertir votre matrice creuse en numpy array en utilisant la méthode toarray .

Vous obtiendrez un vecteur pour chaque entrée de texte que vous pourrez concaténer avec d'autres fonctionnalités.


0 commentaires

1
votes

Je pense que vous devez utiliser la vectorisation one-hot pour la fonction "localisation". Les vecteurs one-hot pour les données données seraient,

Londres - 100

Manchester - 010

Édimbourg - 001

La longueur du vecteur est le nombre de villes que vous avez là-dedans. Notez que chaque bit ici serait une fonctionnalité. Les données catégorielles sont généralement converties en vecteurs one-hot avant d'être alimentées par un algorithme d'apprentissage automatique.


3 commentaires

Merci pour la réponse @avin, ma question est de savoir comment combiner le codage que vous avez décrit ci-dessus avec la matrice creuse produite par le tf-idf?


À ma connaissance, sklearn a besoin de lignes au format 1D. Vous pouvez essayer TfidfVectorizer [ scikit-learn.org/ stable / modules / generated /… pour avoir un vecteur 1D pour chacune de ces phrases. Et puis vectoriser à chaud la fonction de localisation et utiliser np.concatenate ((seq1, seq2, .., seqN)) pour tout concaténer dans un tableau 1D?


Merci pour l'aide @avin