[PYTHON] [Explication de la mise en œuvre] Classer les actualités de livingoor par BERT japonais x apprentissage non supervisé (clustering de maximisation de la quantité d'informations): Google Colaboratory (PyTorch)

Dans cet article, nous allons implémenter et expliquer comment le clustering de maximisation de la quantité d'informations de l'apprentissage non supervisé est effectué pour les actualités liveoor à l'aide de la version japonaise de BERT dans Google Colaboratory.

--Contenu jusqu'à la vectorisation des phrases en utilisant la version japonaise de BERT dans Google Colaboratory,

J'ai expliqué à ce sujet dans les articles publiés jusqu'à présent, alors veuillez d'abord jeter un œil ici.

** Liste des séries ** [1] [Explication de la mise en œuvre] Comment utiliser la version japonaise de BERT dans Google Colaboratory (PyTorch) [2] [Explication de la mise en œuvre] Classification des actualités Livedoor dans la version japonaise BERT: Google Colaboratory (PyTorch) [3] [Explication de la mise en œuvre] Science du cerveau et apprentissage non supervisé. Classer MNIST par clustering de maximisation de la quantité d'informations [4] * Cet article [Explication de l'implémentation] Classifier les actualités de livingoor par apprentissage japonais BERT x non supervisé (regroupement de maximisation de la quantité d'informations)


La dernière fois, j'ai écrit un article sur l'image numérique manuscrite du MNIST. Invariant Information Clustering for Unsupervised Image Classification and Segmentation

Regroupement de l'apprentissage non supervisé à l'aide d'informations mutuelles IIC(Invariant Information Clustering) A été effectuée.

Cette fois, nous montrerons ce qui se passe lorsque chaque article de news de livingoor news est vectorisé avec le japonais BERT et qu'il est appris sans supervision (clustering) avec IIC.

Dans le cas de MNIST, le résultat de la classification est divisé en fonction de l'étiquette numérique de l'apprentissage supervisé, et il est bon qu'il puisse être utilisé pour un apprentissage supervisé, mais qu'en est-il des données textuelles?

J'essaierai ceci.

Le flux de cette implémentation est

  1. Téléchargez les actualités de Liveoor et convertissez-les en DataLoader de PyTorch
  2. Vectoriser les articles de news de livingoor avec BERT
  3. Modèle d'apprentissage en profondeur IIC disponible
  4. Apprenez le réseau IIC
  5. Inférer les données de test

Ce sera.

Le code d'implémentation de cet article se trouve dans le référentiel GitHub ci-dessous.

GitHub: Comment utiliser la version japonaise de BERT dans Google Colaboratory: code de mise en œuvre Il s'agit de 4_BERT_livedoor_news_IIC_on_Google_Colaboratory.ipynb.

1. Téléchargez les actualités de Liveoor et convertissez-les en DataLoader de PyTorch

Le contenu jusqu'à présent est [[2] [Explication de la mise en œuvre] Classification des actualités Livedoor en version japonaise BERT: Google Colaboratory (PyTorch)](https: //)

En l'état, je vais omettre la publication dans cet article.

Enfin, créez un DataLoader d'entraînement, de validation et de test en procédant comme suit:

#Créer un DataLoader (simplement appelé iterater dans le contexte de torchtext)
batch_size = 16  #BERT utilise environ 16 et 32

dl_train = torchtext.data.Iterator(
    dataset_train, batch_size=batch_size, train=True)

dl_eval = torchtext.data.Iterator(
    dataset_eval, batch_size=batch_size, train=False, sort=False)

dl_test = torchtext.data.Iterator(
    dataset_test, batch_size=batch_size, train=False, sort=False)

#Assembler dans un objet dictionnaire
dataloaders_dict = {"train": dl_train, "val": dl_eval}

Vectoriser les articles d'actualité de Liveoor avec BERT

Vectorisez le corps de l'article de liveoor news avec la version japonaise de BERT

Ce sera une vectorisation du document.

Cette fois, je traiterai simplement le vecteur incorporé de 768 dimensions du premier mot de BERT ([CLS]) comme un vecteur de document (il existe différentes manières de créer un vecteur de document et sa validité).

Comme c'est une perte de temps de vectoriser les données d'un document à chaque fois lors de la formation d'un réseau neuronal pour le clustering par IIC, créez un DataLoader qui a été converti en vecteur de document par BERT.

La mise en œuvre est la suivante:

Tout d'abord, préparez le corps principal de BERT. Il s'agit d'une version paramétrée de l'Université de Tohoku qui a déjà appris le japonais.

from transformers.modeling_bert import BertModel

#Modèle de paramètre appris japonais de BERT
model = BertModel.from_pretrained('bert-base-japanese-whole-word-masking')
model.eval()
print('Configuration réseau terminée')

Ensuite, définissez une fonction à vectoriser avec BERT.

#Définir une fonction à vectoriser avec BERT


def vectorize_with_bert(net, dataloader):

    #Vérifiez si le GPU peut être utilisé
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    print("Appareil utilisé:", device)
    print('-----start-------')

    #Réseau vers GPU
    net.to(device)

    #Si le réseau est réparé dans une certaine mesure, accélérez-le
    torch.backends.cudnn.benchmark = True

    #Mini taille de lot
    batch_size = dataloader.batch_size

    #Boucle pour récupérer un mini-lot à partir du chargeur de données
    for index, batch in enumerate(dataloader):
        #batch est un objet dictionnaire Text and Lable
        device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
        inputs = batch.Text[0].to(device)  #Phrase
        labels = batch.Label.to(device)  #étiquette

        #Calcul à terme
        with torch.set_grad_enabled(False):

            #Entrez dans Ber
            result = net(inputs)

            # sequence_Extraire le premier mot vecteur de sortie
            vec_0 = result[0]  #Le premier 0 est la séquence_Afficher la sortie
            vec_0 = vec_0[:, 0, :]  #Tous les lots. Tous les 768 éléments du premier 0ème mot
            vec_0 = vec_0.view(-1, 768)  #Taille[batch_size, hidden_size]Conversion en

            #Organisez les données vectorisées dans une liste de torches
            if index == 0:
                list_text = vec_0
                list_label = labels
            else:
                list_text = torch.cat([list_text, vec_0], dim=0)
                list_label = torch.cat([list_label, labels], dim=0)

    return list_text, list_label

Vectorisez les DataLoaders de formation, de validation et de test avec les fonctions définies.

#Convertir DataLoader en version vectorisée
#Cela prend un peu moins de 5 minutes

list_text_train, list_label_train = vectorize_with_bert(model, dl_train)
list_text_eval, list_label_eval = vectorize_with_bert(model, dl_eval)
list_text_test, list_label_test = vectorize_with_bert(model, dl_test)

Faites ensuite de cette liste un ensemble de données PyToch.

#Convertir la liste des torches en jeu de données

from torch.utils.data import TensorDataset

dataset_bert_train = TensorDataset(
    list_label_train.view(-1, 1), list_text_train)
dataset_bert_eval = TensorDataset(list_label_eval.view(-1, 1), list_text_eval)
dataset_bert_test = TensorDataset(list_label_test.view(-1, 1), list_text_test)

Enfin, définissez l'ensemble de données sur DataLoader. Ce DataLoader est utilisé pour l'apprentissage du réseau IIC (Invariant Information Clustering).

#Faites-en un chargeur de données
from torch.utils.data import DataLoader

batch_size = 1024

dl_bert_train = DataLoader(
    dataset_bert_train, batch_size=batch_size, shuffle=True, drop_last=True)
# drop_le dernier est le dernier lot de mini-lots_Ignorer si la taille ne suffit pas

dl_bert_eval = DataLoader(
    dataset_bert_eval, batch_size=batch_size, shuffle=False)
dl_bert_test = DataLoader(
    dataset_bert_test, batch_size=batch_size, shuffle=False)

Avec ce qui précède, le texte des news de livingoor a été vectorisé en japonais BERT.

Il ne vous reste plus qu'à regrouper ces données vectorisées.

Préparation 3: Préparer le modèle d'apprentissage en profondeur IIC

Ensuite, préparez un modèle d'apprentissage en profondeur d'IIC. Cette partie est essentiellement

[Explication de la mise en œuvre] Science du cerveau et apprentissage non supervisé. Classer MNIST par clustering de maximisation de la quantité d'informations

Il a la même configuration que.

Le modèle de réseau neuronal doit correspondre à un vecteur de 768 dimensions. Cette fois, le montant de la caractéristique est converti en répétant le pliage de 1d.

Le clustering 10 fois le nombre de clusterings réellement estimé par overclustering est également effectué en même temps, et le réseau qui capture des fonctionnalités infimes est formé.

import torch.nn as nn
import torch.nn.functional as F

OVER_CLUSTRING_RATE = 10


class NetIIC(nn.Module):
    def __init__(self):
        super(NetIIC, self).__init__()

        # multi-la tête ne fait pas cette fois
        self.conv1 = nn.Conv1d(1, 400, kernel_size=768, stride=1, padding=0)
        self.bn1 = nn.BatchNorm1d(400)
        self.conv2 = nn.Conv1d(1, 300, kernel_size=400, stride=1, padding=0)
        self.bn2 = nn.BatchNorm1d(300)
        self.conv3 = nn.Conv1d(1, 300, kernel_size=300, stride=1, padding=0)
        self.bn3 = nn.BatchNorm1d(300)

        self.fc1 = nn.Linear(300, 250)
        self.bnfc1 = nn.BatchNorm1d(250)

        #Correspond-il à 9 catégories d'actualités liveoor? 9 catégories à attendre
        self.fc2 = nn.Linear(250, 9)

        # overclustering
        #En regroupant plus que l'hypothèse réelle, il sera possible de capturer des changements infimes dans le réseau.
        self.fc2_overclustering = nn.Linear(250, 9*OVER_CLUSTRING_RATE)

    def forward(self, x):
        x = x.view(x.size(0), 1, -1)
        x = F.relu(self.bn1(self.conv1(x)))

        x = x.view(x.size(0), 1, -1)
        x = F.relu(self.bn2(self.conv2(x)))

        x = x.view(x.size(0), 1, -1)
        x = F.relu(self.bn3(self.conv3(x)))

        x = x.view(x.size(0), -1)
        x_prefinal = F.relu(self.bnfc1(self.fc1(x)))

        # multi-N'utilisez pas la tête
        y = F.softmax(self.fc2(x_prefinal), dim=1)
        y_overclustering = F.softmax(self.fc2_overclustering(
            x_prefinal), dim=1)  # overclustering

        return y, y_overclustering

Définit une fonction d'initialisation pour les paramètres de pondération du modèle.

import torch.nn.init as init


def weight_init(m):
    """Initialisation du poids"""
    if isinstance(m, nn.Conv1d):
        init.normal_(m.weight.data)
        if m.bias is not None:
            init.normal_(m.bias.data)
    elif isinstance(m, nn.BatchNorm1d):
        init.normal_(m.weight.data, mean=1, std=0.02)
        init.constant_(m.bias.data, 0)
    elif isinstance(m, nn.Linear):
        # Xavier
        # init.xavier_normal_(m.weight.data)

        # He
        init.kaiming_normal_(m.weight.data)

        if m.bias is not None:
            init.normal_(m.bias.data)

Définit comment calculer la fonction de perte pour IID.

Calculez la quantité d'informations mutuelles entre la sortie (x_out) lorsque les données vectorisées cible sont entrées dans NetIID et la sortie (x_tf_out) lorsque les données converties des données vectorisées cible sont entrées dans NetIID.

Voir l'article précédent pour plus de détails sur l'implémentation ici.

[Explication de la mise en œuvre] Science du cerveau et apprentissage non supervisé. Classer MNIST par clustering de maximisation de la quantité d'informations

#Définition de la fonction de perte par IIS
#Référence: https://github.com/RuABraun/phone-clustering/blob/master/mnist_basic.py
import sys


def compute_joint(x_out, x_tf_out):
    bn, k = x_out.size()
    assert (x_tf_out.size(0) == bn and x_tf_out.size(1) == k), '{} {} {} {}'.format(
        bn, k, x_tf_out.size(0), x_tf_out.size(1))

    p_i_j = x_out.unsqueeze(2) * x_tf_out.unsqueeze(1)  # bn, k, k
    p_i_j = p_i_j.sum(dim=0)  # k, k
    p_i_j = (p_i_j + p_i_j.t()) / 2.  # symmetrise
    p_i_j = p_i_j / p_i_j.sum()  # normalise
    return p_i_j


def IID_loss(x_out, x_tf_out, EPS=sys.float_info.epsilon):
    # has had softmax applied
    bs, k = x_out.size()
    p_i_j = compute_joint(x_out, x_tf_out)
    assert (p_i_j.size() == (k, k))

    p_i = p_i_j.sum(dim=1).view(k, 1).expand(k, k)
    p_j = p_i_j.sum(dim=0).view(1, k).expand(k, k)

    # avoid NaN losses. Effect will get cancelled out by p_i_j tiny anyway
    #Ceci est la version 1 de PyTorch.S'il est 3 ou plus, une erreur se produira.
    # https://discuss.pytorch.org/t/pytorch-1-3-showing-an-error-perhaps-for-loss-computed-from-paired-outputs/68790/3
    #p_i_j[(p_i_j < EPS).data] = EPS
    #p_j[(p_j < EPS).data] = EPS
    #p_i[(p_i < EPS).data] = EPS

    p_i_j = torch.where(p_i_j < EPS, torch.tensor(
        [EPS], device=p_i_j.device), p_i_j)
    p_j = torch.where(p_j < EPS, torch.tensor([EPS], device=p_j.device), p_j)
    p_i = torch.where(p_i < EPS, torch.tensor([EPS], device=p_i.device), p_i)

    # https://qiita.com/Amanokawa/items/0aa24bc396dd88fb7d2a
    #Ajout du poids alpha pour référence

    alpha = 2.0
    loss = (- p_i_j * (torch.log(p_i_j) - alpha *
                       torch.log(p_j) - alpha*torch.log(p_i))).sum()

    return loss

Ensuite, définissez la transformation à appliquer aux données vectorisées d'intérêt.

Cette fonction de conversion est la clé de l'IIC.

Dans le cas de données d'image, la conversion affine (rotation / étirement), le changement de rapport d'aspect, l'écrêtage (écrêtage) et l'ajout de bruit sont effectués selon l'augmentation normale des données.

Que dois-je faire avec les données textuelles ...

Lors de l'augmentation des données dans les compétitions telles que Kaggle, nous les traduisons une fois dans une autre langue.

Cette fois, je vais simplement ajouter du bruit en fonction de l'écart type de toutes les données vectorielles.

#Définition d'une fonction qui ajoute du bruit aux données
device = 'cuda' if torch.cuda.is_available() else 'cpu'
tensor_std = list_text_train.std(dim=0).to(device)


def perturb_data(x):
    y = x.clone()
    noise = torch.randn(len(tensor_std)).to(device)*tensor_std*2.0
    noise = noise.expand(x.shape[0], -1)
    y += noise

    return y

4: Apprenez le réseau IIC

Maintenant que les modèles DataLoader et IIC sont prêts, formons les poids du modèle IIC.

Tout d'abord, définissez la fonction de formation.

#Définition de la fonction d'apprentissage


def train(total_epoch, model, train_loader, optimizer, device):

    #Mettre le réseau en mode formation
    model.train()

    #Programmateur de taux d'apprentissage CosAnnealing
    scheduler = torch.optim.lr_scheduler.CosineAnnealingWarmRestarts(
        optimizer, T_0=2, T_mult=2, eta_min=0)

    for epoch in range(total_epoch):
        for batch_idx, (target, data) in enumerate(train_loader):

            #Changement du taux d'apprentissage
            scheduler.step()

            data_perturb = perturb_data(data)  #Donner du bruit et créer des données converties

            #Envoyer si envoyé au GPU
            data = data.to(device)
            data_perturb = data_perturb.to(device)

            #Initialisation de la fonction d'optimisation
            optimizer.zero_grad()

            #Entrez dans le réseau neuronal
            output, output_overclustering = model(data)
            output_perturb, output_perturb_overclustering = model(data_perturb)

            #Calcul des pertes
            loss1 = IID_loss(output, output_perturb)
            loss2 = IID_loss(output_overclustering,
                             output_perturb_overclustering)
            loss = loss1 + loss2

            #Mis à jour pour réduire les pertes
            loss.backward()
            optimizer.step()

        #Sortie de journal
        if epoch % 50 == 0:
            print('Train Epoch {} \tLoss1: {:.6f} \tLoss2: {:.6f} \tLoss_total: {:.6f}'.format(
                epoch, loss1.item(), loss2.item(), loss1.item()+loss2.item()))

    return model, optimizer

Dans la formation ci-dessus, le taux d'apprentissage est modifié en préparant les redémarrages à chaud du recuit cosinus du planificateur.

Il s'agit d'un appareil qui modifie le taux d'apprentissage comme indiqué ci-dessous pour faciliter l'apprentissage des paramètres de la solution locale à la solution minimale globale lorsque la valeur est soudainement augmentée à partir d'une petite valeur.

sgdr.jpg Figure: devis https://www.kaggle.com/c/imet-2019-fgvc6/discussion/94783

Nous effectuons des apprentissages. Cette fois, la taille du lot est de 1 024 et les données elles-mêmes sont d'environ 4 000, nous augmentons donc le nombre d'époques.

Il faut moins de 5 minutes pour apprendre.

#Mise en œuvre de l'apprentissage (moins de 5 minutes)

total_epoch = 1000
optimizer = torch.optim.Adam(net.parameters(), lr=5e-4)  #Fonction d'optimisation

model_trained, optimizer = train(
    total_epoch, net, dl_bert_train, optimizer, device)

Maintenant que la formation est terminée, déduisons avec les données de test. Pour faciliter la compréhension des résultats, préparez un DataLoader pour le test avec une taille de mini-lot 1 et inférez un par un. Stockez le résultat.

La fonction est définie ci-dessous.

#Vérifiez les résultats du cluster de classification du modèle
import numpy as np

#Préparer le chargeur de données pour un test de taille 1 en mini-lot
dl_bert_test = DataLoader(
    dataset_bert_test, batch_size=1, shuffle=False)


def test(model, device, test_loader):
    model.eval()

    out_targs = []
    ref_targs = []

    #Préparer une liste pour la sortie
    total_num = len(test_loader)
    # index, (target_label, inferenced_label)
    output_list = np.zeros((total_num, 2))

    with torch.no_grad():
        for batch_idx, (target, data) in enumerate(test_loader):
            data = data.to(device)
            target = target.to(device)
            outputs, outputs_overclustering = model(data)

            #Ajouter le résultat de la classification à la liste
            out_targs.append(outputs.argmax(dim=1).cpu())
            ref_targs.append(target.cpu())

            #Mettez les résultats dans une liste
            output_list[batch_idx, 0] = target.cpu()  #Étiquette de réponse correcte
            output_list[batch_idx, 1] = outputs.argmax(dim=1).cpu()  #Étiquette de prédiction

    out_targs = torch.cat(out_targs)
    ref_targs = torch.cat(ref_targs)

    return out_targs.view(-1, 1).numpy(), ref_targs.numpy(), output_list

5. Inférer les données de test

Effectuer une inférence avec des données de test.

#Effectuer une inférence avec des données de test

out_targs, ref_targs, output_list = test(model_trained, device, dl_bert_test)

Vérifiez le tableau de fréquence de la matrice de confusion des résultats d'inférence dans les données de test.

#Faire une matrice de confusion
matrix = np.zeros((9, 9))

#Créez une classe de réponse correcte pour les actualités liveoor verticalement et une table de fréquences pour la classe jugée horizontalement
for i in range(len(out_targs)):
    row = ref_targs[i]
    col = out_targs[i]
    matrix[row][col] += 1

np.set_printoptions(suppress=True)
print(matrix)

Le résultat de sortie est le suivant.

[[ 55.   0.   1.   0.   4.  47.   2.  76.   0.]
 [  3.  40.   4.   0.  14.   1.   1.   0. 116.]
 [  7.  39.  21.   4.  16.   3.   6.   3.   1.]
 [ 11.  60.  16.   4.  13.   8.  27.   2.  17.]
 [  8.   6.  20. 107.   1.   8.  16.   0.   1.]
 [ 11.  17.  15.   0.  40.   6.  78.   7.   0.]
 [ 18.   3.  65.  40.  13.  15.  14.   3.   1.]
 [ 63.   7.  45.  11.   2.  42.   7.   1.   1.]
 [ 27.   0.   6.   0.   4.  61.   1.  61.   1.]]

De plus, l'axe vertical est dans l'ordre suivant après vérification du contenu de dic_id2cat.

{0: 'sports-watch',
 1: 'dokujo-tsushin',
 2: 'livedoor-homme',
 3: 'peachy',
 4: 'smax',
 5: 'movie-enter',
 6: 'it-life-hack',
 7: 'kaden-channel',
 8: 'topic-news'}

Premièrement, les clusters qui étaient supposés être des classes, comme dans MNIST, ne correspondent pas parfaitement. Je pense que c'est quelque chose comme ça.

Si l'on vous demande de «classer un grand nombre de documents en plusieurs types», je pense que même les humains classeront (regrouperont) selon divers modèles. Lorsqu'on m'a demandé de classer les news de livingoor en 9 catégories, cette fois j'ai obtenu ce résultat.

Le deuxième cluster estimé est principalement "it-life-hack" et "kaden-channel". Le troisième des clusters estimés est «smax (smartphones et gadgets)». Le dernier cluster inféré semble être un cluster avec beaucoup de "communication unique".

L'avant-dernier est principalement "sports-watch" et "topic-news". Les classes "sports-watch" et "topic-news" sont dans le cluster estimé Il est séparé en 0e, 5e et 7e.

Le texte du 5ème cluster et le texte du 7ème cluster de "sports-watch" Le texte du 5ème cluster et le texte du 7ème cluster dans "topic-news"

Jetons un coup d'œil aux fonctionnalités du cluster 5 et du cluster 7.

#Vérifiez le résultat du cluster
#「sports-Texte du cinquième groupe de "montre", texte du septième groupe
#「topic-Texte du 5e groupe de "nouvelles", texte du 7e groupe
#Jetons un coup d'œil aux fonctionnalités du cluster 5 et du cluster 7.

import pandas as pd

df2 = pd.DataFrame(output_list)
df2.columns=["Classe de réponse correcte", "Cluster estimé"]
df2.head()
df2[(df2['Classe de réponse correcte']==0) & (df2['Cluster estimé']==5)].head()

La sortie est la suivante.

Classe correcte Cluster estimé
21	0.0	5.0
59	0.0	5.0
126	0.0	5.0
142	0.0	5.0
153	0.0	5.0

Jetons un coup d'œil aux 21e et 59e phrases de l'ensemble de données de test.

#Le document original est placé dans df. Regardez environ 300 caractères.
print(df.iloc[21, 0][:300])
print(df.iloc[59, 0][:300])

La première phrase du cinquième groupe de "montre de sport" est

Le 29 du mois dernier, après avoir pris sa retraite en tant que lutteur professionnel, Kotetsu Yamamoto, qui était aimé par les fans en tant que joueur entraîneur, commentateur et arbitre, est décédé subitement des suites d'une encéphalopathie hypoxique et a profondément attristé les fans et les parties liées. À ce moment-là, "Weekly Asahi Performing Arts" sorti le 7 de cette semaine rapportait une action incroyable qui montre "immédiatement avant sa mort" de M. Yamamoto dans le coin "NEWS SHOT!". L'ancien rédacteur hebdomadaire de lutte professionnelle Tarzan Yamamoto, qui a commenté le magazine, a déclaré: "Le corps, qui mesure 170 cm et pèse 113 kg, maintient toujours des muscles qui rappellent l'ère active. Il est aussi dur que les jeunes. Après l'entraînement, j'avais un appétit incroyable quand j'avais 68 ans, mais en fait, M. Yamamoto était diabétique », dit-il.

est devenu.

De même,

La première phrase du 7e groupe de «montre de sport» est

Entretien avec M. Hiromitsu Ochiai, ancien directeur des Dragons de Chunichi, où des mots choquants tels que «tout est devenu fou», «je n'ai jamais touché au lanceur», et «personne ne me fait confiance» sont apparus les uns après les autres. .. Sur Nippon Television "Going! Sports & News", le commentateur de baseball Taku Egawa était l'auditeur, et le modèle a été diffusé pendant deux nuits (17 et 18). Dans la première émission, M. Ochiai a révélé un épisode inconnu en disant: «Si je porte un uniforme l'année prochaine, je ne parlerai pas pour autant», mais la deuxième partie de l'émission est encore plus surprenante. C'est devenu le contenu qui devrait être. Voici un résumé de l'entrevue. Egawa: Pensiez-vous que vous pourriez être le meilleur au Japon cette année? Je ne pensais pas

est. La première phrase du cinquième groupe de "sujets-actualités" est

En Corée, c'est une règle générale que les moines sont célibataires, mais le Facebook du moine, qui dit: «J'étais désespéré et j'ai décidé de quitter la maison sans être populaire du sexe opposé», est devenu un sujet brûlant sur le babillard en ligne coréen. Le moine, nommé Hyobon, a déclaré sur Facebook le 19: "Je n'étais pas populaire auprès du sexe opposé dans la vingtaine ... J'ai fini par conclure que je ne pouvais rien y faire et j'ai décidé de quitter la maison. Tout le monde a abandonné. En y pensant maintenant, j'aurais dû faire des tours et des punks quand j'étais jeune », a-t-il déclaré à propos de son expérience de moine. Concernant la vie d'un prêtre, il a dit: "Plus vite vous quittez la maison, plus vite vous devenez grand. Si vous devenez grand, vous n'avez pas à vous soucier du riz et de la lessive."

est. La première phrase du 7e groupe de "sujets-actualités" est

Le 18, le Nihon Keizai Shimbun a rendu compte de la réalité déformée de la zone sinistrée dans un article intitulé «Une autre demande spéciale de reconstruction de situation anormale / Compensation nucléaire ... ing. Dans le même article, il a souligné que si la famille à indemniser est une famille de cinq personnes, 800000 yens par mois seront dans la poche, "j'ai reçu de l'argent de TEPCO, et même si je ne travaille pas, je peux pachinko, manger des sushis, et avoir un nouveau smartphone et un nouveau sac. Les mots de la population locale «Je le fais» sont affichés. L'indemnisation qui revient aux victimes et comment l'utiliser se positionne comme une «régénération déformée». Sur le babillard en ligne, "je n'ai pas récolté d'argent, je n'avais pas d'angle mort", "Sama-sama", "ça ne me dérange pas parce que les smartphones et les sushis sont consommés, mais le pachinko n'est pas bon."

est.

Vous ne pouvez pas vraiment comprendre les caractéristiques simplement en regardant le texte. .. ..

Cependant, vous pouvez voir que le sport et l'actualité ont des atmosphères d'articles très similaires.

Plus que cela, pour avoir une meilleure idée des caractéristiques des clusters IIC

De telles opérations peuvent être envisagées.

C'est trop long à faire dans cet article, c'est donc tout pour cette fois.

Le code d'implémentation de cet article se trouve dans le référentiel GitHub ci-dessous.

GitHub: Comment utiliser la version japonaise de BERT dans Google Colaboratory: code de mise en œuvre Il s'agit de 4_BERT_livedoor_news_IIC_on_Google_Colaboratory.ipynb.

Ce qui précède est un exemple d'implémentation et une explication pour les news de livingoor en tant que clustering IIC pour l'apprentissage non supervisé en japonais BERT.

Merci pour la lecture.


[Remarques] L'équipe de développement du département des technologies de l'IA, que je dirige, recherche des membres. Cliquez ici si vous êtes intéressé

[Clause de non-responsabilité] Le contenu de cet article lui-même est l'opinion / la transmission de l'auteur, et non l'opinion officielle de la société à laquelle l'auteur appartient.


Recommended Posts

[Explication de la mise en œuvre] Classer les actualités de livingoor par BERT japonais x apprentissage non supervisé (clustering de maximisation de la quantité d'informations): Google Colaboratory (PyTorch)
[Explication de la mise en œuvre] Comment utiliser la version japonaise de BERT dans Google Colaboratory (PyTorch)
La relation entre la science du cerveau et l'apprentissage non supervisé. Maximisez la quantité d'informations MNIST: Google Colabratory (PyTorch)