Lorsque la classification de texte a été effectuée à l'aide de données classées par les humains comme données d'enseignants, les effets néfastes de l'intervention humaine entre les données sont apparus, j'ai donc créé un classificateur de texte sans enseignant.
Je regrette qu'il valait mieux classer par algorithme graphique plutôt que par k-means. La raison est qu'il n'y a qu'un nombre limité de documents qui produisent une similitude lorsqu'ils sont calculés avec Doc2Vec. Avec k-means, vous devez construire une matrice creuse une fois, mais si vous classifiez avec un algorithme de graphe, vous n'avez pas à vous soucier de perdre de la mémoire. ..
Je suis désolé que les commentaires soient mélangés avec du japonais et de l'anglais, et le code est assez sale. ..
# coding: utf-8
from gensim import corpora, models
import numpy as np
from numpy import random
random.seed(555)
from scipy.cluster.vq import vq, kmeans, whiten
from sklearn.decomposition import TruncatedSVD
from collections import defaultdict
from separatewords import MecabTokenize #Veuillez appeler un analyseur morphologique adapté à vos besoins.
class MyTexts:
def __init__(self, text_list):
self.text_list = text_list
def __iter__(self):
for line in self.text_list:
if line==b'Non entré': continue
yield MecabTokenize.tokenize( line.rstrip().decode('utf-8') )
class LabeledLineSentence(object):
def __init__(self, texts_words):
self.texts_words = texts_words
def __iter__(self):
for uid, words in enumerate(self.texts_words):
yield models.doc2vec.LabeledSentence(words, labels=['SENT_%s' % uid])
#Définir la similitude de chaque phrase acquise par Doc2Vec avec la matrice
#De plus, obtenez le mot représentatif de chaque phrase
def create_sim_vec(model,n_sent):
base_name = 'SENT_'
sim_matrix = []
sim_matrix_apd = sim_matrix.append
word_matrix = []
word_matrix_apd = word_matrix.append
for i_sent in xrange(n_sent):
sim_vec = np.zeros(n_sent)
word_list = []
word_list_apd = word_list.append
#Comme envoyé peut ne pas exister, incluez la gestion des exceptions
try:
for word, sim_val in model.most_similar(base_name+str(i_sent)):
if 'SENT_' in word:
_, s_idx = word.split('_')
sim_vec[int(s_idx)] = sim_val
else:
word_list_apd(word)
except:
pass
sim_matrix_apd(sim_vec)
word_matrix_apd(word_list)
return sim_matrix, word_matrix
#Organiser des documents similaires avec kmeans
def sent_integrate(sim_matrix,n_class):
#Distribution uniforme pour chaque dimension
whiten(sim_matrix)
centroid, destortion = kmeans(sim_matrix, n_class, iter=100, thresh=1e-05)
labels, dist = vq(sim_matrix, centroid)
return labels
def count_class(labels):
res_dic = defaultdict(int)
for label in labels:
res_dic[label] += 1
return res_dic
def count_labeled_data(label_data, labels):
result_dict = {}
for orig_labels, label in zip(label_data, labels):
labels = np.array(orig_labels.split(), dtype=np.int64)
if label not in result_dict:
result_dict[label] = labels
else:
result_dict[label] += labels
return result_dict
if __name__=='__main__':
ifname = './out_data.csv'
model_basename = './D2V/doc2vec_result/model'
topic_result_basename = './D2V/doc2vec_result/topic'
comment_data = []
comment_data_apd = comment_data.append
label_data = []
label_data_apd = label_data.append
with open(ifname, 'r') as f:
for line in f:
single_flag, label_flags, comment = line.strip().split('\t')
comment_data_apd(comment.strip())
label_data_apd(label_flags.strip())
texts = MyTexts(comment_data)
sentences = LabeledLineSentence(texts)
model = models.Doc2Vec(alpha=0.025, min_alpha=0.025) # use fixed learning rate
model.build_vocab(sentences)
# store the model to mmap-able files
model.save(model_basename+'.d2v')
# load the model back
model_loaded = models.Doc2Vec.load(model_basename+'.d2v')
epoch = 10
for _ in xrange(epoch):
model.train(sentences)
model.alpha -= 0.002 # decrease the learning rate
model.min_alpha = model.alpha # fix the learning rate, no decay
print 'done training'
# show topic
n_sent = len(comment_data)
sent_matrix, word_matrix = create_sim_vec(model, n_sent)
print 'done get sent_matrix'
##Rassemblez des documents similaires
#Compression de données par svd(Données denses)
np.savetxt('./D2V/sent_matrix', np.array(sent_matrix))
dimension = 100
lsa = TruncatedSVD(dimension)
info_matrix = lsa.fit_transform(sent_matrix)
np.savetxt('./D2V/info_matrix', np.array(info_matrix))
#Mise en œuvre des kmeans
n_class = 7
labels = sent_integrate(np.array(info_matrix),n_class)
np.savetxt('./D2V/sent_labels.csv', labels,delimiter=',', fmt='%d')
print count_class(labels)
#Comparaison avec ce que les humains ont classé
print count_labeled_data(label_data, labels)
Les données utilisées sont une ligne composée de (0 \ t1 0 1 0 0 0 0 \ txxxx). Les étiquettes étiquetées par l'homme sont marquées de 7 01 indicateurs séparés par des espaces.
Ce n'est pas crédible car les résultats des données expérimentales ne sont pas joints. En vérifiant visuellement 2000 éléments de données, environ 80% ont été classés sans aucune gêne. Au contraire, quand j'ai regardé les étiquettes attachées par les humains, il y en avait environ 30% qui n'avaient pas de sens. (Quelle est la différence de sensibilité ...)
Récemment, j'ai publié un article sans expliquer la méthode ni publier de données expérimentales. Je veux écrire un article (j'aimerais pouvoir l'écrire) sans couper les coins ronds à l'avenir. Nous vous prions de nous excuser pour la gêne occasionnée, mais nous vous serions reconnaissants de bien vouloir signaler toute erreur.
Recommended Posts