…кроме песни о стрингах? Я не могу вспомнить ничего более горячего, чем песня о стрингах в 2000 году. Будучи школьником, когда она вышла… я не могу сказать вам, сколько моих друзей (включая меня) любили эту песню… но понятия не имели, что это за песня. стринги были.

Несколько дней назад она появилась в моем плейлисте в случайном порядке, и я задумался, какие песни были популярны в 2000 году?

Очистка и обработка данных

Я начал с набора данных от billboard.com для песен, которые вошли в топ-100 Billboard в 2000 году.

Давайте начнем с небольшого исследовательского анализа данных:

Похоже, у меня достаточно данных: 317 строк и 83 столбца, все в строковой форме. У нас есть типичная информация о песне: исполнитель, трек, длина песни, жанр. Затем некоторая информация об исполнении песни в 2000 году — дата вошла в топ-100, дата достигла пика, а затем один столбец с рейтингом песни для каждой из 76 недель пребывания в топ-100. Самая популярная песня, попавшая в список. в 2000 году должно было занимать первое место в списке максимум 76 недель, в то время как не каждая песня имеет запись в каждой из этих 76-недельных колонок.

Прежде всего, мне нужно было преобразовать данные в рабочие типы, чтобы выполнить анализ.

Я решил, что мне нужно сделать две вещи:

  1. Преобразуйте числовые данные в рабочие формы. Сюда входят столбцы длины песни, даты ввода, даты пика.
  2. Создайте пару сводных столбцов с громоздкими 76 столбцами данных за неделю, чтобы я мог легко с ними работать.

Для шага 1 я написал несколько функций и использовал конвертер даты и времени, встроенный в pandas, для преобразования столбцов времени. Я создал 6 новых столбцов: длина песни в минутах и ​​секундах, введенное время, время пика и дни пика (разница между введенным и пиковым) во времени и в целочисленной форме.

import pandas as pd
import numpy as np
import re
from datetime import datetime
from scipy import stats
data=pd.read_csv("billboard.csv")
data2=data
def minute (n):
    return int(n[0])
def second (n):
    return int(n[2:4])
data2["min_lenth"]=data2['time'].apply(minute)
data2["sec_length"]=data2['time'].apply(second)
data2["time_entered"]=pd.to_datetime(data2['date.entered'])
data2["time_peaked"]=pd.to_datetime(data2['date.peaked'])
data2["days_peaked"]=data2["time_peaked"]-data2["time_entered"]
data2["int_days_peaked"]=data2["days_peaked"].dt.days

Для шага 2 я создал функцию, которую я мог применить только к столбцам недель, что позволило мне извлечь общее количество недель в Billboard 100 и среднюю позицию за это время.

def weekcleaner (x):
    if x=="*":
        return np.nan
    else:
        return float(x)
data2.loc[:,'x1st.week':'x76th.week']=data2.loc[:,'x1st.week':'x76th.week'].applymap(weekcleaner)
data2["sum_of_weeks"]= data2.loc[:,'x1st.week':'x76th.week'].count(axis=1)
data2["average_place"]=data2.loc[:,'x1st.week':'x76th.week'].apply(np.mean, axis=1)

Изучение данных

Итак, давайте взглянем на 10 песен, которые дольше всех продержались на чарте Billboard 100:

Кредо! Не ожидал увидеть тебя там в #1. Два топ-10 хита… в 2000-м у нас был не самый лучший музыкальный вкус.

Где Сиско?

Неплохо, 3 песни в топ-100, а Thong Song провела в топ-100 28 недель.

Меня интересовало исполнение песни, поэтому я хотел сделать быструю визуализацию характеристик исполнения песни — дни пика, недели в Billboard 100 и среднее место:

Любопытная тенденция обнаружилась, когда я просмотрел общее количество недель, проведенных в топ-100: на 20-й неделе наблюдается большой всплеск. Любопытно, почему большинство песен достигает своего пика в 20 недель? Billboard должны приложить усилия, чтобы выпустить песни, которым исполнилось 20 недель. Обратимся к википедии:

Конечно же, песни, которые достигают 20 недель и находятся ниже 50-го рейтинга, автоматически выпадают.

Давайте проверим набор данных, чтобы увидеть, так ли это:

Я создал функцию, которая позволила бы мне найти первое место песни, когда она попала в топ-100, и последнее место песни перед тем, как она вышла из топ-100.

def first_rank(x):
    if x.first_valid_index() is None:
        return None
    else:
        return x[x.first_valid_index()]
    
weeks=data2.loc[:,'x1st.week':'x76th.week']
    
data2["first_rank"]=weeks.apply(first_rank, axis=1)
data2["last_rank"]=weeks.loc[::,::-1].apply(first_rank, axis=1)
data2['peak_rank']=pd.Series(weeks.min(axis=1))
data3=data2[['artist.inverted', 'track',"int_days_peaked", "average_place", "sum_of_weeks", "first_rank", "x20th.week","last_rank"]]
print(np.mean(data3[data3['sum_of_weeks']==20]["last_rank"]))
data3[data3['sum_of_weeks']==20]
data3[data3['sum_of_weeks']==20]['last_rank'].describe()
plt.figure(figsize=(4,2))
sns.distplot(data3[data3['sum_of_weeks']==20]['last_rank'])

