Une introduction à l'analyse de données à l'aide de Python - Pour augmenter le nombre de vues vidéo -

introduction

Objectif de cet article

Quand j'ai eu l'idée que «la science des données semble être amusante et je veux commencer!», Il y a des informations sur des «méthodes» telles que des packages tels que les pandas et des modèles tels que SVM, mais il y a peu d'introduction de cas familiers. Je le pense. ~~ Je ne suis pas enthousiasmé par la classification d'Ayame. ~~

Par conséquent, le but de cet article est de vous faire découvrir une série de processus d'analyse de données, en utilisant mon passe-temps «Analyse pour augmenter le nombre de vues du premier travail publié de VOCALOID» comme exemple. J'espère que je pourrais avoir une certaine influence sur votre analyse et votre motivation.

Structure de cet article

Nous procéderons à l'analyse dans l'ordre suivant. Je ne fais référence à rien de spécifique, mais je suis conscient de la forme qui intègre la technologie de programmation basée sur le flux d'articles empiriques utilisant l'économie métrique. [^ 1]

[^ 1]: Cette analyse fait partie du cadre d'analyse de données classique consistant à «faire d'abord une hypothèse, puis la tester avec des données». Je pense que le processus est différent de l'approche d'exploration de données consistant à «trouver des connaissances utiles à partir de données désordonnées».

  1. Réglage du thème
  2. Établissement d'hypothèses
  3. Obtention de données à l'aide de l'API
  4. Analyse des données
  5. Évaluation de la validité de l'analyse

Techniques couvertes dans cet article

L'objectif principal de cet article est de vous parler du processus d'analyse des données, mais si vous êtes intéressé par les sujets suivants utilisés pour l'analyse, n'hésitez pas!

--Comment accéder à la vidéo Nico Nico "Snapshot Search API v2" en utilisant Python

Bonne connaissance pour lire cet article

1. Réglage du thème

Vous avez terminé votre premier travail en tant que nouveau venu Bokaro P. Lorsque je publie une œuvre sur un site vidéo, je pense essayer d'augmenter le plus possible le nombre de vues. La qualité de la chanson elle-même ne peut plus être modifiée, donc je pense à concevoir quelque chose pour le titre et les commentaires de l'affiche.

2. Établissement d'hypothèses

Le premier message d'une chanson VOCALOID est presque toujours étiqueté comme "VOCALOID maiden work". En revanche, peu de personnes mettent «premier message» dans le titre de leur travail. (Par exemple, "[Hatsune Miku Original] ~ Titre ~ [Premier message]")

Si vous ajoutez "premier message" au titre, quel type d'image les spectateurs auront-ils lorsqu'ils le verront? Il y a deux réactions possibles: "Oh, je vais vous demander si vous êtes un nouveau venu" ou "Je ne peux m'empêcher de vous demander si vous êtes un nouveau venu sans antécédents." Si la première réaction est prédominante, vous pouvez vous attendre à une augmentation du nombre de vues en ajoutant un mot au titre pour le rendre plus accrocheur.

Par conséquent, dans cet article, je voudrais tester l'hypothèse selon laquelle l'ajout de «premier message» au titre des œuvres étiquetées «VOCALOID maiden work» augmentera le nombre de vues.

3. Obtention de données à l'aide de l'API

Les données nécessaires à cette analyse sont

-Le travail avec le tag "VOCALOID maiden work"

Sera. De plus, nous traiterons les données des 4 dernières années (travaux affichés de 2013 à 2016).

Obtenons les informations de travail de la vidéo Nico Nico "Snapshot Search API v2". L'utilisation est organisée dans le guide officiel. http://site.nicovideo.jp/search-api-docs/snapshot.html

Les points sont les suivants.

[^ 2]: Comment utiliser le décalage: Par exemple, si vous triez par le nombre de vues de classement et définissez offset = 30, vous pouvez spécifier des œuvres après le 30e classement.


import urllib
import requests
import time
import pandas as pd


class NiconicoApi():

    def __init__(self, keyword):
        self.keyword = keyword

    def gen_url(self, year, offset):
        url_body = 'http://api.search.nicovideo.jp/api/v2/video/contents/search?'
        url_query = urllib.parse.urlencode( {
          'q': self.keyword,
          'filters[startTime][gte]': '%i-01-01T00:00:00' % year,
          'filters[startTime][lt]':  '%i-01-01T00:00:00' % (year + 1),
          '_offset': offset,
          'targets': 'tags',
          'fields': 'title,viewCounter,startTime',
          '_sort': '-viewCounter',
          '_limit': 100,
          '_context': 'apiguide'
        } )
        self.url_ = url_body + url_query
        return self

    def get_json(self):
        response = requests.get(self.url_)
        self.json_ = response.json()
        return self.json_


