Création d'une extension Chrome qui utilise la puissance du traitement du langage naturel pour chasser les sites sombres du monde

Motivation

Épidémie de virus Corona et seulement de sombres nouvelles de nos jours ... → Si vous ne voyez que les bonnes nouvelles, vous devriez vous sentir positif!

Ce que j'ai fait

Une extension Chrome qui rend les résultats de recherche Google plus difficiles à voir à mesure que le contenu s'assombrit. Chrome Store: Opty github

Écran réel

Site sombre Site lumineux
Capture d'écran 2020-04-22 11.01.17.png Capture d'écran 2020-04-22 11.03.22.png

Comment utiliser

Installez simplement l'extension Chrome depuis ici et recherchez! Référence: Comment installer l'extension

environnement

Personnel: 2 étudiants universitaires (Tomohiro Inoue, Takeshi Watanabe) Période de production: 1 jour Cloud Functions Python 3.7 JavaScript MeCab

Configuration du système

図.png

Jugement de luminosité

Décomposez une phrase en mots et jugez si chaque élément est clair ou sombre.

MeCab est utilisé pour décomposer des phrases en mots. Par exemple

morph.py


import MeCab

tagger = MeCab.Tagger()
result = tagger.parse('Le nouveau virus corona est une épidémie dans le monde entier.')
print(result)

Lorsque vous exécutez le processus

Nouvelle nomenclature,Général,*,*,*,*,Nouveau modèle,Singata,Singata
Corona substantif,Général,*,*,*,*,couronne,couronne,couronne
Virus substantif,Général,*,*,*,*,virus,virus,virus
Est un assistant,Assistant de cas,Général,*,*,*,Mais,Géorgie,Géorgie
Monde substantif,Général,*,*,*,*,monde,Sekai,Sekai
Nomenclature cible,suffixe,Racine du verbe adjectif,*,*,*,Cible,Texte,Texte
Auxiliaire,Auxiliaire,*,*,*,*,À,ré,ré
Grand préfixe,Connexion de nom,*,*,*,*,Gros,Mourir,Mourir
Nomenclature tendance,Changer de connexion,*,*,*,*,tendance,Ryukou,Ryuko
Verbe shi,Indépendance,*,*,Sahen / Suru,Type continu,Faire,Shi,Shi
Te assistant,Assistant de connexion,*,*,*,*,main,Te,Te
Je verbe,Non indépendant,*,*,Un pas,Type continu,Est,je,je
Masu verbe auxiliaire,*,*,*,Spécial / masse,Forme basique,Masu,truite,truite
.. symbole,Phrase,*,*,*,*,。,。,。
EOS

Il est démonté comme. Extrayez la forme inutilisée de chaque mot du résultat décomposé et utilisez-la.

[Dictionnaire japonais de polarité d'évaluation](http://www.cl.ecei.tohoku.ac.jp/index.php?Open] publié par le laboratoire Inui Suzuki de l'Université de Tohoku pour déterminer la luminosité des éléments % 20Resources% 2FJapanese% 20Sentiment% 20Polarity% 20Dictionary) a été utilisé.

Dans ce dictionnaire, les mots japonais sont classés en positif (clair) ou négatif (sombre), et la nomenclature est classée en trois niveaux: p (positif), n (négatif) et e (ni l'un ni l'autre).

wago.121808.pn


Négatif (expérience)
Abandon négatif (expérience)
Négatif (expérience)
Négatif (expérience)
Négatif (expérience)

pn.csv.m3.120408.trim


Merci p ~ Il y a / améliore (existence / nature)
Merci p ~ Il y a / améliore (existence / nature)
Merci ennui n ~ devient / devient (évaluation / émotion) subjectif
Être e ~ tel qu'il est (évaluation / sentiment) Subjectivité
Telle qu'elle est, elle devient / devient (évaluation / émotion) subjective

Chaque composant de la phrase est remplacé par 1 s'il est positif, -1 s'il est négatif et 0 dans le cas contraire, et la moyenne est utilisée comme luminosité de la phrase.

Voici les points sur lesquels je suis tombé lors du développement.

Point de chute 1: dictionnaire de polarité ≠ Luminosité pour chaque mot

