[PYTHON] [Réunion de changement d'emploi] Essayez de classer les entreprises en traitant le bouche-à-oreille en langage naturel avec word2vec

introduction

Je m'appelle @ naotaka1128 et je suis en charge du 20e jour de LivesenseAdventCalendar 2016. Actuellement, je suis en charge d'un analyste de données pour un service de bouche à oreille de changement d'emploi appelé réunion de changement d'emploi.

Job Change Conference est le plus grand service de bouche-à-oreille de changement d'emploi au Japon avec des millions d'avis sur les entreprises. Actuellement, nous affichons uniquement le bouche-à-oreille et les notes, mais à l'avenir, nous aimerions analyser le bouche-à-oreille par traitement du langage naturel, etc. et fournir des informations utiles au monde qui n'étaient pas disponibles jusqu'à présent. Nous sommes ici.

Cette fois, comme point de départ, j'analyserai le bouche-à-oreille en utilisant des technologies de traitement du langage naturel telles que word2vec et doc2vec, et classerai les entreprises.

Technologie de traitement du langage naturel à utiliser

word2vec Récemment, la technologie de traitement du langage naturel appelée word2vec est devenue un sujet brûlant. Comme beaucoup d'entre vous le savent peut-être, nous utilisons une grande quantité de phrases pour quantifier les mots dans une représentation vectorielle et nous permettons les calculs suivants entre les mots.

--Roi --Homme + Femme = Reine --Paris --France + Japon = Tokyo

doc2vec Il existe également doc2vec, qui étend word2vec et permet les calculs ci-dessus dans le document lui-même. En gros, c'est comme résumer le vecteur de mots acquis par word2vec.

Avec doc2vec, il est possible de calculer la similitude entre différents documents en numérisant les documents. Je vais considérer le bouche-à-oreille de l'entreprise comme un document et l'analyser avec doc2vec pour analyser la relation entre les entreprises.

Technologie à utiliser

couler

Nous suivrons le flux ci-dessous.

  1. Analyse morphologique des revues d'entreprises
  2. Construisez un modèle de doc2vec avec gensim -Le modèle word2vec est construit en même temps que le modèle doc2vec est construit.
  3. Avec le modèle construit 3-1. Word2vec dans le mot apparaissant dans le bouche à oreille 3-2. Calcul de la similitude entre les entreprises avec doc2vec 3-3. Addition et soustraction entre entreprises avec doc2vec

1. Analyse morphologique des revues d'entreprises

C'est presque la même chose que Essayez de classer les magasins de ramen par traitement du langage naturel.

#Lire des données de bouche à oreille
from io_modules import load_data  #Bibliothèque de lecture DB personnalisée
rows = load_data(LOAD_QUERY, KUCHIKOMI_DB)  # [Nom de la compagnie,Communication de bouche à oreille]

#Extraire le mot radical avec la fonction racine de l'article de référence
from utils import stems  #Mise en œuvre de l'article de référence Presque tel quel
companies = [row[0] for row in rows]
docs = [stems(row[1]) for row in rows]

"""
Je crée les données suivantes
companies = ['Black Company Co., Ltd.', 'Rewarding Co., Ltd.', ...]
docs = [
  ['Récompense', 'pas assez', 'heures supplémentaires', 'beaucoup', 'Beaucoup', ...
  ['Heures supplémentaires de minuit', 'Naturel', 'Épicé', 'je veux mourir', 'Impossible', ...
   ...
]
"""

2. Construisez un modèle de doc2vec avec gensim

Au fait, voici la clé du traitement du langage naturel.

J'aimerais dire, mais je ne fais pas grand-chose parce que je viens d'appeler la bibliothèque. De plus, le calcul a été rapide, et il s'est terminé sans accroc.

#Charge de la bibliothèque
from gensim import models

#Enregistrer les avis sur Gensim
#J'utilise la classe d'extension implémentée dans l'article de référence pour donner le nom de l'entreprise au bouche-à-oreille
sentences = LabeledListSentence(docs, companies)

#Configuration des conditions d'apprentissage de doc2vec
# alpha:Taux d'apprentissage/ min_count:Ignorer les mots qui apparaissent moins de X fois
# size:Nombre de dimensions du vecteur/ iter:Nombre d'itérations/ workers:Nombre d'exécutions parallèles
model = models.Doc2Vec(alpha=0.025, min_count=5,
                       size=100, iter=20, workers=4)

#Préparation pour doc2vec(Construction de liste de mots)
model.build_vocab(sentences)

#Vous pouvez également l'utiliser en appliquant de force le mot vecteur appris de Wikipedia.
# model.intersect_word2vec_format('./data/wiki/wiki2vec.bin', binary=True)

#Exécution de l'apprentissage
model.train(sentences)

#enregistrer
model.save('./data/doc2vec.model')

#Le modèle peut être chargé à partir du fichier après l'entraînement
# model = models.Doc2Vec.load('./data/doc2vec.model')

#La liste des entreprises peut être rappelée après avoir appris car l'ordre peut changer.
companies = model.docvecs.offset2doctag

L'implémentation de LabeledListSentence est la suivante:

#Article de référence: http://qiita.com/okappy/items/32a7ba7eddf8203c9fa1
class LabeledListSentence(object):
    def __init__(self, words_list, labels):
        self.words_list = words_list
        self.labels = labels

    def __iter__(self):
        for i, words in enumerate(self.words_list):
            yield models.doc2vec.LabeledSentence(words, ['%s' % self.labels[i]])

3-1. Word2vec dans le mot apparaissant dans le bouche à oreille

Eh bien, le modèle a été construit en un rien de temps.

Si la précision de word2vec est mauvaise, le résultat de doc2vec sera inévitablement mauvais, donc En jouant avec word2vec ~~, nous vérifierons l'exactitude.

Mots similaires

Tout d'abord, passons du "travail supplémentaire" qui est très populaire pour les revues de changement de poste.

# model.most_similar(positive=[mot]) で似ているmotが出せる
>> model.most_similar(positive=['heures supplémentaires'])
[('travail supplémentaire', 0.8757208585739136),
 ('Heures supplémentaires de service', 0.8720364570617676),
 ('Résidu de rouille', 0.7500427961349487),
 ('Frais d'heures supplémentaires', 0.6272672414779663),
 ('réverbération', 0.6267948746681213),
 ('Travail de vacances', 0.5998174548149109),
 ('De longues heures de travail', 0.5923150777816772),
 ('charge de travail', 0.5819833278656006),
 ('Heures supplémentaires', 0.5778118371963501),
 ('paiement des heures supplémentaires', 0.5598958730697632)]

Des mots similaires sont alignés ...!

Il est étonnant de trouver des abréviations telles que «résidu de rouille» et des fautes de frappe telles que «réverbération». L'ordinateur comprend le concept des "heures supplémentaires"! C'était un moment profondément émouvant.

Je veux que les utilisateurs changent d'emploi positivement chaque jour, donc Vérifions également les mots positifs.

>> model.most_similar(positive=['Récompense'])
[('Kai', 0.9375230073928833),
 ('Le vrai frisson', 0.7799979448318481),
 ('intéressant', 0.7788150310516357),
 ('Intéressant', 0.7710426449775696),
 ('agréable', 0.712959885597229),
 ('Raison de vivre', 0.6919904351234436),
 ('Intéressant', 0.6607719659805298),
 ('joie', 0.6537446975708008),
 ('fierté', 0.6432669162750244),
 ('Ennuyeuse', 0.6373245120048523)]

Il y a un mot qui m'intéresse à la fin, mais c'est une bonne impression. Il semble que le mot lui-même soit compris, donc l'étape suivante consiste à ajouter ou à soustraire le mot.

Addition et soustraction de mots

En regardant les avis sur les changements d'emploi, le contenu lié à la facilité de travail des femmes est populaire. Essayez quelque chose comme "femme seule-femme + homme =?".

Tout d'abord, vérifiez la compréhension de base des mots.

#Des mots qui ressemblent à des femmes
>> model.most_similar(positive=['Femme'])
[('Employée', 0.8745297789573669),
 ('une femme qui travaille', 0.697405219078064),
 ('Femme célibataire', 0.6827554106712341),
 ('Femme', 0.5963315963745117)]

#Des mots qui ressemblent aux hommes
>> model.most_similar(positive=['Masculin'])
[('La gestion', 0.7058243751525879),
 ('actif', 0.6625881195068359),
 ('Traitement spécial', 0.6411184668540955),
 ('Traitement préférentiel', 0.5910355448722839)]

#Des mots qui ressemblent à une femme seule
>> model.most_similar(positive=['Femme célibataire'])
[('Employée', 0.7283456325531006),
 ('Mère célibataire', 0.6969124674797058),
 ('Célibataire', 0.6945561170578003),
 ('Femme', 0.6827554106712341)]

Cela semble aller, alors exécutez l'addition et la soustraction.

#Femme célibataire-Femme+Masculin= ?
# model.most_similar(positive=[Mots à ajouter], negative=[Mot à dessiner])
>> model.most_similar(positive=['Femme célibataire', 'Masculin'], negative=['Femme'])
[('Célibataire', 0.665600597858429),
 ('La gestion', 0.6068357825279236),
 ('Avoir des enfants', 0.58555006980896),
 ('Garçons', 0.530462384223938),
 ('Traitement spécial', 0.5190619230270386)]

Malgré certains résultats suspects, les mots féminins tels que «employée» et «mère célibataire» ont disparu de «femme célibataire» et «célibataire» a été présumé être le mot le plus similaire.

word2vec semble être fait correctement tel quel, donc Nous continuerons à classer les entreprises.

3-2. Calcul de la similitude entre les entreprises avec doc2vec

Ensuite, examinons les relations entre les entreprises.

Tout d'abord, vérifiez auprès d'une entreprise simple qui compte de nombreuses sociétés affiliées.

# model.docvecs.most_similar(positive=[ID de l'entreprise de base])
# ID 53 :Recruter Holdings
>> model.docvecs.most_similar(positive=[53])
[('Recrutez Lifestyle Co., Ltd.', 0.9008421301841736),
 ('Recruter Jobs Co., Ltd.', 0.8883105516433716),
 ('Recrutez Carrier Co., Ltd.', 0.8839867115020752),
 ('Recruter Housing Company Co., Ltd.', 0.8076469898223877),
 ('Recruter Communications Co., Ltd.', 0.7945607900619507),
 ('Career Design Center Co., Ltd.', 0.7822821140289307),
 ('En Japan Co., Ltd.', 0.782017707824707),
 ('Recruter Marketing Partners Co., Ltd.', 0.7807818651199341),
 ('Cyber Agent Co., Ltd.', 0.7434782385826111),
 ('Quick Co., Ltd.', 0.7397039532661438)]

Cela semble trop facile, mais en tant qu'entreprise similaire à Recruit Holdings Recrutez des sociétés affiliées.

Cela semble correct, alors jetons un coup d'œil aux entreprises en général.

# ID 1338 : DeNA
>> model.docvecs.most_similar(positive=[1338])
[('Gree Co., Ltd.', 0.8263522386550903),
 ('Cyber Agent Co., Ltd.', 0.8176108598709106),
 ('Dricom Co., Ltd.', 0.7977319955825806),
 ('Seee Co., Ltd.', 0.787316083908081),
 ('Cyberd Co., Ltd.', 0.7823044061660767),
 ('Dwango Co., Ltd.', 0.767551064491272),
 ('Yahoo Japan Corporation', 0.7610974907875061),
 ('KLab Co., Ltd.', 0.7593647837638855),
 ('Gloops Co., Ltd.', 0.7475718855857849),
 ('NHN\u3000comico Co., Ltd.', 0.7439380288124084)]

M. DeNA, qui a été un sujet brûlant récemment, a déclaré qu'il ressemblait à M. Gree. Il semble que cela ait été jugé lié au jeu, et Cyber et Dricom sont également apparus.

Ça a l'air plutôt bien. Puisqu'il y a une possibilité que les résultats soient biaisés s'il n'y a que des entreprises Web Je regarde aussi des entreprises complètement différentes.

# ID 862 :Honda
>> model.docvecs.most_similar(positive=[862])
[('Toyota Motor Corporation', 0.860333263874054),
 ('Mazda Corporation Inc', 0.843244194984436),
 ('Denso Co., Ltd.', 0.8296780586242676),
 ('Fuji Heavy Industries Ltd.', 0.8261093497276306),
 ('Hino Motor Co., Ltd.', 0.8115691542625427),
 ('Nissan Motor Co., Ltd', 0.8105560541152954),
 ('Daihatsu Industry Co., Ltd.', 0.8088374137878418),
 ('Aisin Seiki Co., Ltd.', 0.8074800372123718),
 ('Honda Technical Research Institute Co., Ltd.', 0.7952905893325806),
 ('Toyota Automatic Lumber Co., Ltd.', 0.7946352362632751)]

# ID 38 :Sony
>> model.docvecs.most_similar(positive=[38])
[('Panasonic Corporation', 0.8186650276184082),
 ('Toshiba Corporation', 0.7851587533950806),
 ('OMRON Corporation', 0.7402874231338501),
 ('NEC', 0.7391767501831055),
 ('Nikon Corporation', 0.7331269383430481),
 ('Sony Global Manufacturing & Operations Co., Ltd.', 0.7183523178100586),
 ('Taiyo Denki Co., Ltd.', 0.7149790525436401),
 ('Sharp Co., Ltd.', 0.7115868330001831),
 ('Pioneer Co., Ltd.', 0.7104746103286743),
 ('Canon Inc', 0.7103182077407837)]

# ID 1688 :McKinsey(Ferme-conseil)
>> model.docvecs.most_similar(positive=[1688])
[('Accenture Co., Ltd.', 0.7885801196098328),
 ('Boston Consulting Group Co., Ltd.', 0.7835338115692139),
 ('Goldman Sachs Securities Co., Ltd.', 0.7507193088531494),
 ('Deloitte Tohmatsu Consulting LLC', 0.7278151512145996),
 ('Sigmaxis Co., Ltd.', 0.6909163594245911),
 ('PwC Advisory LLC', 0.6522221565246582),
 ('Link and Motivation Co., Ltd.', 0.6289964914321899),
 ('Morgan Stanley MUFG Securities Co., Ltd.', 0.6283067464828491),
 ('EY Advisory Co., Ltd.', 0.6275663375854492),
 ('Abeam Consulting Co., Ltd.', 0.6181442737579346)]

Il semble que ça va généralement.

Puisque la similitude entre les entreprises peut être calculée de cette manière (= la distance peut être calculée), L'analyse suivante peut être facilement effectuée.

Le processus ci-dessus est très facile à mettre en œuvre avec scikit-learn.

Cette fois, j'ai en fait essayé de visualiser la distribution par la méthode de l'échelle multidimensionnelle, Si vous écrivez le contenu, cet article sera très long, donc Je voudrais le présenter à un autre moment.

3-3. Addition et soustraction entre entreprises avec doc2vec

Comme word2vec, doc2vec peut ajouter et soustraire entre les documents. Faisons-le pour le moment.

Comme mentionné précédemment, les entreprises qui ressemblaient à Recruit Holdings étaient des sociétés de recrutement.

# ID 53:Sociétés similaires à Recruit Holdings(Republier)
>> model.docvecs.most_similar(positive=[53])
[('Recrutez Lifestyle Co., Ltd.', 0.9008421301841736),
 ('Recruter Jobs Co., Ltd.', 0.8883105516433716),
 ('Recrutez Carrier Co., Ltd.', 0.8839867115020752),
 ('Recruter Housing Company Co., Ltd.', 0.8076469898223877),
 ('Recruter Communications Co., Ltd.', 0.7945607900619507),
 ('Career Design Center Co., Ltd.', 0.7822821140289307),
 ('En Japan Co., Ltd.', 0.782017707824707),
 ('Recruter Marketing Partners Co., Ltd.', 0.7807818651199341),
 ('Cyber Agent Co., Ltd.', 0.7434782385826111),
 ('Quick Co., Ltd.', 0.7397039532661438)]

Ici, "Informations de changement de travail DODA", "Informations de travail à temps partiel et", etc. sont exploités. Ajoutons l'intelligence d'une grande entreprise de ressources humaines.

# model.docvecs.most_similar(positive=[ID de l'entreprise de base,Ajouter plus d'un])
# 「ID 53:Recruter Holdings "+ 「ID 110:Intelligence "= ?
>> model.docvecs.most_similar(positive=[53, 110])
[('Recrutez Carrier Co., Ltd.', 0.888693630695343),
 ('Recruter Jobs Co., Ltd.', 0.865821123123169),
 ('Recrutez Lifestyle Co., Ltd.', 0.8580507636070251),
 ('Career Design Center Co., Ltd.', 0.8396339416503906),
 ('En Japan Co., Ltd.', 0.8285592794418335),
 ('My Navi Co., Ltd.', 0.7874248027801514),
 ('Quick Co., Ltd.', 0.777060866355896),
 ('Recruter Housing Company Co., Ltd.', 0.775804877281189),
 ('Cyber Agent Co., Ltd.', 0.7625365257263184),
 ('Neo Carrier Co., Ltd.', 0.758436381816864)]

Les résultats ci-dessus peuvent être considérés comme suit.

J'ai l'impression d'avoir donné un exemple arbitraire assez facile à comprendre, Il semble que l'on puisse juger que cela se passe bien comme ça.

Résumé et futurs numéros

Dans cet article, nous avons réalisé les contenus suivants en utilisant le bouche-à-oreille de la réunion de changement de carrière.

--Word2vec a fait comprendre à la machine le concept des mots apparaissant dans le bouche-à-oreille, et a effectué un calcul de similitude de mots et une addition / soustraction. --Par doc2vec, laissez la machine comprendre les grandes lignes de l'entreprise et de l'entreprise (idem ci-dessous)

À l'avenir, il sera possible d'effectuer des calculs tels que "mot + mot => entreprise similaire" (exemple: récompense + croissance => ribsense), et l'entreprise avec la culture d'entreprise que les utilisateurs aiment et [Emplois](https: // carrière. Je voudrais essayer une technologie qui permet de rechercher jobtalk.jp/).

Cependant, à l'heure actuelle, il y a un problème fatal, je vais donc le présenter brièvement à la fin. Voici un exemple facile à comprendre.

#Quels mots sont similaires à «noir»?
>> model.most_similar(positive=['noir'])
[('Compagnie noire', 0.8150135278701782),
 ('blanc', 0.7779906392097473),
 ('Entreprise blanche', 0.6732245683670044),
 ('Compagnie noire', 0.5990744829177856),
 ('Noir noir', 0.5734715461730957),
 ('Célèbre', 0.563334584236145),
 ('nettoyer', 0.5561092495918274),
 ('gris', 0.5449624061584473),
 ('Château sans nuit', 0.5446360111236572),
 ('Organisation religieuse', 0.5327660441398621)]

Comme le montre cet exemple, la méthode simple introduite cette fois-ci reconnaît «noir» et «blanc» comme des mots similaires.

Les mots utilisés dans le même contexte sont considérés comme identiques, et leur polarité ne peut être déterminée, et la machine semble reconnaître ce qui suit.

――Je comprends que vous parlez d'heures supplémentaires ――Je ne sais pas s'il y a plus ou moins d'heures supplémentaires

En fait, afin de sortir le résultat de "mot + mot => société similaire", j'ai modifié la bibliothèque gensim et l'ai étendue.

Cependant, j'ai pensé qu'il serait trop malhonnête de l'annoncer à cause de tels problèmes et l'exactitude des résultats ne peut être garantie, je ne l'ai donc pas présentée cette fois. (Je préparais un exemple difficile comme "Live Sense + Overtime + Hard => ??" ...!)

Ce sentiment de défi existe quel que soit le japonais, et il semble que diverses études progressent dans le monde. Parmi eux, une étude que le résultat change considérablement lorsque word2vec est appris après avoir considéré la dépendance (Reference Il semble y avoir /)), et je voudrais faire de tels efforts à l'avenir.

Recommended Posts

[Réunion de changement d'emploi] Essayez de classer les entreprises en traitant le bouche-à-oreille en langage naturel avec word2vec
[Python] Essayez de classer les boutiques de ramen par traitement du langage naturel
Traitement du langage naturel (données originales) avec Word2Vec développé par des chercheurs Google américains
J'ai essayé de classer M. Hanyu et M. Hanyu avec le traitement du langage naturel × classificateur Naive Bayes
[Traitement du langage naturel / PNL] Comment effectuer facilement une traduction arrière par traduction automatique avec Python
Essayez le livre «Introduction au développement d'applications de traitement du langage naturel en 15 étapes» - Chapitre 2 Étape 06 Mémo «Identifiant»
Essayez le livre "Introduction au développement d'applications de traitement du langage naturel en 15 étapes" - Chapitre 2 Étape 02 Mémo "Prétraitement"
Essayez le livre «Introduction au développement d'applications de traitement du langage naturel en 15 étapes» - Chapitre 2 Étape 07 Mémo «Évaluation»
Dockerfile avec les bibliothèques nécessaires pour le traitement du langage naturel avec python
Résumez comment prétraiter le texte (traitement du langage naturel) avec l'api tf.data.Dataset
[Traitement du langage naturel] Prétraitement avec le japonais
Se préparer à démarrer le traitement du langage naturel
Essayez le livre «Introduction au développement d'applications de traitement du langage naturel en 15 étapes» --Chapitre 2 Étape 04 Mémo «Extraction de fonctionnalités»
Essayez le livre "Introduction au développement d'applications de traitement du langage naturel en 15 étapes" - Chapitre 4 Étape 15 Mémo "Collecte de données"
Essayez le livre «Introduction au développement d'applications de traitement du langage naturel en 15 étapes» - Chapitre 3 Étape 08 Mémo «Introduction aux réseaux de neurones»
Essayez le livre "Introduction au développement d'applications de traitement du langage naturel en 15 étapes" --Chapitre 2 Étape 05 Mémo "Conversion de quantité de fonctionnalités"
Essayez le livre "Introduction au développement d'applications de traitement du langage naturel en 15 étapes" - Chapitre 3 Étape 11 Mémo "Embeddings de mots"
3. Traitement du langage naturel avec Python 1-2. Comment créer un corpus: Aozora Bunko
Essayez le livre "Introduction au développement d'applications de traitement du langage naturel en 15 étapes" --Chapitre 3 Étape 12 Mémo "Réseaux de neurones convolutifs"
Essayez le livre «Introduction au développement d'applications de traitement du langage naturel en 15 étapes» --Chapitre 3 Étape 13 Mémo «Réseaux de neurones récurrents»
3. Traitement du langage naturel par Python 2-1. Réseau de co-occurrence
[WIP] Pré-traitement des notes dans le traitement du langage naturel
3. Traitement du langage naturel par Python 1-1. Word N-gram
Essayez de classer les livres d'O'Reilly en les regroupant
J'ai essayé le traitement du langage naturel avec des transformateurs.
J'ai essayé d'extraire des expressions uniques avec la bibliothèque de traitement du langage naturel GiNZA
Essayez le livre "Introduction au développement d'applications de traitement du langage naturel en 15 étapes" -Chapitre 1 Mémo "Connaissances préliminaires avant de commencer les exercices"
La première intelligence artificielle. Je voulais essayer le traitement du langage naturel, donc je vais essayer l'analyse morphologique en utilisant MeCab avec python3.
100 traitement du langage knock-90 (en utilisant Gensim): apprendre avec word2vec
3. Traitement du langage naturel par Python 2-2. Réseau de co-occurrence [mecab-ipadic-NEologd]
[Python] J'ai joué avec le traitement du langage naturel ~ transformers ~
Python: apprentissage profond du traitement du langage naturel: principes de base
Profitons du traitement du langage naturel à l'aide de l'API COTOHA
Insoutenable manque d'attention dans le traitement du langage naturel
Essayez le livre «Introduction au développement d'applications de traitement du langage naturel en 15 étapes» --Chapitre 2 Étape 01 Mémo «Créer un agent de dialogue»
Essayez le livre "Introduction au développement d'applications de traitement du langage naturel en 15 étapes" --Chapitre 2 Étape 03 Mémo "Analyse morphologique et écriture écrite"