'''Obtenez des données'''
data = []
nicoApi = NiconicoApi('Œuvre inaugurale de VOCALOID')

for year in range(2013, 2017):
    offset = 0
    nicoApi.gen_url(year=year, offset=offset)
    json = nicoApi.get_json()

    while json['data']:
        data += json['data']
        offset += 100
        nicoApi.gen_url(year=year, offset=offset)
        json = nicoApi.get_json()
        time.sleep(1)


'''Conversion vers DataFrame'''
df = pd.DataFrame.from_dict(data)
df.shape  # => (4579, 3)

La taille de l'échantillon est désormais de 4579 [^ 3]. Puisqu'il s'agit de données pour 4 ans, il est calculé que plus de 1000 nouveaux arrivants Bokaro P naissent chaque année.

[^ 3]: au 06/03/2017

4. Analyse des données

Visualisation du classement et du nombre de vues

Avant de nous lancer dans une analyse à grande échelle, examinons rapidement les données.

Tout d'abord, tracez le nombre de lectures sur l'axe vertical et le classement sur l'axe horizontal. À ce stade, comme on peut prédire qu'il existe une grande différence dans le nombre de vues entre les œuvres populaires et les œuvres inconnues, nous prendrons l'axe vertical sur l'échelle logarithmique.


import numpy as np
import matplotlib.pyplot as plt


df = df.sort_values('viewCounter', ascending=False)
ranking = np.arange(len(df.index))
view_counter = df['viewCounter'].values
plt.scatter(ranking, view_counter)
plt.yscale('log')
plt.grid()
plt.title('2013~2016 Ranking & ViewCounter')
plt.xlabel('Ranking')
plt.ylabel('ViewCounter')
plt.show()

résultat: pic1.png

――Il semble qu'environ 3/4 des œuvres soient jouées 100 à 1000 fois. ――Le degré de cette distorsion même si l'axe vertical est log. La disparité est terrible ... «Nous avons confirmé le degré de distorsion de la distribution et l'existence de valeurs aberrantes, nous aimerions donc l'utiliser pour des analyses futures.

Regroupement des DataFrames par "si le titre inclut ou non" premier message ""

Pour l'analyse, il est nécessaire de séparer les œuvres qui incluent «premier message» dans le titre et les œuvres qui n'en contiennent pas. Utilisez le groupe de pandas par méthode.

Groupby transmet souvent un nom de colonne comme argument, mais vous pouvez également transmettre une fonction. Passer une fonction facilite le regroupement dans des conditions arbitraires.

Cette fois, nous voulons regrouper par "si le titre inclut ou non" premier message "", définissons donc la fonction de la condition de jugement. Nous inclurons également "travail vierge", qui a la même signification que "premier post", dans l'analyse.

Définissez une fonction avec une valeur de retour différente selon que l'argument contient «premier post» ou «travail vierge» ou ni l'un ni l'autre.


def include_keyword(title):
  if 'Premier poste' in title:
    return 'Premier poste'
  elif 'Premier livre' in title:
    return 'Premier livre'
  else:
    return 'Groupe de contrôle'

Passez la fonction définie comme argument de groupby. Ensuite, la fonction est appliquée à chaque élément d'index de df1 et groupée selon la valeur de retour. C'est similaire au filtre.


#Changer l'index en colonne de titre
df1 = df[['viewCounter', 'title']].set_index('title')

#regroupement
df1_grouped = df1.groupby(include_keyword)

Trouver des statistiques descriptives

Maintenant que le regroupement est terminé, passons à une analyse détaillée.

Si vous calculez la valeur moyenne et la valeur médiane de chaque groupe et que vous les comparez avec "fonctionne avec des mots-clés (ci-après, groupe de traitement)" et "fonctionne sans mots-clés (groupe de contrôle)", "effets de l'inclusion de mots-clés (effets en incluant des mots-clés) Effet du traitement) »peut être mesuré.

Puis pour chaque groupe

Demandons.

Agg est utile pour trouver plusieurs statistiques descriptives à la fois. En passant plusieurs méthodes sous forme de tableau à l'argument de agg, ces méthodes peuvent être appliquées collectivement à df1_grouped.