Если мы посмотрим на последний рейтинг песен, которые находились в топ-100 ровно 20 недель:

Среди 82 песен, которые оставались в течение 20 недель, их средний рейтинг был 80. Судя по распределению, подавляющее большинство песен были выше 50 рейтинга, что показывает нам, что действительно те песни с рейтингом ниже 50 были автоматически загружены из топ-100 один раз. 20 недель истекли. Я предполагаю, что пара с рейтингом ниже 50 просто выпала из первой сотни после 20-й недели.

Выводы из данных

Я также хотел посмотреть, есть ли отношения, которые я мог бы выявить между переменными. Что помогло песням продержаться больше 20 недель? Одна гипотеза, которую я хотел проверить, заключалась в следующем: песни, которые остаются в топ-100 более 20 недель, начинаются с более высокого ранга и достигают более высокого ранга, чем песни, которые этого не делают.

Во-первых, беглый взгляд на взаимосвязь между переменными:

data3=data2[['artist.inverted', 'track',"int_days_peaked", "average_place", "sum_of_weeks"]]
data3.sort_values('int_days_peaked',ascending=False)
data3.sort_values('average_place',ascending=True)
data3.sort_values('sum_of_weeks',ascending=False)
dataplot=data2[["int_days_peaked", "average_place", "sum_of_weeks"]]
sns.pairplot(dataplot, kind='reg', size=2, aspect=1.5)

Использование pairplot из пакета seaborn — отличный способ визуализировать попарные отношения между группой переменных. Все отношения, которые мы ожидаем увидеть, проявляются: чем дольше песня достигает своего пика, тем дольше она остается в топ-100. Чем выше средний рейтинг (меньше ранговое число), тем дольше песня находится в топ-100.

Чтобы увидеть, действительно ли популяция песен в топ-100 в течение более 20 недель (песни_>20) и песни, которые не могут продержаться более 20 недель (песни_‹20), действительно различаются, я собираюсь использовать 2 образца студенческого теста. Т-тест.

Допущения. Поскольку я не ожидаю, что эти две совокупности будут иметь одинаковую дисперсию ИЛИ одинаковые размеры (n), я буду использовать Т-критерий Уэлча. Этот Т-критерий Стьюдента предназначен для одинаковых или неравных размеров выборки и неравных дисперсий.



Моя нулевая гипотеза или H0 = В совокупности песен_›20 и песен_‹20 нет статистически значимой разницы между начальным и максимальным рейтингом.

Я установлю порог значения p равным 0,05 или 5%.

Другими словами, являются ли песни, которые начинаются горячими или пиковыми, обладают выносливостью?

Чтобы запустить этот тест, мне придется сначала разделить песни_>20 и песни_‹20, а затем запустить t-тест на образцах. В библиотеке статистики в библиотеке scipy на python есть отличная функция, которая может помочь нам в этом, называемая stats.ttest_ind().

from scipy import stats
songs_above_20=data3[data3['sum_of_weeks']>20][["first_rank", 'peak_rank']]
songs_stuck_at20=data3[data3['sum_of_weeks']<=20][["first_rank", 'peak_rank']]
print("first rank:", stats.ttest_ind(songs_above_20['first_rank'], songs_stuck_at20['first_rank'], equal_var=False))
print("peak rank:", stats.ttest_ind(songs_above_20['peak_rank'], songs_stuck_at20['peak_rank'], equal_var=False))
fig, ax= plt.subplots()
sns.distplot(songs_above_20['first_rank'], label='above 20')
sns.distplot(songs_stuck_at20['first_rank'], label='below 20')
ax.legend(loc='upper left')
fig, ax= plt.subplots()
sns.distplot(songs_above_20['peak_rank'], label='above 20')
sns.distplot(songs_stuck_at20['peak_rank'], label='below 20')
ax.legend(loc='upper right')

Результаты подтверждают мою гипотезу. Значения p как для первого, так и для последнего ранга значительно ниже порога 0,05, поэтому мы можем смело отклонить нулевую гипотезу — существует статистически значимая разница между двумя популяциями в отношении переменных первого и последнего ранга. На самом деле нам действительно нужно разделить эти значения p пополам, поскольку они являются двусторонними значениями p, и мы на самом деле только проверяем и ожидаем, что пиковый ранг и первый ранг ›20 больше (меньшее ранговое число), чем ‹ 20 человек.

Мы также видим, что между двумя переменными ранг пика является реальным отличительным фактором. Те песни, которые обладают истинной выносливостью, достигают пика и на этой волне долгое время находятся в топ-100, продержавшись на 20-й неделе.

Хорошо, что песня о стрингах заняла 3-е место.