مجموعة بيانات Pikabu

يُقترح إلقاء نظرة على مجموعة بيانات المنشورات من pikabu.ru من وجهة نظر إحصائيات البيانات. يتم تجميع مجموعة البيانات نفسها ، التي تتكون من 450 قطعة ، بواسطة أفضل المحللين على مدار الساعة ، ومعالجتها بالعطور التي تزيل المقالات المكررة ، كما أنها محشوة بأعمدة إضافية ، لا يتوفر معناها إلا للمبتدئين. هنا مجموعة البيانات نفسها ليست مثيرة للاهتمام بقدر ما هو نهج تحليل مثل هذه المواقع. سنحاول في المنشورات التالية تطبيق عناصر من التعلم الآلي للتحليل.







يمكنك العمل مع مجموعة البيانات في كل من Excel العادي وفي دفتر jupyter ، يتم فصل حقول البيانات بعلامات تبويب. سنركز على الخيار الأخير ، وسيتم إعطاء جميع الأوامر مع مراعاة حقيقة أن العمل يتم في دفتر ملاحظات jupyter.



سنعمل في النوافذ. لذلك ، استخدم cmd للانتقال إلى المجلد الذي يحتوي على مجموعة البيانات التي تم تنزيلها وتشغيل دفتر jupyter باستخدام الأمر الذي يحمل نفس الاسم.



بعد ذلك ، دعنا نستورد الوحدات.



import pandas as pd
import numpy as np


نظرًا لأن مجموعة البيانات لا تحتوي على رؤوس ، فلنقم بتعيينها قبل تحميل مجموعة البيانات:



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']


كل شيء واضح هنا: عنوان المقالة ، الارتباط به ، معرف المقالة ، التصنيف (عدد الإيجابيات) ، تاريخ المقالة ، عدد التعليقات ، معرف المؤلف ، تصنيف التعريف للمقالة ، اسم المؤلف ، رابط المؤلف ، الارتباط بالمجتمع.



نحسب مجموعة البيانات.



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)


فيما يلي تحسين طفيف لقيم القراءة بحيث تظهر بعض الأعمدة كأرقام.



لذا فإن مجموعة البيانات تمثل 468.595 صفاً ، 11 عموداً.



print(df.shape)#468595 ,11 


أول 5 سجلات



df.head(5)






الوصف الإحصائي:



df.describe()






العمل بقيم فارغة في مجموعة بيانات



على الرغم من حقيقة أن المحللين عملوا بلا كلل ، إلا أن هناك ثغرات صغيرة في مجموعة البيانات ، وبعبارة أخرى ، فجوات تكنولوجية تمثلها الفجوات. تأتي هذه الفجوات في الباندا مع القيمة NaN. دعونا نرى عدد الأسطر مع هذه الفراغات:



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


كيف تبدو في مجموعة البيانات:



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






1444 سطرًا به فجوات لا تفسد الصورة العامة ، لكن مع ذلك ، دعونا نتخلص منها:



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


نتحقق من نجاح الحذف:



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


دعنا نعمل مع مجموعة البيانات



دعونا نرى أسماء الأعمدة



df.columns






دعنا نختار العمود الأول



col = df['story_title']
col






دعنا نلقي نظرة على الحد الأدنى في مجموعة البيانات



data1.min()






أقصى



data1.max()






الشيء نفسه أكثر بصرية:



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






الآن دعنا نجمع القيم من الأعمدة المثيرة للاهتمام في مصفوفة:



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


يمكنك إلقاء نظرة على أحد أعمدة المصفوفة:



arr[:, 1] # 






لنلقِ نظرة على عدد المقالات التي يزيد تصنيفها عن 10000:



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


فقط 2672 مقالة لها تصنيف فائق من 450 ألف



لنرسم المخططات



أولاً ، دعنا نستورد الوحدة:



import matplotlib.pyplot as plt


دعنا نكتشف ما إذا كانت العلاقة بين معرف المؤلف للمقال وتقييم المقال؟



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






بسبب الكم الهائل من البيانات ، من الصعب فهم العلاقة ، والأرجح أنها مفقودة.



هل هناك علاقة بين معرف المقالة وتقييم المادة؟



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






من الملاحظ هنا أن المشاركات ذات العدد الأعلى (المشاركات اللاحقة) تحصل على تصنيف أعلى ، وغالبًا ما يتم التصويت لها. هل تزداد شعبية المورد؟



