Добрый день, уважаемые читатели. Недавно мне на глаза попался отрывок статистики PornHub, где хранились данные про 190к видеоматериалов. Сам датасет находится на kaggle. Мы проведём анализ данных PornHub и визуализируем результаты статистики.
Сегодня мы узнаем, какие самые высокооцениваемые, продолжительные или просматриваемые категории.
Подпишись на группу Вконтакте и Телеграм-канал. Там еще больше полезного контента для программистов.
А на YouTube-канале ты найдешь обучающие видео по программированию. Подписывайся!
Загрузка данных
Для начала импортируем все необходимые пакеты, т.к. для анализа мы будем использовать язык программирования Python.
In[1]: import pandas as pd import numpy as np import matplotlib.pyplot as plt
Загрузим данные в таблицу pandas
и извлечём размер таблицы.
In[2]: df = pd.read_csv('data.csv') total_size = len(df) df.head()
Каждый раз я буду вызывать метод head()
для проверки корректности операций над таблицей.
Удалим ненужные столбцы с помощью конструкции del
:
In[3]: del df['Unnamed: 0'] del df['img_source'] del df['video_link'] del df['tags'] df.head()
Отбор категорий
Вся сложность в распределении видео по категориям состоит в том, что поле category содержит строки вида «Category1__Category2__…».
И чтобы правильно присвоить каждому видео несколько категорий, нам необходим особый механизм, который мы сейчас и реализуем.
Чтобы создать список всех категорий, выполним следующий фрагмент кода:
In[4]:
categories = list()
for category in df['categories'].values:
category = str(category)
for tag in category.split('__'):
if not tag in categories:
categories.append(tag)
categories[:5]
Out[5]:
['Blowjob', 'Threesome ', 'Brunette', 'Blonde', 'MILF ']
Примечание. Я не буду переводить название категорий в виду своей неполной компетентности в этом вопросе :) Кто знает, тот поймёт.
Теперь для каждой категории создадим соответствующий столбец в таблице, состоящий из нулей.
In[5]:
for tag in categories:
df[tag] = np.zeros(total_size)
df.head()
Из предыдущих двух фрагментов кода, ничего, кроме стандартных конструкций python не использовалось, потому с этим у обывателя проблем возникнуть не должно.
Теперь по следующему алгоритму заполним столбцы:
- пройдёмся по всем названиям категорий
- разделяем значение поля category по ‘__’ для каждого видео
- если одна из категорий соответствует текущему, то присваиваем соответствующему элементу столбца значение 1
- передаём новый столбец в таблицу
In[6]:
for tag in categories:
column = np.zeros(total_size)
for i, category in enumerate(df[categories]):
if tag in category.split('__'):
column[i] = 1
df[tag] = column
df.head()
Визуализация
Следующие три фрагмента кода очень похожи и легки по своему смыслу, поэтому просто приведу их, а затем покажу результат их выполнения.
In[7]:
votes = [(tag, df[df[tag] == 1]['voting'].values.mean()) for tag in categories]
votes.sort(reverse=True, key=lambda set: set[1])
votes = votes[:15]; votes.reverse()
scores = [set[1] for set in votes]
labels = [set[0] for set in votes]
plt.figure(figsize=(20, 10))
plt.yticks(range(15), labels, fontsize=20)
plt.title('Most voited categories on PornHub', fontsize=20)
plt.xlabel('Vote', fontsize=20); plt.ylabel('Category', fontsize=20)
plt.barh(range(15), scores, height=0.5, color='blue')
plt.savefig('votes.png')

In[8]:
views = [(tag, df[df[tag] == 1]['nb_views'].values.mean()) for tag in categories]
views.sort(reverse=True, key=lambda set: set[1])
views = views[:15]; views.reverse()
view = [set[1] / 10**6 for set in views]
labels = [set[0] for set in views]
plt.figure(figsize=(20, 10))
plt.yticks(range(15), labels, fontsize=20)
plt.title('Most viewed categories on PornHub', fontsize=20)
plt.xlabel('Mean views (in millions)', fontsize=20);
plt.ylabel('Category', fontsize=20)
plt.barh(range(15), view, height=0.5, color='blue')
plt.savefig('views.png')

Warning! Вас тоже смущает значительный отрыв категории «Babe»? Скорее всего это связанно с выбросом в данных. Попробуйте самостоятельно разобрать этот момент.
In[9]:
lengths = [(tag, df[df[tag] == 1]['length'].values.mean()) for tag in categories]
lengths.sort(reverse=True, key=lambda set: set[1])
lengths = lengths[:15]; lengths.reverse()
length = [set[1] / 60 for set in lengths]
labels = [set[0] for set in lengths]
plt.figure(figsize=(20, 10))
plt.yticks(range(15), labels, fontsize=20)
plt.title('Most "longest" categories on PornHub', fontsize=20)
plt.xlabel('Mean length (in minutes)', fontsize=20);
plt.ylabel('Category', fontsize=20)
plt.barh(range(15), length, height=0.5, color='blue')
plt.savefig('lengths.png')

Заключение про анализ данных PornHub
Как мы можем заметить, исследование статистики порносайтов порой приносят интересные наблюдения. В таблице много «полей», которые вы можете исследовать. Подкидываю пищу для размышлений: попробуйте выяснить, какие слова наиболее часто встречаются в названиях порнографии (естественно, слова по типу I, and, too не должны учитываться)?
Ссылка на документ с кодом, который вы можете просмотреть и изменить на своё усмотрение, используя Jupyter Notebook.
Также рекомендую прочитать статью Функциональный API библиотеки Keras. А также подписывайтесь на группу ВКонтакте, Telegram и YouTube-канал. Там еще больше полезного и интересного для программистов.