Simón, miembro de nuestro equipo de trabajo, nos hizo el favor de redactar esta crónica porque domina perfectamente este tema.
Solución:
Parece que un buen enfoque aquí sería usar un modelo de asignación Latent Dirichlet, que es un ejemplo de lo que se conoce como modelos temáticos.
A LDA
es un modelo no supervisado que encuentra grupos similares entre un conjunto de observaciones, que luego puede usar para asignar un tema a cada uno de ellos. Aquí repasaré lo que podría ser un enfoque para resolver esto entrenando un modelo usando las oraciones en el text
columna. Aunque en el caso de la phrases
son lo suficientemente representativos y contienen la información necesaria para ser capturada por los modelos, entonces también podrían ser un buen candidato (posiblemente mejor) para entrenar el modelo, aunque será mejor que lo juzgue usted mismo.
Antes de entrenar el modelo, debe aplicar algunos pasos de preprocesamiento, incluida la tokenización de las oraciones, la eliminación de palabras vacías, la lematización y la derivación. Para eso puedes usar nltk
:
from nltk.stem import WordNetLemmatizer
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
import lda
from sklearn.feature_extraction.text import CountVectorizer
ignore = set(stopwords.words('english'))
stemmer = WordNetLemmatizer()
text = []
for sentence in df.text:
words = word_tokenize(sentence)
stemmed = []
for word in words:
if word not in ignore:
stemmed.append(stemmer.lemmatize(word))
text.append(' '.join(stemmed))
Ahora tenemos un corpus más apropiado para entrenar el modelo:
print(text)
['great game lot amazing goal team',
'goalkeeper team made misteke',
'four grand slam championchips',
'best player three-point line',
'Novak Djokovic best player time',
'amazing slam dunk best player',
'deserved yellow-card foul',
'free throw point']
Luego podemos convertir el texto en una matriz de recuentos de tokens a través de CountVectorizer
que es la entrada LDA
estará esperando:
vec = CountVectorizer(analyzer='word', ngram_range=(1,1))
X = vec.fit_transform(text)
Tenga en cuenta que puede utilizar el ngram
parámetro para especificar el rango de n-gramas que desea considerar para entrenar el modelo. Configurando ngram_range=(1,2)
por ejemplo, terminaría con funciones que contienen todas las palabras individuales, así como 2-grams
en cada oración, aquí hay un ejemplo de haber entrenado CountVectorizer
con ngram_range=(1,2)
:
vec.get_feature_names()
['amazing',
'amazing goal',
'amazing slam',
'best',
'best player',
....
The advantage of using n-grams
is that you could then also find Key-Phrases
other than just single words.
Then we can train the LDA
with whatever amount of topics you want, in this case I’ll just be selecting 3
topics (note that this has nothing to do with the topics
column), which you can consider to be the Key-Phrases
– or words
in this case – that you mention. Here I’ll be using lda
, though there are several options such as gensim.
Each topic will have associated a set of words from the vocabulary it has been trained with, with each word having a score measuring the relevance of the word in a topic.
model = lda.LDA(n_topics=3, random_state=1)
model.fit(X)
Through topic_word_
we can now obtain these scores associated to each topic. We can use argsort
to sort the vector of scores, and use it to index the vector of feature names, which we can obtain with vec.get_feature_names
:
topic_word = model.topic_word_
vocab = vec.get_feature_names()
n_top_words = 3
for i, topic_dist in enumerate(topic_word):
topic_words = np.array(vocab)[np.argsort(topic_dist)][:-(n_top_words+1):-1]
print('Tema : '.format(i, ' .join(topic_words))) Tema 0: punto de mejor jugador Tema 1: increíble golpe de equipo Tema 2: tarjeta amarilla de novak
Los resultados impresos realmente no representan mucho en este caso, ya que el modelo ha sido entrenado con la muestra de la pregunta, sin embargo, debería ver más claro y significativo. temas entrenando con todo tu corpus.
También tenga en cuenta que para este ejemplo he usado todo el vocabulario para entrenar el modelo. Sin embargo, parece que en su caso, lo que tendría más sentido es dividir la columna de texto en grupos de acuerdo con los diferentes topics
ya lo tienes y entrenar un modelo separado en cada grupo. Pero espero que esto le dé una buena idea sobre cómo proceder.
Reseñas y puntuaciones
Si te animas, puedes dejar una reseña acerca de qué te ha parecido este ensayo.