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).
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
3 Réponses :
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.
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.
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.
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
vous pouvez utiliser Neural Network pour utiliser à la fois du texte et des données numériques pour la classification.