functions = ['count', 'mean', 'median', 'std']
df1_summary = df1_grouped.agg(functions)

résultat: ―― Sur les 4579 échantillons, 109 œuvres ont «premier message» dans le titre, et 144 œuvres dont «œuvre vierge». ――Les résultats ont montré que le groupe de traitement avait plus de régénérations que le groupe témoin, à la fois en termes de valeurs moyennes et médianes. En d'autres termes, en ajoutant un mot «premier message» au titre, il semble qu'il ait pu attirer l'attention. pic2.png

Comparaison de graphes

A partir de maintenant, considérons deux groupes, le «groupe de traitement» et le «groupe de contrôle», pour simplifier l'analyse. Modifiez df1_grouped comme suit.


def include_keyword(title):
    if 'Premier poste' in title or 'Premier livre' in title:
        return 'Groupe de traitement'
    else:
        return 'Groupe de contrôle'


df1_grouped = df1.groupby(include_keyword)
df1_summary = df1_grouped.agg(functions)
df1_summary

résultat: pic3.png

Maintenant, regardons la différence entre les deux groupes dans un graphique.


X_treated   = np.log(df1_grouped.get_group('Groupe de traitement').values)
X_untreated = np.log(df1_grouped.get_group('Groupe de contrôle').values)
plt.hist(X_treated, normed=True, bins=20, label='Groupe de traitement', color='r', alpha=0.5)
plt.hist(X_untreated, normed=True, bins=20, label='Groupe de contrôle', color='b', alpha=0.5)
plt.show()

résultat: pic4.png

Le graphique montre également la différence de distribution entre le groupe de traitement et le groupe témoin.

Test U de Mann-Whitney

Soit dit en passant, le résultat souhaité (le nombre de vues augmente en incluant le "premier message" dans le titre) a été suggéré jusqu'à présent, mais la "différence dans le nombre de vues entre le groupe de traitement et le groupe témoin" obtenue dans la section précédente est statistique. Vérifions si c'est significatif (n'est-ce pas une différence qui peut s'expliquer par le hasard)?

Comme mentionné précédemment, la distribution des lectures est sévèrement déformée, vous devriez donc regarder la médiane plutôt que la moyenne. Ce n'est pas la comparaison médiane des deux groupes, mais une alternative est le test U de Mann-Whitney [^ 4].

Le test U de Mann-Whitney pose l'hypothèse nulle que la forme de la distribution entre les deux groupes est la même [^ 5]. Si cette hypothèse nulle est rejetée, le nombre de rediffusions dans les groupes de traitement et de contrôle se trouve être inexplicablement différent.

Le test U est fourni dans le module de statistiques de scipy. Testons-le.


from scipy import stats

result = stats.mannwhitneyu(X_treated, X_untreated)
print(result.pvalue)  # => 0.00137327945838

Puisque la valeur p est de 0,0014, on peut dire que la distribution entre les deux groupes est significativement différente. Tu l'as fait!

