Iniziamo importando alcune librerie utili.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import powerlaw
from scipy.stats import kurtosis
Successivamente, caricheremo ciascun set di dati e lo memorizzeremo in un dizionario.
filename_list = ('medium-followers', 'YT-earnings', 'LI-impressions')df_dict = {}
for filename in filename_list:
df = pd.read_csv('data/'+filename+'.csv')
df = df.set_index(df.columns(0)) # set index
df_dict(filename) = df
A questo punto, guardare i dati è sempre una buona idea. Possiamo farlo tracciando istogrammi e stampando i primi 5 record per ciascun set di dati.
for filename in filename_list:
df = df_dict(filename)# plot histograms (function bleow is defined in notebook on GitHub)
plot_histograms(df.iloc(:,0)(df.iloc(:,0)>0), filename, filename.split('-')(1))
plt.savefig("images/"+filename+"_histograms.png")
# print top 5 records
print("Top 5 Records by Percentage")
print((df.iloc(:,0)/df.iloc(:,0).sum()).sort_values(ascending=False)(:5))
print("")
In base agli istogrammi sopra riportati, ciascun set di dati appare in una certa misura con una coda grassa. Vediamo i primi 5 record in percentuale per dare un’altra occhiata a questo.
Da questo punto di vista, i follower medi appaiono quelli con la coda più grassa, con il 60% dei follower provenienti da soli 2 mesi. Anche i guadagni di YouTube sono fortemente “fat-tailed”, dove circa il 60% delle entrate proviene da soli 4 video. Le impressioni di LinkedIn sembrano quelle meno complesse.
Mentre potremmo avere un senso qualitativo della coda grassa solo da questo guardando i datirendiamolo più quantitativo attraverso le nostre 4 euristiche.
Euristica 1: Indice della coda della legge di potenza
Per ottenere un UN per ogni set di dati, possiamo utilizzare il file powerlaw biblioteca come abbiamo fatto nel articolo precedente. Questo viene fatto nel blocco di codice seguente, dove eseguiamo l’adattamento e stampiamo le stime dei parametri per ciascun set di dati in un ciclo for.
for filename in filename_list:
df = df_dict(filename)# perform Power Law fit
results = powerlaw.Fit(df.iloc(:,0))
# print results
print("")
print(filename)
print("-"*len(filename))
print("Power Law Fit")
print("a = " + str(results.power_law.alpha-1))
print("xmin = " + str(results.power_law.xmin))
print("")
I risultati di cui sopra corrispondono alla nostra valutazione qualitativa secondo cui i follower medi sono quelli con la coda più grassa, seguiti dai guadagni di YouTube e dalle impressioni di LinkedIn (ricorda, un numero più piccolo UN significa una coda più grossa).
Euristica 2: Kurtosi
Un modo semplice per calcolare Kurtosis è utilizzare un’implementazione standard. Ecco, io uso Scivoloso e stampare i risultati in modo simile a prima.
for filename in filename_list:
df = df_dict(filename)# print results
print(filename)
print("-"*len(filename))
print("kurtosis = " + str(kurtosis(df.iloc(:,0), fisher=True)))
print("")
Kurtosis ci racconta una storia diversa da Euristica 1. La classifica delle code grasse secondo questa misura è la seguente: LinkedIn > Medium > YouTube.
Tuttavia, questi risultati dovrebbero essere presi con le pinze. Come abbiamo visto sopra con la legge di potenza, tutti e 3 i set di dati si adattano a una legge di potenza UN < 4, il che significa che la Kurtosi è infinita. Quindi, anche se il calcolo restituisce un valore, probabilmente è saggio diffidare di questi numeri.
Euristica 3: σ log-normale
Possiamo nuovamente utilizzare il file powerlaw libreria per ottenere stime σ simili a quelle che abbiamo fatto Euristica 1. Ecco come appare.
for filename in filename_list:
df = df_dict(filename)# perform Power Law fit
results = powerlaw.Fit(df.iloc(:,0))
# print results
print("")
print(filename)
print("-"*len(filename))
print("Log Normal Fit")
print("mu = " + str(results.lognormal.mu))
print("sigma = " + str(results.lognormal.sigma))
print("")
Osservando i valori σ sopra, vediamo che tutti gli adattamenti implicano che i dati siano a coda grassa, dove i follower medi e le impressioni di LinkedIn hanno stime σ simili. I guadagni di YouTube, d’altro canto, hanno un valore σ significativamente più grande, il che implica una coda (molto) più grossa.
Un motivo di sospetto, tuttavia, è che l’adattamento stima un μ negativo, il che potrebbe suggerire che un adattamento log-normale potrebbe non spiegare bene i dati.
Euristica 4: κ di Taleb
Dato che non sono riuscito a trovare un’implementazione Python standard per il calcolo di κ (non ho cercato molto attentamente), questo calcolo richiede alcuni passaggi aggiuntivi. Vale a dire, dobbiamo definire 3 funzioni di supporto, come mostrato di seguito.
def mean_abs_deviation(S):
"""
Computation of mean absolute deviation of an input sample S
"""
M = np.mean(np.abs(S - np.mean(S)))return M
def generate_n_sample(X,n):
"""
Function to generate n random samples of size len(X) from an array X
"""
# initialize sample
S_n=0
for i in range(n):
# ramdomly sample len(X) observations from X and add it to the sample
S_n = S_n + X(np.random.randint(len(X), size=int(np.round(len(X)))))
return S_n
def kappa(X,n):
"""
Taleb's kappa metric from n0=1 as described here: https://arxiv.org/abs/1802.05495
Note: K_1n = kappa(1,n) = 2 - ((log(n)-log(1))/log(M_n/M_1)), where M_n denotes the mean absolute deviation of the sum of n random samples
"""
S_1 = X
S_n = generate_n_sample(X,n)
M_1 = mean_abs_deviation(S_1)
M_n = mean_abs_deviation(S_n)
K_1n = 2 - (np.log(n)/np.log(M_n/M_1))
return K_1n
La prima funzione, mean_abs_deviation(), calcola la deviazione assoluta media come definita in precedenza.
Successivamente, abbiamo bisogno di un modo per generare e sommare N campioni dai nostri dati empirici. Qui, adotto un approccio ingenuo e campione casualmente un array di input (X) N volte e sommare i campioni insieme.
Infine, riunisco media_deviazione_ass(S) E generare_n_campione(X,n) per implementare il calcolo κ definito in precedenza e calcolarlo per ciascun set di dati.
n = 100 # number of samples to include in kappa calculationfor filename in filename_list:
df = df_dict(filename)
# print results
print(filename)
print("-"*len(filename))
print("kappa_1n = " + str(kappa(df.iloc(:,0).to_numpy(), n)))
print("")
I risultati sopra ci danno ancora un’altra storia. Tuttavia, data l’implicita casualità di questo calcolo (ricord generare_n_campione() definizione) e il fatto che abbiamo a che fare con code spesse, non ci si può fidare delle stime puntuali (cioè eseguendo semplicemente il calcolo una volta).
Di conseguenza, eseguo lo stesso calcolo 1000x e stampo la media k(1.100) per ciascun set di dati.
num_runs = 1_000
kappa_dict = {}for filename in filename_list:
df = df_dict(filename)
kappa_list = ()
for i in range(num_runs):
kappa_list.append(kappa(df.iloc(:,0).to_numpy(), n))
kappa_dict(filename) = np.array(kappa_list)
print(filename)
print("-"*len(filename))
print("mean kappa_1n = " + str(np.mean(kappa_dict(filename))))
print("")
Questi risultati più stabili indicano che i follower medi sono quelli con la coda più grassa, seguiti dalle impressioni di LinkedIn e dai guadagni di YouTube.
Nota: è possibile confrontare questi valori con la Tabella III nel rif (3) per comprendere meglio ciascun valore κ. Vale a dire, questi valori sono paragonabili a una distribuzione di Pareto con α compreso tra 2 e 3.
Sebbene ciascuna euristica raccontasse una storia leggermente diversa, tutti i segnali indicano che i follower medi guadagnati sono quelli con la coda più grassa dei 3 set di dati.
Sebbene l’etichettatura binaria dei dati come coda grassa (o meno) possa essere allettante, la coda grassa vive in uno spettro. Qui, abbiamo suddiviso 4 euristiche per la quantificazione che coda grassa i dati sono.
Sebbene ciascun approccio abbia i suoi limiti, fornisce ai professionisti metodi quantitativi per confrontare la coda grassa dei dati empirici.
👉 Maggiori informazioni su leggi di potenza e code grasse: introduzione | La legge sul potere si adatta
Fonte: towardsdatascience.com