Actuellement, je suis stagiaire pour l'analyse de données chez EXIDEA Co., Ltd., qui développe des outils d'écriture SEO. Cela fait quatre mois que j'ai commencé à travailler, mais en raison de l'influence de Corona, je n'ai jamais rencontré personne dans l'entreprise. Mais quelles sont les caractéristiques des buveurs en ligne réguliers et des réunions quotidiennes? Je comprends enfin. De plus, j'entends souvent le mot ** «recrutement» ** lors de récentes réunions mensuelles. Non limité aux sociétés de capital-risque, je pense que de nombreuses entreprises utilisent Wantedly pour se concentrer sur les activités de recrutement. Dans cet article, ** L'article d'histoire de Wantedly sera une histoire pour re-reconnaître les caractéristiques et les sentiments de l'entreprise que vous souhaitez transmettre aux candidats à l'aide du package nlplot qui facilite la visualisation du langage naturel. ** **
Le code source est disponible sur Github, alors n'hésitez pas à nous contacter. https://github.com/yuuuusuke1997/Article_analysis
・ MacOS ・ Python 3.7.6 ・ Cahier Jupyter ・ Coque Zsh
Dans ce grattage, nous effectuerons la transition de la page Web comme suit et n'acquérirons que tous les articles de notre société. Avant le grattage, nous le ferons après avoir obtenu l'autorisation préalable de Wantedly. Merci de votre compréhension à l'avance.
La page Web de Wantedly charge l'article suivant en faisant défiler vers le bas de la page. Par conséquent, Selenium, qui automatise les opérations du navigateur, est utilisé dans les emplacements minimaux nécessaires pour acquérir des données. Pour faire fonctionner le navigateur, vous devez préparer un pilote ** compatible avec votre ** navigateur et installer la ** bibliothèque Selenium **. Depuis que j'aime Google Chrome, j'ai téléchargé le pilote Chrome à partir de ici et l'ai placé dans le répertoire suivant. De plus, veuillez remplacer * sous Utilisateurs par votre propre nom d'utilisateur, le cas échéant.
python
$ cd /Users/*/documents/nlplot
$ ls
article_analysis.ipynb
chromedriver
post_articles.csv
user_dic.csv
Installez la bibliothèque Selenium avec pip.
python
$ pip install selenium
Si vous voulez en savoir plus sur Selenium de l'installation à la méthode d'exploitation, vous pouvez vous référer à l'article ici. Maintenant que nous sommes prêts, nous allons en fait gratter.
article_analysis.ipynb
import json
import re
import time
import pandas as pd
import requests
from bs4 import BeautifulSoup as bs4
from selenium import webdriver
base_url = 'https://www.wantedly.com'
def scrape_path(url):
"""
Obtenez l'URL de la page de détail de l'espace à partir de la page de liste d'articles
Parameters
--------------
url: str
URL de la page de liste d'articles
Returns
----------
path_list: list of str
Liste contenant l'URL de la page de détail de l'espace
"""
path_list = []
response = requests.get(url)
soup = bs4(response.text, 'lxml')
time.sleep(3)
# <script data-placeholder-key="wtd-ssr-placeholder">Obtenez le contenu
#Au début du caractère json'//'Retirer.string[3:]
feeds = soup.find('script', {'data-placeholder-key': 'wtd-ssr-placeholder'}).string[3:]
feed = json.loads(feeds)
# {'body'}de'spaces'Avoir
feed_spaces = feed['body'][list(feed['body'].keys())[0]]['spaces']
for i in feed_spaces:
space_path = base_url + i['post_space_path']
path_list.append(space_path)
return path_list
path_list = scrape_path('https://www.wantedly.com/companies/exidea/feed')
def scrape_url(path_list):
"""
Obtenez l'URL de la page de détails de l'histoire à partir de la page de détails de l'espace
Parameters
--------------
path_list: list of str
Liste contenant l'URL de la page de détail de l'espace
Returns
----------
url_list: list of str
Liste contenant les URL des pages de détails de l'histoire
"""
url_list = []
#Lancer chrome(chromedriver est placé dans le même répertoire que ce fichier)
driver = webdriver.Chrome('chromedriver')
for feed_path in path_list:
driver.get(feed_path)
#Faites défiler vers le bas de la page et quittez le programme si vous ne pouvez plus faire défiler
#Hauteur avant le défilement
last_height = driver.execute_script("return document.body.scrollHeight")
while True:
#Faites défiler vers le bas de la page
driver.execute_script('window.scrollTo(0, document.body.scrollHeight);')
#Le traitement au sélénium est trop rapide pour charger une nouvelle page, donc attente forcée
time.sleep(3)
#Hauteur après défilement
new_height = driver.execute_script("return document.body.scrollHeight")
# last_la hauteur est nouvelle_Faites défiler jusqu'à ce qu'il corresponde à la hauteur de la hauteur
if new_height == last_height:
break
else:
last_height = new_height
continue
soup = bs4(driver.page_source, 'lxml')
time.sleep(3)
# <div class="post-space-item" >Obtenez l'élément de
post_space = soup.find_all('div', class_='post-content')
for post in post_space:
# <"post-space-item">de<a>Obtenir l'élément
url = base_url + post.a.get('href')
url_list.append(url)
url_list = list(set(url_list))
#Fermer la page Web
driver.close()
return url_list
url_list = scrape_url(path_list)
def get_text(url_list, wrong_name, correct_name):
"""
Obtenir le texte de la page de détails de l'histoire
Parameters
--------------
url_list: list of str
Liste contenant les URL des pages de détails de l'histoire
wrong_name: str
Nom d'entreprise erroné
correct_name: str
Nom correct de l'entreprise
Returns
----------
text_list: list of str
Liste contenant des histoires
"""
text_list = []
for url in url_list:
response = requests.get(url)
soup = bs4(response.text, 'lxml')
time.sleep(3)
# <section class="article-description" data-post-id="○○○○○○">Dans<p>Obtenez tous les éléments
articles = soup.find('section', class_='article-description').find_all('p')
for article in articles:
#Fractionner par délimiteur
for text in re.split('[\n!?!?。]', article.text):
#Prétraitement
replaced_text = text.lower() #Conversion en minuscules
replaced_text = re.sub(wrong_name, correct_name, replaced_text) #Convertir le nom de l'entreprise en majuscules
replaced_text = re.sub(r'https?://[\w/:%#\$&\?\(\)~\.=\+\-…]+', '', replaced_text) #Supprimer l'URL
replaced_text = re.sub('[0-9]', '', replaced_text) #Exclure les nombres
replaced_text = re.sub('[,:;-~%()]', '', replaced_text) #Remplacez le symbole par un espace demi-largeur
replaced_text = re.sub('[,:; · ~% () ※ "" 【】 (Lol)]', '', replaced_text) #Remplacez le symbole par un espace demi-largeur
replaced_text = re.sub(' ', '', replaced_text) # \Supprimer u3000
text_list.append(replaced_text)
text_list = [x for x in text_list if x != '']
return text_list
text_list = get_text(url_list, 'exidea', 'EXIDEA')
Enregistrez le texte récupéré dans un fichier CSV.
nlplot_articles.ipynb
df_text = pd.DataFrame(text_list, columns=['text'])
df_text.to_csv('post_articles.csv', index=False)
À partir de là, je vais commencer à installer MeCab et à faire diverses préparations, mais cela ne fonctionnera pas aussi bien que prévu et mon cœur sera brisé, donc j'espère que cela mènera à la motivation.
En premier lieu, pourquoi faites-vous une tâche aussi fastidieuse? Certaines personnes peuvent penser que taper sur $ brew install mecab ne fera qu'un seul coup. Cependant, afin d'obtenir le résultat de l'analyse morphologique avec nlplot comme vous le souhaitez, il est nécessaire d'enregistrer le code de caractère dans le dictionnaire utilisateur avec UTF-8, en utilisant le nom de la division et le mot de la société comme nomenclature appropriée. À la suite de l'installation avec brew pour plus de facilité, le code de caractère est devenu EUC-JP et j'ai dû prendre la peine deux fois. Par conséquent, si vous souhaitez vous en tenir au résultat de sortie, veuillez essayer la méthode à partir de maintenant. Si vous souhaitez l'essayer facilement, veuillez l'installer avec une infusion en vous reportant à ce qui suit.
Préparation de l'environnement pour l'utilisation de MeCab sur Mac
MeCab Depuis le site officiel, utilisez la commande curl pour télécharger ** MeCab lui-même ** et le ** dictionnaire IPA **. Cette fois, installez-le dans l'environnement local. Le premier est l'installation de MeCab lui-même.
python
#Créer le répertoire d'installation de mecab dans l'environnement local
$ mkdir /Users/*/opt/mecab
$ cd /Users/*/opt/mecab
#Dans le répertoire courant-o Télécharger en spécifiant le nom du fichier avec l'option
$ curl -Lo mecab-0.996.tar.gz 'https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7cENtOXlicTFaRUE'
#Décompressez le fichier de code source
$ tar zxfv mecab-0.996.tar.gz
$ cd mecab-0.996
#Code de caractère UTF-Vérifiez s'il peut être compilé en spécifiant 8
$ ./configure --prefix=/Users/*/opt/mecab --with-charset=utf-8
#Compilez le Makefile créé par configure
$ make
#Vérifiez s'il fonctionne correctement avant l'installation
$ make check
#Fichier binaire compilé par make/Users/*/opt/Installer sur mecab
$ make install
Done
Si vous vous demandez ce qu'est configure, make, make install, here peut être utile.
Maintenant qu'il est installé, parcourons le chemin afin que nous puissions exécuter la commande mecab.
python
#Vérifier le type de coque
$ echo $SHELL
/bin/zsh
# .Ajouter un chemin à zshrc
$ echo 'export PATH=/Users/*/opt/mecab/bin:$PATH' >> ~/.zshrc
"""
Mise en garde:Dernier par shell de connexion(~/.zshrc)changement
Exemple) $ echo 'export PATH=/Users/*/opt/mecab/bin:$PATH' >> ~/.bash_profile
"""
#Reflète les paramètres de la coque
$ source ~/.zshrc
#Vérifiez si le pass a réussi
$ which mecab
/Users/*/opt/mecab/bin/mecab
Done
Article de référence: Qu'est-ce que PATH?
python
#Déplacer vers le répertoire de départ
$ cd /Users/*/opt/mecab
#Dans le répertoire courant-o Télécharger en spécifiant le nom du fichier avec l'option
$ curl -Lo mecab-ipadic-2.7.0-20070801.tar.gz 'https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7MWVlSDBCSXZMTXM'
#Décompressez le fichier de code source
$ tar zxfv mecab-ipadic-2.7.0-20070801.tar.gz
$ cd mecab-ipadic-2.7.0-20070801
#Code de caractère UTF-Vérifiez s'il peut être compilé en spécifiant 8
$ ./configure --prefix=/Users/*/opt/mecab --with-charset=utf-8
#Compilez le Makefile créé par configure
$ make
#Fichier binaire compilé par make/Users/*/opt/Installer sur mecab
$ make install
Done
#Confirmation du code de caractère
#Le code de caractère est EUC-Pour JP, UTF-Changer en 8
$ mecab -P | grep config-charset
config-charset: EUC-JP
#Fichier de paramètres de recherche
$ find /Users -name dicrc
/Users/*/opt/mecab/mecab-ipadic-2.7.0-20070801/dicrc
$ vim /Users/*/opt/mecab/mecab-ipadic-2.7.0-20070801/dicrc
[Avant le changement] config-charset = EUC-JP
[Après modification] config-charset = UTF-8
$ mecab
J'arrêterai les humains! Jojo
Mon nom,Synonyme,Général,*,*,*,je,moi,moi
Est un assistant,Assistance,*,*,*,*,Est,C,sensationnel
Nomenclature humaine,Général,*,*,*,*,Humain,Ningen,Ningen
Auxiliaire,Assistant de cas,Général,*,*,*,À,Wo,Wo
Quitter le verbe,Indépendance,*,*,Un pas,Forme basique,Arrêtez,Yamel,Yamel
Assistant Zo,Aide finale,*,*,*,*,Je suis désolé,Zo,Zo
!! symbole,Général,*,*,*,*,!,!,!
Jojo substantif,Nomenclature propriétaire,Organisation,*,*,*,*
EOS
#Vérifiez le répertoire du dictionnaire IPA
$ find /Users -name ipadic
/Users/*/opt/mecab/lib/mecab/dic/ipadic
python
#Déplacer vers le répertoire de départ
cd /Users/*/opt/mecab
#Téléchargez le code source depuis github
$ git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
$ cd mecab-ipadic-neologd
#Entrez "oui" sur l'écran pour exécuter et vérifier le résultat
$ ./bin/install-mecab-ipadic-neologd -n
Done
#Confirmation du code de caractère
#Le code de caractère est EUC-Pour JP, UTF-Changer en 8
$ mecab -d /Users/*/opt/mecab/lib/mecab/dic/mecab-ipadic-neologd -P | grep config-charset
config-charset: EUC-JP
#Fichier de paramètres de recherche
$ find /Users -name dicrc
/Users/*/opt/mecab/lib/mecab/dic/mecab-ipadic-neologd/dicrc
$ vim /Users/*/opt/mecab/lib/mecab/dic/mecab-ipadic-neologd/dicrc
[Avant le changement] config-charset = EUC-JP
[Après modification] config-charset = UTF-8
#Vérifiez le répertoire du dictionnaire NEologd
$ find /Users -name mecab-ipadic-neologd
/Users/*/opt/mecab/lib/mecab/dic/mecab-ipadic-neologd
$echo «Je quitte les humains!| mecab -d /Users/*/opt/mecab/lib/mecab/dic/mecab-ipadic-neologd
"Symbole,Ouvrir les parenthèses,*,*,*,*,“,“,“
J'arrêterai les humains! nom,Nomenclature propriétaire,Général,*,*,*,Je vais quitter les humains!,Orehaningen Woyamerzo,Orewaningen Oyamelzo
Jojo substantif,Général,*,*,*,*,*
EOS
Officiel Github: mecab-ipadic-neologd
python
#Enfin pip pour pouvoir utiliser mecab avec python3
$ pip install mecab-python3
Le dictionnaire utilisateur crée des mots que le dictionnaire système ne peut pas gérer en donnant un sens à l'utilisateur.
Tout d'abord, créez un fichier csv selon le format du mot que vous souhaitez ajouter. Visualisez-le une fois, et s'il y a un mot qui vous intéresse, essayez d'ajouter le mot au fichier csv.
python
"""
format
Type de surface,ID de contexte gauche,ID de contexte correct,Coût,Partie,Partie細分類1,Partie細分類2,Partie細分類3,Type d'utilisation,Type d'utilisation,Prototype,en train de lire,prononciation
"""
#création de fichier csv
$ echo 'Étudiant stagiaire,-1,-1,1,nom,Général,*,*,*,*,*,*,*,Stagiaire Say'"\n"'La valeur de base,-1,-1,1,nom,Général,*,*,*,*,*,*,*,La valeur de base'"\n"'Se rencontrer,-1,-1,1,nom,Général,*,*,*,*,*,*,*,Se rencontrer' > /Users/*/Documents/nlplot/user_dic.csv
#Vérifiez le code de caractère du fichier csv
$ file /Users/*/Documents/nlplot/user_dic.csv
/users/*/documents/nlplot/user_dic.csv: UTF-8 Unicode text
Ensuite, compilez le fichier csv créé dans un dictionnaire utilisateur.
python
#Créer un répertoire de destination pour le dictionnaire utilisateur
$ mkdir /Users/*/opt/mecab/lib/mecab/dic/userdic
"""
-d Répertoire avec dictionnaire système
-u utilisateur-Où enregistrer le dictionnaire
-f Code de caractère du fichier CSV
-t Code de caractère du dictionnaire utilisateur/Où enregistrer le fichier csv
"""
##Créer un dictionnaire utilisateur
/Users/*/opt/mecab/libexec/mecab/mecab-dict-index \
-d /Users/*/opt/mecab/lib/mecab/dic/mecab-ipadic-neologd \
-u /Users/*/opt/mecab/lib/mecab/dic/userdic/userdic.dic \
-f utf-8 -t utf-8 /Users/*/Documents/nlplot/user_dic.csv
# userdic.Confirmez que le dic est terminé
$ find /Users -name userdic.dic
/Users/*/opt/mecab/lib/mecab/dic/userdic/userdic.dic
Maintenant que nous avons installé mecab et créé un dictionnaire utilisateur, nous allons passer à l'analyse morphologique.
Article de référence: Comment ajouter des mots
Commencez par charger le fichier csv créé lors du scraping.
nlplot_articles.ipynb
df = pd.read_csv('post_articles.csv')
df.head()
Dans nlplot, nous voulons produire des phrases mot par mot, nous effectuons donc une analyse morphologique avec la nomenclature.
article_analysis.ipynb
import MeCab
def download_slothlib():
"""
Chargez SlothLib et créez un mot d'arrêt
Returns
----------
slothlib_stopwords: list of str
Liste contenant des mots vides
"""
slothlib_path = 'http://svn.sourceforge.jp/svnroot/slothlib/CSharp/Version1/SlothLib/NLP/Filter/StopWord/word/Japanese.txt'
response = requests.get(slothlib_path)
soup = bs4(response.content, 'html.parser')
slothlib_stopwords = [line.strip() for line in soup]
slothlib_stopwords = slothlib_stopwords[0].split('\r\n')
slothlib_stopwords = [x for x in slothlib_stopwords if x != '']
return slothlib_stopwords
stopwords = download_slothlib()
def add_stopwords():
"""
Ajouter des mots vides aux mots vides
Returns
----------
stopwords: list of str
Liste contenant des mots vides
"""
add_words = ['Voir', 'Compagnie', 'J'adorerais', 'Par tous les moyens', 'Récit', '弊Compagnie', 'Humain', 'Quoi', 'article', 'Autre que', 'Hmm', 'de', 'Moi', 'Sa', 'comme ça']
stopwords.extend(add_words)
return stopwords
stopwords = add_stopwords()
def tokenize_text(text):
"""
Extraire uniquement la nomenclature par analyse morphologique
Parameters
--------------
text: str
Texte stocké dans le dataframe
Returns
----------
nons_list: list of str
Une liste qui ne contient que la nomenclature après analyse morphologique
"""
#Spécifiez le répertoire dans lequel le dictionnaire utilisateur et le dictionnaire neologd sont enregistrés
tagger = MeCab.Tagger('-d /Users/*/opt/mecab/lib/mecab/dic/mecab-ipadic-neologd -u /Users/*/opt/mecab/lib/mecab/dic/userdic/userdic.dic')
node = tagger.parseToNode(text)
nons_list = []
while node:
if node.feature.split(',')[0] in ['nom'] and node.surface not in stopwords:
nons_list.append(node.surface)
node = node.next
return nons_list
df['words'] = df['text'].apply(tokenize_text)
article_analysis.ipynb
df.head()
python
$ pip install nlplot
3-2. uni-gram
nlplot_articles.ipynb
import nlplot
#Spécifiez les mots de df
npt = nlplot.NLPlot(df, taget_col='words')
# top_Top 2 des mots qui apparaissent fréquemment dans n, min_Spécifiez les sous-mots fréquents avec freq
#Top 2 mots: ['Compagnie', 'travaux']
stopwords = npt.get_stopword(top_n=2, min_freq=0)
npt.bar_ngram(
title='uni-gram',
xaxis_label='word_count',
yaxis_label='word',
ngram=1,
top_n=50,
stopwords=stopwords,
save=True
)
3-3. bi-gram
nlplot_articles.ipynb
npt.bar_ngram(
title='bi-gram',
xaxis_label='word_count',
yaxis_label='word',
ngram=2,
top_n=50,
stopwords=stopwords,
save=True
)
3-4. tri-gram
nlplot_articles.ipynb
npt.bar_ngram(
title='tri-gram',
xaxis_label='word_count',
yaxis_label='word',
ngram=3,
top_n=50,
stopwords=stopwords,
save=True
)
3-5. tree map
nlplot_articles.ipynb
npt.treemap(
title='tree map',
ngram=1,
stopwords=stopwords,
width=1200,
height=800,
save=True
)
3-6. wordcloud
nlplot_articles.ipynb
npt.wordcloud(
stopwords=stopwords,
max_words=100,
max_font_size=100,
colormap='tab20_r',
save=True
)
nlplot_articles.ipynb
npt.build_graph(stopwords=stopwords, min_edge_frequency=13)
display(
npt.node_df, npt.node_df.shape,
npt.edge_df, npt.edge_df.shape
)
npt.co_network(
title='All sentiment Co-occurrence network',
color_palette='hls',
save=True
)
3-8. sunburst chart
nlplot_articles.ipynb
npt.sunburst(
title='All sentiment sunburst chart',
colorscale=True,
color_continuous_scale='Oryel',
width=800,
height=600,
save=True
)
Article de référence: La bibliothèque "nlplot" qui permet de visualiser et d'analyser facilement les langages naturels a été publiée
En le visualisant, j'ai senti que j'étais en mesure d'incarner la ligne directrice d'action "Le partage" qu'EXIDEA chérit à nouveau. En particulier, l'action est heureuse et sincère. Et l'altruiste est au premier plan dans l'article, et par conséquent, je pense que j'ai pu rencontrer des amis qui peuvent parler du meilleur environnement de travail, de ce que je veux réaliser et de mes inquiétudes. Bien qu'il soit encore rare que je puisse contribuer à l'entreprise dans mon travail quotidien, j'aimerais maximiser ce que je peux faire maintenant, comme m'engager pleinement dans la tâche qui m'incombe et l'envoyer à l'extérieur.
Dans cet article, j'ai pu réaffirmer l'importance du prétraitement. J'ai commencé avec le désir d'essayer nlplot, mais quand je l'ai visualisé sans prétraitement, la nomenclature appropriée était affichée en morphologie sur bi-gramme et tri-gramme, et le résultat était désastreux. Cela en valait la peine, et je pense que le meilleur avantage était que j'ai pu en apprendre davantage sur Linux lors de l'installation de mecab et de la création d'un dictionnaire utilisateur. Plutôt que de l'acquérir en tant que connaissance, je vais l'utiliser pour un apprentissage futur afin de ne pas négliger l'essentiel de bouger réellement mes mains.
Cela fait longtemps, mais merci d'avoir lu jusqu'ici. Si vous constatez des erreurs, je vous serais très reconnaissant de bien vouloir les signaler dans les commentaires.