Habrastatistika: kako Habr živi bez geektimesa

Hej Habr.

Ovaj članak je logičan nastavak ocjene Najbolji članci Habra za 2018. I premda godina još nije završila, kao što znate, ljeti je došlo do promjena u pravilima pa je postalo zanimljivo vidjeti hoće li to na nešto utjecati.

Habrastatistika: kako Habr živi bez geektimesa

Uz stvarnu statistiku, bit će osigurana ažurirana ocjena članaka, kao i neki izvorni kod za one koje zanima kako to funkcionira.

Za one koje zanima što se dogodilo, nastavak je pod rezom. Oni koji su zainteresirani za detaljniju analizu dijelova stranice također mogu pogledati sljedeći dio.

Početni podaci

Ova ocjena je neslužbena i nemam nikakvih insajderskih informacija. Kao što možete lako vidjeti gledajući adresnu traku svog preglednika, svi članci na Habréu imaju kontinuirano numeriranje. Onda je to stvar tehnike, jednostavno čitamo sve članke redom u petlji (u jednoj niti i sa pauzama, da ne opteretimo server). Same vrijednosti dobivene su jednostavnim parserom u Pythonu (izvori su dostupni здесь) i spremljeno u csv datoteku otprilike ovako:

2019-08-11T22:36Z,https://habr.com/ru/post/463197/,"Blazor + MVVM = Silverlight наносит ответный удар, потому что древнее зло непобедимо",votes:11,votesplus:17,votesmin:6,bookmarks:40,views:5300,comments:73
2019-08-11T05:26Z,https://habr.com/ru/news/t/463199/,"В NASA испытали систему автономного управления одного микроспутника другим",votes:15,votesplus:15,votesmin:0,bookmarks:2,views:1700,comments:7

Obrada

Za parsiranje ćemo koristiti Python, Pandas i Matplotlib. Oni koje statistika ne zanima mogu preskočiti ovaj dio i prijeći odmah na članke.

Prvo morate učitati skup podataka u memoriju i odabrati podatke za željenu godinu.

import pandas as pd
import datetime
import matplotlib.dates as mdates
from matplotlib.ticker import FormatStrFormatter
from pandas.plotting import register_matplotlib_converters


df = pd.read_csv("habr.csv", sep=',', encoding='utf-8', error_bad_lines=True, quotechar='"', comment='#')
dates = pd.to_datetime(df['datetime'], format='%Y-%m-%dT%H:%MZ')
df['datetime'] = dates
year = 2019
df = df[(df['datetime'] >= pd.Timestamp(datetime.date(year, 1, 1))) & (df['datetime'] < pd.Timestamp(datetime.date(year+1, 1, 1)))]

print(df.shape)

Ispada da je ove godine (iako još nije završena) u trenutku pisanja objavljeno 12715 članaka. Za usporedbu, za cijelu 2018. - 15904. Općenito, puno - to je oko 43 članka dnevno (i to samo s pozitivnom ocjenom; koliko se ukupno članaka preuzme koji su bili negativni ili su izbrisani, može se samo pogoditi ili grubo procijeniti na temelju praznina među identifikatorima).

Odaberimo potrebna polja iz skupa podataka. Kao metriku koristit ćemo broj pregleda, komentara, vrijednosti ocjena i broj oznaka.

def to_float(s):
    # "bookmarks:22" => 22.0
    num = ''.join(i for i in s if i.isdigit())
    return float(num)

def to_int(s):
    # "bookmarks:22" => 22
    num = ''.join(i for i in s if i.isdigit())
    return int(num)

def to_date(dt):
    return dt.date() 

date = dates.map(to_date, na_action=None)
views = df["views"].map(to_int, na_action=None)
bookmarks = df["bookmarks"].map(to_int, na_action=None)
votes = df["votes"].map(to_float, na_action=None)
votes_up = df["up"].map(to_float, na_action=None)
votes_down = df["down"].map(to_float, na_action=None)
comments = df["comments"].map(to_int, na_action=None)

df['date'] = date
df['views'] = views
df['votes'] = votes
df['bookmarks'] = bookmarks
df['up'] = votes_up
df['down'] = votes_down

Sada su podaci dodani u skup podataka i možemo ih koristiti. Grupirajmo podatke po danima i uzmimo prosječne vrijednosti.

g = df.groupby(['date'])
days_count = g.size().reset_index(name='counts')
year_days = days_count['date'].values
grouped = g.median().reset_index()
grouped['counts'] = days_count['counts']
counts_per_day = grouped['counts'].values
counts_per_day_avg = grouped['counts'].rolling(window=20).mean()
view_per_day = grouped['views'].values
view_per_day_avg = grouped['views'].rolling(window=20).mean()
votes_per_day = grouped['votes'].values
votes_per_day_avg = grouped['votes'].rolling(window=20).mean()
bookmarks_per_day = grouped['bookmarks'].values
bookmarks_per_day_avg = grouped['bookmarks'].rolling(window=20).mean()