Je pensais facilement que je devais diviser la phrase en mots et chercher dans le dictionnaire de polarité avec les mots comme clés, mais ce n'était pas si simple. Dans le dictionnaire de polarité, non seulement un seul mot tel que «bon», mais également un élément composé de deux mots ou plus (dans ce cas, «bon» + «pas») tel que «mauvais» sont enregistrés. Par conséquent, j'ai réorganisé le dictionnaire afin qu'il puisse être recherché par des éléments constitués de plusieurs mots, et je l'ai fait pickle avant de l'utiliser.

main.py


    #Stocker dans le dictionnaire
    for line in pn_noun_file:
        line = line.replace('\n', '').split('\t')
        if line[1] == 'e': #Ignorer les lignes qui ne sont ni positives ni négatives
            continue
        #Une liste de mots enregistrés dans le dictionnaire de polarité convertis en formes de base
        basic_form = convert_to_basic_form(line[0]) 
        #Ignorer les lignes pour lesquelles la forme de base ne peut pas être obtenue et les lignes pour lesquelles la forme de base est un caractère
        if not basic_form:
            continue
        elif len(basic_form) == 1 and len(basic_form[0]) == 1:
            continue
        key = basic_form[0]
        if key not in pn_dict:
            pn_dict[key] = {}
        #Stocké comme une combinaison de luminosité et une combinaison de formes de base
        pn_dict[key][(',').join(basic_form)] = 1 if line[1] == 'p' else - 1

Point de trébuchement 2: pas amusant = positif?

Alors que «mauvais» est enregistré comme un élément négatif dans le dictionnaire de polarité, «pas amusant» n'est pas enregistré, il est donc jugé comme un mot positif en ne réagissant qu'à la partie «amusante». C'était. Par conséquent, si une telle chose n'existe pas, la valeur de luminosité de la partie précédente est inversée.

main.py


#Jugement PN. Renvoie la valeur PN moyenne de l'élément demandé.
def calc_pn(basic_form):
    pn_dict = pickle.load(open('pn.pkl', 'rb'))
    pn_values = [] #Stocke la valeur de jugement PN de chaque élément du texte

    while basic_form:
        pn_value = 0
        del_num = 1  #Numéro à supprimer de la liste
        beginning = basic_form[0] #Définir le premier mot à clé

        if beginning in pn_dict:
            for index, word in enumerate(basic_form):
                if word == "。" or word == "、":  #Si la phrase se brise, arrêtez
                    break
                if index == 0:
                    joined_basic_forms = beginning
                else:
                    joined_basic_forms += ',' + word

                if word == "Absent" and del_num == index: #Inversion négative positive requise
                    print('reverse')
                    pn_value *= -1
                    del_num = index + 1

                if joined_basic_forms in pn_dict[beginning]:
                    pn_value = pn_dict[beginning][joined_basic_forms]
                    del_num = index + 1

        pn_values.append(pn_value)
        del basic_form[0:del_num]

    return sum(pn_values) / len(pn_values)

Points d'amélioration

--Slow: actuellement, il faut environ 3 secondes entre l'affichage des résultats de la recherche et la réflexion du style.

finalement

J'ai eu le temps de m'abstenir de corona, alors je l'ai fait comme étude pendant les vacances de printemps. D'autres sont en cours de développement! Si vous le souhaitez, suivez LGTM et Twitter!

Extension: Opty Twitter: Tomohiro Inoue, Takeshi Watanabe

Les références

  1. J'ai fait une gemme qui porte un jugement négatif / positif

Recommended Posts

Création d'une extension Chrome qui utilise la puissance du traitement du langage naturel pour chasser les sites sombres du monde
[Traitement du langage naturel] J'ai essayé de visualiser les remarques de chaque membre de la communauté Slack
Types de prétraitement dans le traitement du langage naturel et leur puissance
Comment rédiger un test de traitement utilisant BigQuery
[Go] Créez une commande CLI pour changer l'extension de l'image
Une fonction qui mesure le temps de traitement d'une méthode en python
[Word2vec] Visualisons le résultat du traitement en langage naturel des avis des entreprises
[python] Une note que j'ai commencé à comprendre le comportement de matplotlib.pyplot
[Python] Un programme qui fait pivoter le contenu de la liste vers la gauche