Ensemble de données Pikabu

Il est suggéré de regarder l'ensemble de données des articles de pikabu.ru du point de vue de la statistique des données. L'ensemble de données lui-même, composé de 450 pièces, est assemblé par les meilleurs analyseurs 24h / 24, traité avec des parfums qui suppriment les articles en double, et est également bourré de colonnes supplémentaires, dont la signification n'est disponible que pour les initiés. Ici, le jeu de données lui-même n'est pas tant intéressant que l'approche de l'analyse de ces sites. Dans les prochains articles, nous essaierons d'appliquer des éléments de l'apprentissage automatique pour l'analyse.







Vous pouvez travailler avec l'ensemble de données à la fois dans Excel ordinaire et dans le notebook Jupyter, les champs de données sont séparés par des tabulations. Nous nous concentrerons sur la dernière option, et toutes les commandes seront données en tenant compte du fait que le travail est effectué dans un notebook jupyter.



Nous travaillerons sous Windows. Par conséquent, utilisez cmd pour accéder au dossier contenant le jeu de données téléchargé et exécutez jupyter notebook avec la commande du même nom.



Ensuite, importons les modules.



import pandas as pd
import numpy as np


Étant donné que l'ensemble de données ne contient pas d'en-têtes, désignons-les avant de charger l'ensemble de données:



headers=['story_title','link','story_id','data_rating','data_timestamp','story_comments','data_author_id','data_meta_rating','user_name','user_link','story__community_link']


Tout est clair ici: titre de l'article, lien vers celui-ci, identifiant de l'article, note (nombre de plus), date de l'article, nombre de commentaires, identifiant de l'auteur, méta-évaluation de l'article, nom de l'auteur, lien vers l'auteur, lien vers la communauté.



Nous comptons l'ensemble de données.



df = pd.read_csv('400k-pikabu.csv',parse_dates=['data_timestamp'],
                   warn_bad_lines=True,
                   index_col = False,                   
                   dtype ={'story_title':'object','link':'object','story_id':'float32','data_rating':'float32',
                   'story_comments':'float32','data_author_id':'float32'},
                   delimiter='\t',names=headers)


Voici une légère optimisation des valeurs lues afin que certaines colonnes apparaissent comme numériques.



L'ensemble de données représente donc 468 595 lignes, 11 colonnes.



print(df.shape)#468595 ,11 


5 premiers enregistrements



df.head(5)






Description statistique:



df.describe()






Utilisation de valeurs vides dans un ensemble de données



Malgré le fait que les analyseurs ont travaillé sans relâche, il y a de petits trous dans le jeu de données, en d'autres termes, des trous technologiques représentés par des lacunes. Ces lacunes chez les pandas ont la valeur NaN. Voyons le nombre de lignes avec de tels vides:



len(df.loc[pd.isnull( df['story_title'])])


À quoi ça ressemble sur l'ensemble de données:



df.loc[pd.isnull( df['story_title'])]






1444 lignes avec des lacunes ne gâchent pas l'image globale, mais, néanmoins, débarrassons-nous-en:



data1=df.dropna(axis=0, thresh=5)


Nous vérifions que la suppression a réussi:



len(data1.loc[pd.isnull(data1['story_id'])]) 


Travaillons avec l'ensemble de données



Voyons les noms des colonnes



df.columns






Choisissons la première colonne



col = df['story_title']
col






Jetons un coup d'œil au minimum dans l'ensemble de données



data1.min()






Maximum



data1.max()






La même chose est plus visuelle:



data1.loc[:,['user_name', 'data_rating', 'story_comments']].min()






Maintenant, rassemblons les valeurs des colonnes intéressantes dans un tableau:



arr = data1[['story_id', 'data_rating', 'data_timestamp','user_name']].values


Vous pouvez regarder l'une des colonnes du tableau:



arr[:, 1] # 






Regardons le nombre d'articles avec une note de plus de 10000:



print((arr[:, 1] > 10000.0).sum())


Seuls 2672 articles ont une note ultra élevée sur 450k



Dessinons des graphiques



Tout d'abord, importons le module:



