Puisqu'il n'y a pas assez de connaissances pour analyser à partir de zéro par moi-même, cette fois NTT Communications a publié API COTOHA A été utilisé.
Cette fois, je pense utiliser le journal de discussion comme base. En parlant de chat au Japon, LINE est le courant dominant, mais LINE a une fonction d'exportation de journal de discussion. Cette fois, nous analyserons à l'aide du journal de discussion exporté par LINE. Au cas où, nous avons obtenu le consentement préalable de la personne.
Je ne parle généralement pas de choses insipides qui ne touchent pas autant aux profils de l'autre, mais c'était un fichier assez volumineux. Commençons par formater ce fichier.
Bien que ce ne soit pas la vraie chose, le journal de discussion de LINE est structuré comme ceci.
Exemple de fichier original
2019/12/22 Sun
17:00 bowtin [Sticker]
17:01 hogehogekun [Sticker]
17:02 hogehogekun Mangeons des ramen si nous avons du temps libre aujourd'hui
2019/12/23 Mon
05:00 bowtin je suis désolé j'ai dormi
05:00 bowtin [Sticker]
08:35 hogehogekun ne pardonne pas
:
:
Premièrement, nous avons éliminé les informations suivantes:
En conséquence, il est devenu comme suit.
Fichier formaté
Si tu es libre aujourd'hui, mangeons des ramen
impardonnable
Puisqu'il s'agit d'une ligne par chat, il est relativement facile à comprendre visuellement. Le nombre de lignes dans le fichier formaté était d'environ 20500.
Au moment du formatage du fichier, il s'agissait d'un journal de discussion assez volumineux avec 20500 lignes. Si j'atteins l'API telle quelle, une erreur est revenue, alors je l'ai divisée en fichiers d'environ 500 lignes chacun. (J'aurais dû utiliser glob ...)
filesplitter.py
with open(file=r'\path\to\file\sample_chatlog.txt', mode='r', encoding='utf-8') as old_file:
lines = old_file.readlines()
for i in range(0, 21000, 500):
line_count = 0 + i
while line_count <= i + 500:
with open(file=r'\path\to\file\splitted_file' + str(i) + '.txt', mode='a+', encoding='utf-8') as new_file:
new_file.write(lines[line_count + i])
line_count += 1
Je pense qu'il y a une meilleure façon de l'écrire, mais pour le moment, le but était de diviser le fichier, donc je vais l'utiliser.
L'API COTOHA a plusieurs API ouvertes au public, mais cette fois, nous utiliserons "Estimation des attributs utilisateur". Fait. Cette API est toujours en version bêta (au 19 février 2020).
Maintenant, passons tout le contenu du premier fichier à l'API.
Résultat estimé du premier fichier
{"civilstatus": "Célibataire", "earnings": "1M-3M", "gender": "Femme", "hobby": ["INTERNET", "MUSIC", "PAINT", "TRAVEL", "TVGAME"], "moving": ["BUS", "WALKING"], "occupation": "Étudiant du Collège"},
c'est incroyable. Environ 80% conviennent.
Je vais continuer.
{"civilstatus": "Célibataire", "earnings": "-1M", "gender": "Femme", "hobby": ["COOKING", "FORTUNE", "GOURMET", "INTERNET", "MUSIC", "TRAVEL"], "location": "Kanto", "moving": ["RAILWAY", "WALKING"]},
Cette fois, j'ai obtenu un résultat légèrement différent. Qu'est-ce que "gains": "-1M"? Y a-t-il un moins dans le revenu annuel? ?? Postscript: J'ai reçu un commentaire qui pourrait être interprété comme "0-1M" au lieu de "-1M". C'est peut-être vrai! Cela signifie «moins de 1M» ou «moins de 1M».
De plus, cette fois, il y avait des informations sur la région. Les informations qui peuvent être extraites semblent légèrement différer selon les données d'origine.
Donc, après cela, je viens de passer environ 40 fichiers à l'API. Puisque la réponse ci-dessus vient d'être renvoyée, j'ai essayé de stocker toutes les réponses renvoyées dans un seul fichier.
Voici le code que j'ai réellement utilisé.
main.py
#Informations de base sur les demandes adressées à l'API
BASE_URL = 'https://api.ce-cotoha.com/hogehoge/'
CLIENT_ID = 'YOUR ID'
CLIENT_SECRET = 'YOUR SECRET'
TOKEN_SERVER_URL = 'https://api.ce-cotoha.com/hogehoge/'
#Une fonction qui acquiert un jeton d'accès API (est-ce une spécification que le jeton d'accès est invalidé à intervalles réguliers?...Je suis désolé si c'est différent)
def authorization():
payload = {
'grantType': 'client_credentials',
'clientId': CLIENT_ID,
'clientSecret': CLIENT_SECRET
}
headers = {
'content-type': 'application/json'
}
response = requests.post(TOKEN_SERVER_URL, data=json.dumps(payload), headers=headers)
auth_info = response.json()
return auth_info['access_token']
#Une fonction qui fait une requête à l'API (l'argument est une liste de chaînes)
def make_request(original_string_list):
headers = {
'Content-Type': 'application/json',
'charset': 'UTF-8',
'Authorization': 'Bearer ' + authorization()
}
payload = {
'document': original_string_list,
'type': 'kuzure' #Il semble qu'il existe un mode pour cela dans le cas de phrases brisées telles que les journaux de discussion
}
response = requests.post(BASE_URL, data=json.dumps(payload), headers=headers)
jsonified_response = response.json()
return jsonified_response['result']
if __name__ == '__main__':
#Listez les noms de fichiers d'environ 40 fichiers originaux (cette fois, nous avons une régularité sous forme de nom de fichier + numéro)
file_list = ['splitted_file' + str(i) + '.txt' for i in range(0, 21000, 500)]
#Obtenez un nom de fichier dans la liste des noms de fichiers et lisez le contenu
for a_file in file_list:
lines = []
with open(file=(r'path\to\file' + a_file), mode='r', encoding='utf-8') as file:
lines = file.readlines()
file.close()
#Jetez le contenu lu à l'API COTOHA tel quel et enregistrez le résultat dans un fichier
with open(file=r'path\to\file\result.txt', mode='a+', encoding='utf-8') as file:
file.write(json.dumps(parse(lines)))
file.close()
sleep(1) #Si vous lancez trop de demandes en peu de temps, cela causera des problèmes, alors attendez 1 seconde
C'est pourquoi certains extraits, mais la liste des résultats ressemble à ceci. Même avec le même âge, il existe quelques variantes.
Résultat d'extraction d'attribut utilisateur (extrait partiel).py
[
{"age": "20-29 ans", "civilstatus": "Célibataire", "gender": "Femme", "hobby": ["COOKING", "FORTUNE", "INTERNET", "TVCOMMEDY"], "moving": ["OTHER", "WALKING"]},
{"age": "20-29 ans", "civilstatus": "Célibataire", "gender": "Femme", "hobby": ["GOURMET", "INTERNET", "SMARTPHONE_GAME", "PAINT", "TVGAME"], "moving": ["CYCLING", "OTHER", "RAILWAY", "WALKING"]},
{"civilstatus": "Célibataire", "earnings": "1M-3M", "gender": "Femme", "hobby": ["COOKING", "GOURMET", "INTERNET", "SHOPPING", "TRAVEL"], "moving": ["CYCLING"]},
{"age": "30-39 ans", "civilstatus": "Célibataire", "earnings": "-1M", "gender": "Femme", "hobby": ["ANIMAL", "CAMERA", "COLLECTION", "COOKING", "INTERNET", "SHOPPING"]},
{"age": "20-29 ans", "civilstatus": "Célibataire", "earnings": "-1M", "gender": "Femme", "hobby": ["COOKING", "FORTUNE", "GOURMET", "PAINT"], "location": "Tokai", "moving": ["RAILWAY"]},
{"age": "20-29 ans", "civilstatus": "Célibataire", "earnings": "-1M", "gender": "Femme", "hobby": ["ANIMAL", "DRAMA", "GYM", "SMARTPHONE_GAME", "MUSIC", "TVGAME"], "moving": ["RAILWAY", "WALKING"]}
]
Je ne suis pas sûr que ce soit le cas, alors j'aimerais ajouter. Je coderai en dur le résultat ci-dessus en tant que dict python.
parse_result.py
results = [
{"age": "20-29 ans", "civilstatus": "Célibataire", "earnings": "-1M", "gender": "Femme", "hobby": ["ANIMAL", "DRAMA", "GYM", "SMARTPHONE_GAME", "MUSIC", "TVGAME"], "moving": ["RAILWAY", "WALKING"]},
{"age": "30-39 ans", "civilstatus": "Célibataire", "earnings": "-1M", "gender": "Femme", "hobby": ["ANIMAL", "CAMERA", "COLLECTION", "COOKING", "INTERNET", "SHOPPING"]}
#Ce qui suit est omis
]
from collections import Counter
import itertools
#Vous pouvez utiliser des collections pour récupérer les valeurs les plus fréquentes
print(Counter([data['age'] for data in dict_array if 'age' in data]).most_common()[0][0])
print(Counter([data['location'] for data in dict_array if 'location' in data]).most_common()[0][0])
print(Counter([data['gender'] for data in dict_array if 'gender' in data]).most_common()[0][0])
print(Counter([data['civilstatus'] for data in dict_array if 'civilstatus' in data]).most_common()[0][0])
print(Counter([data['earnings'] for data in dict_array if 'earnings' in data]).most_common()[0][0])
#Puisqu'il y a une liste dans la liste, je le jette simplement dans une liste plate, puis je récupère les valeurs les plus fréquentes.
print(Counter(list(itertools.chain.from_iterable([data['hobby'] for data in dict_array if 'hobby' in data]))).most_common()[0][0])
Le résumé des valeurs les plus fréquentes est le suivant.
Valeur la plus fréquente
20-29 ans
Kanto
Femme
Célibataire
1M-3M
INTERNET
Je pense que la précision est assez élevée. Au moins, je n'aurais pas dû parler de «si je suis marié» dans une conversation avec cette personne, et bien sûr je n'ai pas posé la simple question «Êtes-vous une femme? L'histoire du revenu annuel peut être un peu.
Au fait, j'ai essayé un peu en discutant avec d'autres personnes, mais c'était plutôt correct.
À l'avenir, vous pourrez peut-être trouver le vrai profil de la personne à partir du journal de discussion dans une certaine mesure avec une application correspondante, etc.! Compte tenu des écarts, il semble que les personnes qui utilisent généralement des caractères différents découvriront qu'ils les utilisent correctement.
En conclusion, il s'est avéré que les gens ont renversé leur profil de manière inattendue dans le chat, mais je pense que c'est difficile à comprendre pour ceux qui sont minutieux dans la création de personnages tels que VTuber et le soi-disant nekama.