Ce que j'ai fait | Événements principaux | |
---|---|---|
Épisode 1 | Balayage automatique à droite | |
Épisode 2 | Envoi automatique de messages | Assorti avec une femme |
Épisode 3 | Bibliothèque | Échangé LINE avec une femme assortie |
numéro 3.Épisode 5 | Réacquisition du jeton d'accès | Vous ne pouviez pas obtenir de jetons avec le code précédent |
Épisode 4 | Collecte de données | Les réponses LINE ne viennent plus |
Épisode 5 | Texte du profil d'analyse des données | Les produits d'information ont été recommandés par des personnes avec lesquelles je suis devenu ami |
Épisode 6 | Édition d'image d'analyse de données | Une vraie fille de connaissance m'appelle récemment tard dans la nuit(?) |
Le code peut être visualisé depuis [GitHub] git.
J'étais occupé à préparer la conférence et quand je m'en suis rendu compte, cela faisait plus de deux mois depuis le dernier article. Cependant, le robot d'exploration a fonctionné tout le temps, j'ai donc beaucoup de données que j'ai commencé à collecter depuis la dernière fois. Elle ne peut pas le faire comme d'habitude.
De nombreuses données ont été collectées. Il y a 10632 femmes qui ont balayé. 72 d'entre eux correspondaient. Cela ne correspond pas à ce à quoi je m'attendais. La dernière fois, j'ai enregistré les données du tableau dans la feuille de calcul et les données d'image dans Google Drive, j'ai donc commencé par les télécharger. Lors du téléchargement d'une feuille de calcul, vous pouvez sélectionner plusieurs formats de fichier, mais lorsque vous le téléchargez avec csv ou tsv, les sauts de ligne dans le texte du profil et les virgules écrites par des étrangers dans le texte du profil sont mauvais et c'était inutilement gênant. Alors enregistrez-le au format .xlsx. De plus, il y avait environ 25 000 images de profil, donc le téléchargement a pris beaucoup de temps. L'analyse se fait sur le notebook jupyter.
Veuillez noter que ces données sont une vérification des données collectées en fonction de mon profil, donc si vous l'exécutez, le résultat peut différer. [^ 1] Soyez prudent.
Tout d'abord, regardons les données des personnes correspondantes.
analytics.py
import pandas as pd
import numpy as np
from tqdm.notebook import tqdm
import matplotlib.pyplot as plt
import seaborn as sns
from collections import Counter
filePath="data/tinder.xlsx"
df=pd.read_excel(filePath)
df.set_index("id", inplace=True)
match = df[df["match"]==1]
Y a-t-il quelqu'un que vous ne reconnaissez pas? ??
Viennent ensuite les données de la personne qui ne correspond pas.
analytics.py
unmatch = df[df["match"]==0]
Cela ressemble à Pat, mais je pense que la personne correspondante remplit le texte du profil plus fermement. Allons vérifier. Il est difficile de définir un "texte de profil bien rempli", mais pour l'instant, vérifions simplement le nombre de caractères dans le texte du profil.
analytics.py
%matplotlib inline
sns.distplot(unmatch["bio"].apply(lambda w:len(str(w))), color="b", bins=30)
sns.distplot(match["bio"].apply(lambda w:len(str(w))), color="r", bins=30)
Le résultat est le suivant. Ceux qui correspondent au rouge et ceux qui ne correspondent pas au bleu.
Après tout, je pense que le rouge a moins de caractères proches de zéro que le bleu. En fait, il semble qu'il existe de nombreux comptes qui n'écrivent pas un seul caractère dans le profil pour ceux qui ne correspondent pas. Les comptes avec un profil vide sont moins susceptibles de correspondre même si vous faites glisser votre doigt vers la droite, il semble donc préférable de ne pas glisser.
Tout d'abord, je voudrais vérifier les mots inclus dans la phrase du profil. Pour les phrases de profil, l'analyse morphologique est réalisée à l'aide du moteur d'analyse morphologique MeCab [1] et du dictionnaire étendu mecab-ipadic-NEologd [2].
Vous pouvez installer MeCab avec `` pip install mecab-python3 ''. Pour la méthode d'installation de mecab-ipadic-NEologd, le texte officiel [3] est très bien organisé, veuillez donc vous y référer. Vous pouvez choisir différentes options, mais pour ceux qui sont vraiment gênants
$git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git ~/neologd
$echo yes | ~/neologd/bin/install-mecab-ipadic-neologd -n -a
Ensuite, vous pouvez l'installer.
Appelez mecab de Python pour diviser votre déclaration de profil mot par mot.
L'appel simple de mecab utilise un dictionnaire standard, alors spécifiez NEologd comme option. L'emplacement du dictionnaire peut être obtenu avec ```echo mecab-config --dicdir
" / mecab-ipadic-neologd "` ``.
mecab.py
import subprocess
import MeCab
cmd = 'echo `mecab-config --dicdir`"/mecab-ipadic-neologd"'
path = (subprocess.Popen(cmd, stdout=subprocess.PIPE,
shell=True).communicate()[0]).decode('utf-8')
m = MeCab.Tagger("-d {0}".format(path))
print(m.parse("Elle a dansé amoureuse de Penpainappoappopen."))
#>>
#Sa nomenclature,Synonyme,Général,*,*,*,Petite amie,Petite amie,Petite amie
#Est un assistant,Assistance,*,*,*,*,Est,C,sensationnel
#Nomenclature du stylo Appo,Nomenclature propriétaire,Général,*,*,*,Pen-Pineapple-Apple-Pen,Pen Ananas Apple Pen,Pen Ananas Apple Pen
#Et des mots auxiliaires,Assistants parallèles,*,*,*,*,Quand,À,À
#Danse substantif,Nomenclature propriétaire,Général,*,*,*,Danse d'amour,Danse d'amour,Danse d'amour
#Auxiliaire,Assistant de cas,Général,*,*,*,À,Wo,Wo
#Verbe dansant,Indépendance,*,*,Cinq étapes, La ligne,Connexion continue,Danse,Impair,Impair
#Verbe auxiliaire,*,*,*,Spécial,Forme basique,Ta,Ta,Ta
#.. symbole,Phrase,*,*,*,*,。,。,。
#EOS
Ceci est utilisé pour extraire les mots inclus dans la phrase de profil de chacune des personnes appariées et non appariées.
analytics.py
def getWord(df):
retval = []
for bio in df.bio:
parse = m.parse(str(bio)).strip().split("\n")
for p in parse:
if ("\t" in p) == False:
continue
word, desc = p.split("\t")
if desc.split(",")[0] in ("nom", "verbe", "adjectif", "形容verbe", "Coalm", "adverbe", "conjonction", "感verbe", "symbole"): # 助詞と助verbeを除きたかった
retval.append(word)
return retval
bio_match = getWord(match)
bio_unmatch = getWord(unmatch)
La liste des mots obtenus est affichée par ordre de fréquence d'occurrence. Tout d'abord, de la personne qui correspond.
analytics.py
df_bio_match = pd.DataFrame.from_dict(
Counter(bio_match), orient="index").reset_index().rename(columns={"index":"word",0:"count"})
sns.barplot(data=df_bio_match.sort_values(
"count", ascending=False)[:20], x="word", y="count")
plt.xticks(rotation="vertical")
Le tofu qui se produit est quelque chose comme un espace vide. Peut-être thinsp? Je me demandais qui utilisait ∇ (Nabla), alors je l'ai vérifié et j'ai trouvé qu'il était utilisé pour des lettres faciales comme (・ ∇ ・). Vient ensuite la personne qui ne correspond pas.
analytics.py
df_bio_unmatch = pd.DataFrame.from_dict(
Counter(bio_unmatch), orient="index").reset_index().rename(columns={"index":"word",0:"count"})
sns.barplot(data=df_bio_unmatch.sort_values(
"count", ascending=False)[:20], x="word", y="count")
plt.xticks(rotation="vertical")
Il semble y avoir une différence dans la tendance, il semble que ce ne soit pas le cas ... Par exemple, on peut voir que les personnes qui correspondent ont tendance à ne pas percer les phrases. Aussi, bien qu'il y ait beaucoup de gens qui écrivent "comme" en kanji avec ou sans correspondance, aucun d'entre eux ne correspond à ceux qui écrivent "suki" en hiragana. ~~ Est-ce une mine terrestre? ~~ Pour être honnête, je ne pense pas que ce soit dans la fourchette d'erreur car le nombre d'échantillons de personnes appariées est petit, mais cela vaut peut-être la peine de s'en souvenir.
Enfin, vectorisons la déclaration de profil à l'aide de Doc2Vec. Il y a quelques années, DNN, qui vectorise le mot Word2Vec, est devenu un gros sujet dans le domaine de la PNL, mais Doc2Vec est un algorithme qui l'applique à des phrases plutôt qu'à des mots. L'explication de Word2Vec a été utile dans [4], et l'explication de Doc2Vec a été utile dans [5] [6]. L'implémentation utilise une bibliothèque appelée gensim [7]. Veuillez l'installer avec `` pip install gensim ''. Pour le code spécifique, je me suis référé à [8].
analytics.py
#Divisez les données en données d'entraînement et données de test
df_train, df_test = train_test_split(df, random_state=8888)
#Divisez les phrases de profil en mots à l'aide de MeCab
m_wakati = MeCab.Tagger("-d {0} -Owakati".format(path)) #Options MeCab-En ajoutant Owakati, les mots sont séparés par des espaces sans générer de mots partiels.
bios=[]
for bio in df_train.bio:
bio = m_wakati.parse(str(bio)).strip()
bios.append(bio)
#Convertir les données dans un format pouvant être traité par gensim
trainings = [TaggedDocument(words = data.split(),tags = [i]) for i,data in enumerate(bios)]
#Apprendre doc2vec
doc2vec = Doc2Vec(documents=trainings, dm=1, vector_size=300, window=4, min_count=3, workers=4)
#Obtenez un vecteur de données d'entraînement
X_train = np.array([doc2vec.docvecs[i] for i in range(df_train.shape[0])])
#Obtenez l'étiquette de réponse correcte pour les données d'entraînement
y_train = df_train["match"]
#Obtenez un vecteur de données de test et une étiquette correcte
X_test = np.array([doc2vec.infer_vector(m.parse(str(bio)).split(" ")) for bio in df_test.bio])
y_test = df_test["match"]
Visualisons le texte vectorisé en utilisant PCA. Tout d'abord, à partir des données d'entraînement.
analytics.py
from sklearn.decomposition import PCA
pca = PCA()
X_reduced = pca.fit_transform(X_train)
plt.scatter(X_reduced[y_train==0][:,0], X_reduced[y_train==0][:,1], c="b", label="No Match")
plt.scatter(X_reduced[y_train==1][:,0], X_reduced[y_train==1][:,1], c="r", label="Match")
plt.legend()
Pour ceux qui ne correspondent pas, il y a un certain nombre de personnes qui ont une deuxième composante principale importante, tandis que la deuxième composante principale de celles qui correspondent est généralement autour de 0. Regardons également les données de test.
analytics.py
X_test_reduced = pca.transform(X_test)
plt.scatter(X_test_reduced[y_test==0][:,0], X_test_reduced[y_test==0][:,1], c="b", label="No Match")
plt.scatter(X_test_reduced[y_test==1][:,0], X_test_reduced[y_test==1][:,1], c="r", label="Match")
plt.legend()
Ceux qui correspondent peuvent voir que la deuxième composante principale est regroupée près de 0.
Maintenant que les phrases ont été vectorisées, appliquons l'apprentissage automatique pour les classer. Classez les vecteurs de déclaration de profil à l'aide d'une machine à vecteurs de support. Puisque les données manipulées cette fois sont des données déséquilibrées extrêmement biaisées, si la limite de décision est tracée docilement, tous les profils seront jugés comme "ne correspondant pas". Cela ne sert à rien. En premier lieu, en regardant en arrière sur ce que je voulais faire cette fois, je ne voulais pas améliorer la précision de l'apprentissage automatique, mais elle le voulait. Focalisation sur chaque élément de la matrice de confusion,
La description | Remarques | |
---|---|---|
TP | Déterminé à correspondre à la personne qui correspond réellement | C'est ce que vous recherchez |
TN | Jugez que les personnes qui ne correspondent pas réellement ne sont pas appariées | Vous pouvez réduire le balayage à droite inutile |
FP | Déterminé à faire correspondre les personnes qui ne correspondent pas réellement | Le balayage à droite est perdu une fois |
FN | Jugez que la personne qui correspond réellement ne correspond pas | Je ne peux pas rencontrer la personne destinée |
Evidemment FN est le pire et je veux l'éviter à tout prix. D'un autre côté, il est souhaitable que FP ne se produise pas, mais peu importe si cela se produit un peu. Par conséquent, dans cette tâche, il est nécessaire que le rappel soit aussi élevé que possible. En revanche, la précision et les valeurs F sont acceptables même si elles sont faibles. Bien sûr, si vous prédisez que tous les cas "correspondent", vous pouvez obtenir un rappel élevé en échange de la destruction de la précision et de la valeur F [^ 2], nous avons donc introduit l'apprentissage automatique pour éviter cela. Pour cette raison, si le rappel diminue, je dois dire que c'est une chute. Par conséquent, cette fois, nous allons adopter une stratégie pour estimer la probabilité d'appariement par Regressor et fixer un seuil assez bas pour éliminer uniquement les «méchants qui ne sont évidemment pas susceptibles de correspondre». Le soupçon est un coup droit. Auc est utilisé comme indice d'évaluation.
analytics.py
from sklearn.svm import SVR
from sklearn.metrics import roc_auc_score
model = SVR(C=100.0)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print(roc_auc_score(y_test, y_pred))
#>>0.6196
Over auc0.6! N'est-ce pas un très bon résultat? Des paramètres de seuil spécifiques seront définis une fois l'image analysée. L'article est devenu long, je suis donc ici aujourd'hui. Veuillez attendre avec impatience la prochaine édition d'image de profil.
L'épisode 6 est [ici] ep.6
[1]https://taku910.github.io/mecab/ [2]https://github.com/neologd/mecab-ipadic-neologd [3]https://github.com/neologd/mecab-ipadic-neologd/blob/master/README.ja.md [4] Yasuki Saito, Deep Learning from scratch ❷ - Traitement du langage naturel [5] https://kitayamalab.wordpress.com/2016/12/10/doc2vec paragraph-vector-algorithm / [6]https://deepage.net/machine_learning/2017/01/08/doc2vec.html [7]https://radimrehurek.com/gensim/index.html [8]https://qiita.com/asian373asian/items/1be1bec7f2297b8326cf
[^ 1]: Je voudrais vérifier quel genre de différence se produira si la même expérience est menée entre beau et moi. Non, vous ne voudrez peut-être pas le voir. [^ 2]: Et cela a été réalisé grâce à la stratégie de balayage qui avait été mise en œuvre jusqu'à présent, appelée balayage tout à droite.
Recommended Posts