import matplotlib.pyplot as plt


Voyons s'il y a un lien entre l'identifiant de l'auteur de l'article et la note de l'article?



plt.scatter(data1['data_author_id'], data1['data_rating'])
plt.xlabel('data_author_id') 
plt.ylabel('data_rating')






En raison de la grande quantité de données, il est difficile de saisir la relation et, très probablement, elle est manquante.



Existe-t-il une relation entre l'identifiant de l'article et l'évaluation de l'article?



plt.scatter(data1['story_id'], data1['data_rating'])
plt.xlabel('story_id') 
plt.ylabel('data_rating')






Il est à noter ici que les publications avec un nombre plus élevé (publications ultérieures) reçoivent une note plus élevée, elles sont plus souvent votées. La ressource gagne-t-elle en popularité?



Y a-t-il une relation entre la date de l'article et la note?



plt.scatter(data1['data_timestamp'], data1['data_rating'])
plt.xlabel('data_timestamp') 
plt.ylabel('data_rating')






Vous pouvez également voir la relation entre les publications ultérieures et le classement des publications. Un meilleur contenu ou, encore une fois, simplement une augmentation du trafic sur le site Web?



Y a-t-il un lien entre la note d'un article et le nombre de commentaires sur celui-ci?



plt.scatter(data1['story_comments'], data1['data_rating'])
plt.xlabel('story_comments') 
plt.ylabel('data_rating')






Il existe ici une relation linéaire, bien qu'elle soit très dispersée. Il y a une certaine logique, plus la note du message est élevée, plus il y a de commentaires.



Jetons un coup d'œil aux meilleurs auteurs (auteurs avec les notes totales les plus élevées):



top_users_df = data1.groupby('user_name')[['data_rating']].sum().sort_values('data_rating', ascending=False).head(10)   
top_users_df






Ajoutons de la clarté:



top_users_df.style.bar()






Essayons d'autres outils de visualisation. Par exemple seaborn



#   
 ! pip3 install seaborn
from __future__ import (absolute_import, division,
                        print_function, unicode_literals)
#  
import warnings
warnings.simplefilter('ignore')

#      jupyter'e
%pylab inline
#  svg   
%config InlineBackend.figure_format = 'svg' 

#  
from pylab import rcParams
rcParams['figure.figsize'] = 6,3
import seaborn as sns


Construisons des graphiques en utilisant des colonnes avec l'identifiant de l'article, leur note et leurs commentaires, enregistrez le résultat au format .png:



%config InlineBackend.figure_format = 'png' 
sns_plot = sns.pairplot(data1[['story_id', 'data_rating', 'story_comments']]);
sns_plot.savefig('pairplot.png')






Essayons l'outil de visualisation Plotly



from plotly.offline import init_notebook_mode, iplot
import plotly
import plotly.graph_objs as go
init_notebook_mode(connected=True)


Regroupons les données par date et note totale des articles pour cette date:



df2 = data1.groupby('data_timestamp')[['data_rating']].sum()
df2.head()






Voyons combien d'articles ont été publiés à une certaine date (mois):



released_stories = data1.groupby('data_timestamp')[['story_id']].count()
released_stories.head()






Collons deux tableaux:



years_df = df2.join(released_stories)
years_df.head()






Maintenant, dessinons en utilisant plotly:



trace0 = go.Scatter(
    x=years_df.index,
    y=years_df.data_rating,
    name='data_rating'
)
trace1 = go.Scatter(
    x=years_df.index,
    y=years_df.story_id,
    name='story_id'
)
data = [trace0, trace1]
layout = {'title': 'Statistics'}
fig = go.Figure(data=data, layout=layout)
iplot(fig, show_link=False)






La beauté de l'intrigue est son interactivité. Dans ce cas, en survol, le graphique montre la note totale des articles pour une certaine date (mois). On constate que la note a baissé en 2020. Mais cela peut s'expliquer par le fait que le nombre d'articles de cet intervalle n'a pas été suffisamment collecté par les analyseurs, et aussi que les posts n'ont pas encore acquis un nombre suffisant de plus.



