…кроме песни о стрингах? Я не могу вспомнить ничего более горячего, чем песня о стрингах в 2000 году. Будучи школьником, когда она вышла… я не могу сказать вам, сколько моих друзей (включая меня) любили эту песню… но понятия не имели, что это за песня. стринги были.
Несколько дней назад она появилась в моем плейлисте в случайном порядке, и я задумался, какие песни были популярны в 2000 году?
Очистка и обработка данных
Я начал с набора данных от billboard.com для песен, которые вошли в топ-100 Billboard в 2000 году.
Давайте начнем с небольшого исследовательского анализа данных:
Похоже, у меня достаточно данных: 317 строк и 83 столбца, все в строковой форме. У нас есть типичная информация о песне: исполнитель, трек, длина песни, жанр. Затем некоторая информация об исполнении песни в 2000 году — дата вошла в топ-100, дата достигла пика, а затем один столбец с рейтингом песни для каждой из 76 недель пребывания в топ-100. Самая популярная песня, попавшая в список. в 2000 году должно было занимать первое место в списке максимум 76 недель, в то время как не каждая песня имеет запись в каждой из этих 76-недельных колонок.
Прежде всего, мне нужно было преобразовать данные в рабочие типы, чтобы выполнить анализ.
Я решил, что мне нужно сделать две вещи:
- Преобразуйте числовые данные в рабочие формы. Сюда входят столбцы длины песни, даты ввода, даты пика.
- Создайте пару сводных столбцов с громоздкими 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-е место.