web-dev-qa-db-fra.com

Conserver les résultats TFIDF pour prédire le nouveau contenu à l'aide de Scikit pour Python

J'utilise sklearn sur Python pour faire du clustering. J'ai formé 200 000 données et le code ci-dessous fonctionne bien.

corpus = open("token_from_xml.txt")
vectorizer = CountVectorizer(decode_error="replace")
transformer = TfidfTransformer()
tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))
km = KMeans(30)
kmresult = km.fit(tfidf).predict(tfidf)

Mais lorsque j'ai un nouveau contenu de test, j'aimerais le regrouper en grappes existantes que j'ai formées. Je me demande donc comment enregistrer le résultat IDF afin de pouvoir utiliser TFIDF pour le nouveau contenu de test et que le résultat du nouveau contenu de test présente la même longueur de tableau.

Merci d'avance.

METTRE À JOUR

Je devrais peut-être enregistrer la variable "transformer" ou "tfidf" dans un fichier (txt ou autres), si l'une d'entre elles contient le résultat IDF formé.

METTRE À JOUR

Par exemple. J'ai les données d'entraînement:

["a", "b", "c"]
["a", "b", "d"]

Et faire TFIDF, le résultat contient 4 fonctionnalités (a, b, c, d)

Quand jeTESTE:

["a", "c", "d"]

pour voir à quel cluster (déjà fait par k-means) il appartient. TFIDF ne donnera que le résultat avec 3 caractéristiques (a, c, d), ainsi le regroupement dans k-means va tomber. (Si je teste ["a", "b", "e"], il peut y avoir d'autres problèmes.)

Alors, comment stocker la liste des fonctionnalités pour tester les données (encore plus, stockez-la dans un fichier)?

METTRE À JOUR

Résolu, voir les réponses ci-dessous.

12
lol.Wen

J'ai réussi à enregistrer la liste de fonctionnalités en enregistrant vectorizer.vocabulary_ et à le réutiliser par CountVectorizer(decode_error="replace",vocabulary=vectorizer.vocabulary_).

Codes ci-dessous:

corpus = np.array(["aaa bbb ccc", "aaa bbb ddd"])
vectorizer = CountVectorizer(decode_error="replace")
vec_train = vectorizer.fit_transform(corpus)
#Save vectorizer.vocabulary_
pickle.dump(vectorizer.vocabulary_,open("feature.pkl","wb"))

#Load it later
transformer = TfidfTransformer()
loaded_vec = CountVectorizer(decode_error="replace",vocabulary=pickle.load(open("feature.pkl", "rb")))
tfidf = transformer.fit_transform(loaded_vec.fit_transform(np.array(["aaa ccc eee"])))

Ça marche. tfidf aura la même longueur fonctionnelle que les données entraînées.

12
lol.Wen

Si vous souhaitez stocker la liste des fonctionnalités pour tester les données à utiliser ultérieurement, procédez comme suit:

tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))

#store the content
with open("x_result.pkl", 'wb') as handle:
                    pickle.dump(tfidf, handle)
#load the content
tfidf = pickle.load(open("x_result.pkl", "rb" ) )
6
user123

vous pouvez faire la vectorisation et la transformation tfidf en une étape:

vec =TfidfVectorizer()

puis adapter et transformer sur les données de formation

tfidf = vec.fit_transform(training_data)

et utiliser le modèle tfidf pour transformer

unseen_tfidf = vec.transform(unseen_data)
km = KMeans(30)
kmresult = km.fit(tfidf).predict(unseen_tfid)
1
JAB

Au lieu d'utiliser CountVectorizer pour stocker le vocabulaire, le vocabulaire de tfidfvectorizer peut être utilisé directement.

Phase de formation:

from sklearn.feature_extraction.text import TfidfVectorizer

# tf-idf based vectors
tf = TfidfVectorizer(analyzer='Word', ngram_range=(1,2), stop_words = "english", lowercase = True, max_features = 500000)

# Fit the model
tf_transformer = tf.fit(corpus)

# Dump the file
pickle.dump(tf_transformer, open("tfidf1.pkl", "wb"))


# Testing phase
tf1 = pickle.load(open("tfidf1.pkl", 'rb'))

# Create new tfidfVectorizer with old vocabulary
tf1_new = TfidfVectorizer(analyzer='Word', ngram_range=(1,2), stop_words = "english", lowercase = True,
                          max_features = 500000, vocabulary = tf1.vocabulary_)
X_tf1 = tf1_new.fit_transform(new_corpus)

Fit_transform fonctionne ici car nous utilisons l'ancien vocabulaire. Si vous ne stockiez pas le fichier tfidf, vous auriez simplement utilisé la transformation sur les données de test. Même lorsque vous y effectuez une transformation, les nouveaux documents à partir des données de test sont "adaptés" au vocabulaire du vectoriseur du train. C'est exactement ce que nous faisons ici. Le vocabulaire est la seule chose que nous pouvons stocker et réutiliser pour un vectoriseur tfidf.

1
Arjun Mishra

une solution plus simple, utilisez simplement joblib libarary comme document dit:

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.externals import joblib

vectorizer = CountVectorizer()
X = vectorizer.fit_transform(texts)
feature_name = vectorizer.get_feature_names()
tfidf = TfidfTransformer()
tfidf.fit(X)

# save your model in disk
joblib.dump(transformer, 'tfidf.pkl') 

# load your model
tfidf = joblib.load('tfidf.pkl') 
0
GoatWang