Sada je zanimljiv dio da možemo pogledati grafikone.

Pogledajmo broj objava na Habréu u 2019.

import matplotlib.pyplot as plt

plt.rcParams["figure.figsize"] = (16, 8)
fig, ax = plt.subplots()

plt.bar(year_days, counts_per_day, label='Articles/day')
plt.plot(year_days, counts_per_day_avg, 'g-', label='Articles avg/day')
plt.xticks(rotation=45)
ax.xaxis.set_major_formatter(mdates.DateFormatter("%d-%m-%Y"))  
ax.xaxis.set_major_locator(mdates.MonthLocator(interval=1))
plt.legend(loc='best')
plt.tight_layout()
plt.show()

Rezultat je zanimljiv. Kao što vidite, Habr je tijekom cijele godine malo “kobasirao”. Ne znam razlog.

Habrastatistika: kako Habr živi bez geektimesa

Za usporedbu, 2018. izgleda malo glađe:

Habrastatistika: kako Habr živi bez geektimesa

Općenito, na grafikonu nisam vidio neki drastičan pad broja objavljenih članaka u 2019. godini. Štoviše, naprotiv, čini se da je od ljeta čak i malo porasla.

Ali sljedeća dva grafikona me još malo deprimiraju.

Prosječan broj pregleda po članku:

Habrastatistika: kako Habr živi bez geektimesa

Prosječna ocjena po članku:

Habrastatistika: kako Habr živi bez geektimesa

Kao što vidite, prosječan broj pregleda lagano opada tijekom godine. To se može objasniti činjenicom da novi članci još nisu indeksirani na tražilicama, te se ne pronalaze tako često. Ali neshvatljiviji je pad prosječne ocjene po članku. Osjećaj je da čitatelji ili jednostavno nemaju vremena pregledavati toliko članaka ili ne obraćaju pozornost na ocjene. Sa stajališta programa nagrađivanja autora, ovaj trend je vrlo neugodan.

Inače, u 2018. to se nije dogodilo, a raspored je više-manje izjednačen.

Habrastatistika: kako Habr živi bez geektimesa

Općenito, vlasnici resursa imaju o čemu razmišljati.

Ali nemojmo o tužnim stvarima. Općenito, možemo reći da je Habr prilično uspješno “preživio” ljetne promjene, a broj članaka na stranici se nije smanjio.

Ocjena

Sada, zapravo, ocjena. Čestitke onima koji su ušli u to. Podsjećam vas još jednom da je ocjena neslužbena, možda sam nešto propustio, a ako bi neki članak definitivno trebao biti ovdje, ali nije, napišite, ručno ću ga dodati. Kao ocjenu koristim izračunatu metriku, za koju mislim da se pokazala prilično zanimljivom.

Najbolji članci po broju pregleda

Najbolji članci prema omjeru ocjene i pregleda

Najbolji članci prema omjeru komentara i pregleda

Vrh najkontroverznijih članaka

Najbolji članci prema ocjeni

Najbolji članci po broju oznaka

Vrh po omjeru oznaka i prikaza

Najbolji članci po broju komentara

I na kraju, posljednji Antitop po broju dislajkova

Uf. Imam još nekoliko zanimljivih izbora, ali neću zamarati čitatelje.

Zaključak

Prilikom konstruiranja ocjene obratio sam pažnju na dvije točke koje su se činile zanimljivima.

Prvo, 60% vrha su članci žanra “geektimes”. Hoće li ih sljedeće godine biti manje i kako će Habr izgledati bez tekstova o pivu, svemiru, medicini itd., ne znam. Definitivno će čitatelji nešto izgubiti. Da vidimo.

Drugo, pokazalo se da su top oznake neočekivano visoke kvalitete. To je psihološki razumljivo; čitatelji možda neće obratiti pozornost na ocjenu, ali ako članak trebati, tada će biti dodan u vaše oznake. I upravo je tu najveća koncentracija korisnih i ozbiljnih članaka. Mislim da bi vlasnici stranica trebali nekako razmisliti o vezi između broja knjižnih oznaka i programa nagrađivanja ako žele povećati ovu kategoriju članaka ovdje na Habréu.

Nešto kao ovo. Nadam se da je bilo informativno.

Popis članaka pokazao se dugim, pa, vjerojatno je tako i bolje. Sretno čitanje svima.

Izvor: www.habr.com

Dodajte komentar