[^ 5]: Pour effectuer le test U de Mann-Whitney, il est nécessaire de supposer la dispersion égale des deux groupes, mais ceci est omis pour des raisons de simplicité. J'ai également essayé le test de Brunner-Munzel, qui ne nécessite pas de processus équidistant, et j'ai trouvé des résultats significatifs, donc les résultats semblent robustes. (Pour le test Brunner-Munzel, reportez-vous ici: http://oku.edu.mie-u.ac.jp/~okumura/stat/brunner-munzel.html)

5. Examen de la validité de l'analyse

Une chose qui doit être notée dans une telle analyse est la "fausse corrélation". On peut dire que «corrélation ≠ effet causal».

Tout ce que nous avons fait jusqu'à présent, c'est qu'il existe une corrélation entre l'ajout d'un "premier message" au titre et le nombre de vues. Nous examinerons si cette corrélation peut être interprétée comme une relation causale.

Biais variable manquant

Par exemple, il existe une corrélation entre les ventes de glaces et les accidents d'eau. A partir de là, il semble violent de conclure que "manger de la glace vous rend plus vulnérable aux accidents d'eau", non?

La vraie cause est la «saison». Oublier de considérer la «saison» et conduire à la fausse corrélation mentionnée ci-dessus est appelé «biais de variable manquante» en termes d'économie métrique. (Dans ce cas, variable manquante = saison)

Revenons à la chanson VOCALOID. S'il y a des «variables manquantes» dans cette analyse, quels sont les facteurs possibles?

Je suis venu avec le cas où «date de publication» est une variable manquante. Supposons que la situation suivante se vérifie.

――La culture VOCALOID est entrée dans une période de déclin et le nombre de vues est en baisse de 2013 à 2016. --VOCALOID C'est une vieille pratique d'ajouter "premier message" au titre d'une chanson, et il a disparu récemment.

Dans ce cas, les deux phénomènes «l'année d'affichage est ancienne -> de nombreuses vues» et «l'année d'affichage est ancienne» -> l'ajout de «premier message» au titre «se chevauchent, créant une fausse corrélation. Je comprends ça.

Vérifions s'il existe une fausse corrélation comme celle ci-dessus. Deux colonnes représentant l '«année de cotisation» et le «groupe de traitement ou groupe témoin» sont créées à l'avance et le regroupement est effectué sur la base de ces deux colonnes.


df2 = df.copy()
df2['title'] = df2['title'].apply(include_keyword)
df2['startTime'] = pd.DatetimeIndex(df2['startTime'])
#  tz_Pour appliquer localize'startTime'Est spécifié dans l'index
df2 = df2.set_index('startTime')
df2.index = df2.index.tz_localize('UTC').tz_convert('Asia/Tokyo')
df2['startTime'] = df2.index
df2['startTime'] = df2['startTime'].apply(lambda x: x.year)
df2_grouped = df2.groupby(['startTime', 'title']).viewCounter
df2_summary = df2_grouped.agg(functions)
df2_summary

Résultat: même groupés par année comptable, on constate que le nombre de vues du groupe de traitement et du groupe témoin est différent sauf en 2013. pic5.png

Régression multiple

Maintenant que nous avons grossièrement confirmé dans le tableau ci-dessus que l'année de publication n'est pas une variable manquante, analysons-la plus rigoureusement en utilisant la régression multiple.

Supposons que le nombre de vues soit déterminé comme suit:

log (nombre de vues_i) = \ beta_0 + \ beta_1 * Traitement factice_i + \ beta_2 * Tendance temporelle _i + erreur _i

Ici, les détails de chaque variable sont les suivants.

Ensuite, j'expliquerai les avantages de l'utilisation de la régression multiple. Avec la régression multiple, il est possible d'estimer «combien le nombre de lectures diffère entre le groupe de traitement et le groupe témoin lorsque la tendance temporelle est fixe ($ \ beta_1 $)». Par conséquent, il est possible d'éliminer la corrélation apparente due aux tendances temporelles.

L'inconvénient ici est qu'il utilise le nombre moyen de lectures pour estimer $ \ beta_1 $, ce qui le rend plus sensible aux valeurs aberrantes.

Lançons-le.


import statsmodels.formula.api as smf

def include_keyword(title):
    if 'Premier poste' in title or 'Premier livre' in title:
        return 1
    else:
        return 0

df3 = df.copy()
df3['title'] = df3['title'].apply(include_keyword)
df3['startTime'] = pd.DatetimeIndex(df3['startTime'])
df3['timeTrend'] = df3['startTime'].apply(lambda x: (df3['startTime'].max() - x).days)
df3['lviewCounter'] = np.log(df3['viewCounter'])

mod = smf.ols('lviewCounter ~ title + timeTrend', data=df3).fit()
mod.summary()

résultat: pic6.png

On peut dire que ce résultat d'analyse est plus robuste car il a été confirmé que «post date et heure» ne créait pas de biais variable manquant. Tu l'as fait!

Ceci conclut "l'évaluation de la validité de l'analyse", mais si vous pensez "Est-il préférable de vérifier également ce facteur?", Veuillez commenter!

en conclusion

Cela fait longtemps, mais merci beaucoup d'avoir lu jusqu'ici.

Au fait, sur la base de cette analyse, j'ai ajouté le "premier message" au titre et l'ai posté sur Nikodo, mais le nombre de vues était inférieur à 200. Notez que les tendances statistiques ne s'appliquent pas aux cas individuels.

Cet article se termine lorsque j'obtiens une ligne de punch. Je serais heureux si je pouvais vous dire quelque chose sur le flux de l'analyse, ce à quoi vous devez faire attention et la technologie dont vous avez besoin.

Recommended Posts

Une introduction à l'analyse de données à l'aide de Python - Pour augmenter le nombre de vues vidéo -
Introduction à la modélisation statistique pour l'analyse des données
Introduction à la modélisation statistique pour l'analyse des données Élargissement de la gamme d'applications de GLM
Note de lecture: Introduction à l'analyse de données avec Python
[Livre technique] Introduction à l'analyse de données avec Python -1 Chapitre Introduction-
Une introduction à l'orientation des objets - changeons l'état interne d'un objet
Comment augmenter le nombre d'images de jeux de données d'apprentissage automatique
[Introduction au graphique logarithmique] Prédire l'heure de fin de chaque pays à partir du graphique logarithmique des données sur le nombre d'infections ♬
Obtenez le nombre de vues de Qiita
Recommandation d'analyse des données à l'aide de MessagePack
[Python] PCA scratch dans l'exemple de "Introduction à la méthode d'analyse multivariée"
De l'introduction de JUMAN ++ à l'analyse morphologique du japonais avec Python
"Le gars qui prédit le nombre de vues à partir du titre de la vidéo de Jar Jal"
Le nombre de fermetures de magasins a-t-il augmenté en raison de l'influence du nouveau virus corona?
Comment connaître le nombre de processeurs sans utiliser la commande sar
Affichez le résultat de l'analyse vidéo à l'aide de l'API Cloud Video Intelligence de Colaboratory.
Essayez d'obtenir l'état de la surface de la route en utilisant de grandes données de gestion de la surface de la route
Le nombre est-il équivalent à un entier?
J'ai essayé d'effectuer une analyse de cluster de clients à l'aide des données d'achat
Comment lire une vidéo tout en regardant le nombre d'images (Mac)
[Introduction au Data Scientist] Bases de Python ♬
Introduction aux statistiques de quiz (1) -Analyse mathématique des phrases de questions pour connaître la tendance des questions-
Enregistrez le tableau numpy dans un fichier wav à l'aide du module wave
Organiser les outils Python pour accélérer le mouvement initial des compétitions d'analyse de données
[Introduction à Python] Comment obtenir l'index des données avec l'instruction for
Convertissez les données avec la forme (nombre de données, 1) en (nombre de données,) avec numpy.
Raccourcir le temps d'analyse d'Openpose à l'aide du son
[Introduction à minimiser] Analyse des données avec le modèle SEIR ♬
[Introduction à cx_Oracle] (5e) Gestion des données japonaises
Une introduction à l'analyse vocale pour les applications musicales
Déterminez le nombre de classes à l'aide de la formule Starges
De l'introduction de pyethapp à l'exécution du contrat
Vérifiez l'état des données à l'aide de pandas_profiling
Gratter les données gagnantes de Numbers à l'aide de Docker
Utilisez Pandas pour écrire uniquement les lignes spécifiées du bloc de données dans le fichier Excel
Un moyen simple de remplir le début de 0 en fonction du nombre de chiffres dans le nombre [Python]
Comment connaître le numéro de port du service xinetd
[Python] [Word] [python-docx] Analyse simple des données de diff en utilisant python
Une introduction des technologies de pointe-AI, ML, DL
Analyse de Big Data à l'aide du framework de contrôle de flux de données Luigi
J'ai essayé de prédire le match de la J League (analyse des données)
Essayez d'estimer le nombre de likes sur Twitter
Explication du concept d'analyse de régression à l'aide de Python Partie 1
Écrire des données dans KINTONE à l'aide du module de requêtes Python
J'ai essayé d'utiliser l'API de Sakenowa Data Project
[Introduction à Python] Comment arrêter la boucle en utilisant break?
Explication du concept d'analyse de régression à l'aide de Python Extra 1
[Python] Obtenez le nombre de vues de tous les articles publiés
[Introduction à Python] Utilisation basique de la bibliothèque matplotlib
L'histoire de l'utilisation de Circleci pour construire des roues Manylinux
Je souhaite augmenter la sécurité de la connexion SSH
[Introduction au modèle SIR] Prédire l'heure de fin de chaque pays avec l'ajustement des données COVID-19 ♬
Analyse de la vie de la technologie avec les données d'articles Qiita ~ Analyse du temps de survie à l'aide du journal de contenu ~
[Pour les débutants] Je souhaite expliquer le nombre d’apprentissage d’une manière facile à comprendre.
Comment spécifier un nombre infini de tolérances dans le contrôle de validation d'argument numérique d'argparse
VisibleDeprecation Avertissement: l'utilisation d'un nombre non entier au lieu d'un entier entraînera une erreur dans le futur
Comment calculer la somme ou la moyenne des données csv de séries chronologiques en un instant
Notes de lecture (en Python et Stan) pour une introduction à la modélisation statistique pour l'analyse de données (Midorimoto)