هل هناك علاقة بين تاريخ المقال و التصنيف؟



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






يمكنك أيضًا رؤية العلاقة بين المشاركات اللاحقة وترتيب المنشور. محتوى أفضل أو ، مرة أخرى ، مجرد زيادة في حركة المرور على الموقع؟



هل هناك علاقة بين تصنيف مقال وعدد التعليقات عليه؟



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






هناك علاقة خطية هنا ، على الرغم من أنها مبعثرة للغاية. هناك منطق معين ، فكلما ارتفع تصنيف المنشور ، زاد عدد التعليقات.



دعنا نلقي نظرة على أفضل المؤلفين (المؤلفون الحاصلون على أعلى إجمالي تقييمات منشورات):



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






دعنا نضيف الوضوح:



top_users_df.style.bar()






لنجرب أدوات التصور الأخرى. على سبيل المثال البحر



#   
 ! 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


دعونا نبني الرسوم البيانية باستخدام أعمدة مع معرف المنشور ، وتقييمهم وتعليقاتهم ، وحفظ النتيجة في .png:



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






لنجرب أداة التصور Plotly



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


دعنا نجمع البيانات حسب التاريخ والتصنيف الإجمالي للمقالات لهذا التاريخ:



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






دعونا نرى عدد المقالات التي تم نشرها في تاريخ معين (شهر):



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






دعونا نلصق طاولتين:



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






الآن دعنا نرسم باستخدام الرسم:



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)






جمال الحبكة هو تفاعلها. في هذه الحالة ، عند التمرير ، يعرض الرسم البياني التقييم الإجمالي للمقالات لتاريخ معين (شهر). يمكن ملاحظة أن التصنيف انخفض في عام 2020. ولكن يمكن تفسير ذلك من خلال حقيقة أن عدد المقالات من هذا الفاصل الزمني لم يتم جمعها بشكل كاف من قبل المحللين ، وكذلك أن المشاركات لم تحصل بعد على عدد كافٍ من الإيجابيات.



في الجزء السفلي من الرسم البياني ، يعرض الخط الأحمر أيضًا بشكل تفاعلي عدد المقالات الفريدة لتاريخ محدد.



دعونا نحفظ المخطط كملف html.



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


تجمعات البيانات



دعنا نرى عدد المؤلفين في مجموعة البيانات:



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






كم عدد المقالات لكل مؤلف:



data1['user_name'].value_counts()






من يكتب غالبًا (أكثر من 500 مقالة):



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


هذا هو الذي "يسد" المورد). لا يوجد الكثير منهم:



المؤلفون
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



دعونا نرى عدد المجتمعات الموجودة على المورد إجمالاً:



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






وما هو الأكثر غزارة:



data1['story__community_link'].value_counts()






* البيانات حول المجتمع ليست صحيحة تمامًا ، حيث تم جمع المجتمع المذكور الأول أثناء التحليل ، وغالبًا ما يشير المؤلفون إلى عدة أجزاء.



أخيرًا ، دعنا نرى كيفية تطبيق الوظيفة مع إخراج النتيجة في عمود منفصل .



ستكون هناك حاجة إلى هذا لمزيد من الدراسة لمجموعة البيانات.



وظيفة بسيطة لتعيين تصنيف مقال إلى مجموعة.



إذا كان التصنيف أكثر من <5000 - سيئ ،> 5000 - جيد.



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'


دعنا نطبق دالة ratingGroup على DataFrame ونعرض النتيجة في عمود منفصل -ratingGroup



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


سيظهر عمود جديد في مجموعة البيانات بالقيم التالية:







تنزيل - مجموعة بيانات .



قم بتنزيل مجموعة بيانات غير نظيفة لتنظيف التكرارات بنفسك - مجموعة بيانات .



* ينظف بيثون (يزيل الأسطر المكررة بناءً على معرف المقالة) لمدة ساعة تقريبًا! إذا أعاد شخص ما كتابة الكود في C ++ ، فسأكون ممتنًا!:



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)


السؤال واضح ، لأن بشكل غير متوقع) وجد قاموسًا بلغة بيثون يعمل أسرع بعشر مرات:

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()


Jupyter Notebook - تنزيل .



All Articles