Au bas du graphique, la ligne rouge indique également de manière interactive le nombre d'articles uniques pour une date spécifique.



Sauvegardons le graphique sous forme de fichier html.



plotly.offline.plot(fig, filename='stats_pikabu.html', show_link=False);


Regroupements de données



Voyons combien d'auteurs se trouvent dans l'ensemble de données:



data1.groupby('user_name').size()






Combien d'articles par auteur:



data1['user_name'].value_counts()






Qui écrit le plus souvent (plus de 500 articles):



for i in data1.groupby('user_name').size():
    if i>500:        
        print (data1.iloc[i,8],i) #8-   user_name


C'est donc qui "obstrue" la ressource). Il n'y en a pas tellement:



auteurs
crackcraft 531

mpazzz 568

kastamurzik 589

pbdsu 773

RedCatBlackFox 4882

Wishhnya 1412

haalward 1190

iProcione 690

tooNormal 651

Drugayakuhnya 566

Ozzyab 1088

kalinkaElena9 711

Freshik04 665

100pudofff 905

100pudofff 1251

Elvina.Brestel 1533

1570525 543

Samorodok 597

Mr.Kolyma 592

kka2012 505

DENTAARIUM 963

4nat1k 600

chaserLI 650

kostas26 1192

portal13 895

exJustice 1477

alc19 525

kuchka70 572

SovietPosters 781

Grand.Bro 1051

Rogo3in 1068

fylhtq2222 774

deystvitelno 539

lilo26 802

al56.81 2498

Hebrew01 596

TheRovsh 803

ToBapuLLI 1143

ragnarok777 893

Ichizon 890

hoks1 610

arthik 700



Voyons combien de communautés il y a sur la ressource au total:



data1.groupby('story__community_link').size() 






Et lequel est le plus prolifique:



data1['story__community_link'].value_counts()






* Les données sur la communauté ne sont pas entièrement correctes, puisque la première communauté mentionnée a été collectée lors de l'analyse, et les auteurs indiquent souvent plusieurs pièces.



Enfin, voyons comment appliquer la fonction avec la sortie du résultat dans une colonne séparée .



Cela sera nécessaire pour une étude plus approfondie de l'ensemble de données.



Fonction simple pour attribuer la note d'un article à un groupe.



Si la note est supérieure à <5000 - mauvais,> 5000 - bon.



def ratingGroup( row ):
    # ,      NaN
    if not pd.isnull( row['data_rating'] ):
        if row['data_rating'] <= 5000:
            return 'bad'
        if row['data_rating'] >= 20000:
            return 'good'        
    
    #    NaN,   Undef
    return 'Undef'


Appliquons la fonction ratingGroup au DataFrame et affichons le résultat dans une colonne séparée -ratingGroup



data1['ratingGroup'] = data1.apply( ratingGroup, axis = 1 )
data1.head(10)


Une nouvelle colonne apparaîtra dans l'ensemble de données avec les valeurs suivantes:







Télécharger - ensemble de données .



Téléchargez un ensemble de données non nettoyé pour nettoyer vous - même les doublons - un ensemble de données .



* python nettoie (supprime les lignes en double en fonction de l'identifiant de l'article) pendant près d'une heure! Si quelqu'un réécrit le code en C ++, je vous en serai reconnaissant!:



with open('f-final-clean-.txt','a',encoding='utf8',newline='') as f:
    for line in my_lines:
        try:
            b=line.split("\t")[2]
            if b in a:        
                pass
            else:
                a.append(b)            
                f.write(line)            
        except:
            print(line)


La question est supprimée, tk. de manière inattendue) a trouvé un dictionnaire en python qui fonctionne 10 fois plus vite:

a={}
f = open("f-final.txt",'r',encoding='utf8',newline='')
f1 = open("f-final-.txt",'a',encoding='utf8',newline='') 
for line in f.readlines():
    try:            
        b=line.split("\t")[2]
        if b in a:        
            pass
        else:
            a[b]=b
            #print (a[b])
            f1.write(line) 
    except:
        pass
f.close()
f1.close()


Bloc-notes Jupyter - télécharger .



All Articles