• Хабр: Как я создал собственный алгоритм YouTube (чтобы не тратить время впустую)



    Побег от алгоритма YouTube


    Я люблю смотреть видео на YouTube, осязаемым образом улучшающие мою жизнь. К сожалению, алгоритм YouTube с этим не согласен. Он любит кормить меня кликбэйтом и прочим мусором.

    Всё это неудивительно: алгоритм отдаёт приоритет кликам и времени просмотра.

    Поэтому я поставил перед собой задачу: Смогу ли я написать код, который автоматически будет находить ценные видео, избавив меня от привязанности к алгоритму YouTube?

    Вот так всё и началось.

    Оптимально выстроенные планы


    Я начал с визуализации того, что должен делать мой инструмент. Мне нужна была программа, которая будет (i) ранжировать видео на основании вероятной релевантности для меня и (ii) автоматически отправлять мне предлагаемые видео, из которых я смогу выбирать.

    Я решил, что смогу серьёзно повысить продуктивность, если буду пакетно выбирать наборы видео для просмотра на каждую неделю и избавлюсь от необходимости бесконечного скроллинга YouTube.


    Я знал, что нужно заставить YouTube API получать информацию о видео (что такое API?). Затем я создам формулу, которая будет обрабатывать эту информацию для ранжирования видео. На последнем этапе я запланировал создавать при помощи AWS Lambda автоматическое письмо на мой адрес, содержащее видео с наивысшим рейтингом.

    Однако в конечном итоге всё получилось не совсем так.

    (Если не хотите читать статью и перейти прямиком к готовому коду, то вам сюда.)

    Исследуем YouTube API


    Я хотел найти метрики, которые можно использовать для ранжирования видео по их вероятной интересности для меня.

    Я изучил документацию YouTube, выложенную здесь, и понял, что можно получать информацию на уровне видео (название, время публикации, количество просмотров, картинка-превью и т.д.) и на уровне канала (количество подписчиков, комментарии, просмотры, плейлисты канала и т.д.).

    Когда я увидел это, у меня появилась уверенность в том, что можно использовать эту информацию для задания метрики и ранжирования видео.

    Я получил ключ API через консоль разработчика здесь и скопировал его в мой скрипт на Python.

    Это позволяет инициализировать API такими строками кода:

    # Call the YouTube API api_key = ‘AIzpSyAq3L9DiPK0KxrGBbdY7wNN7kfPbm_hsPg’ # Enter your own API key – this one won’t work youtube_api = build(‘youtube’, ‘v3’, developerKey = api_key) results = youtube_api.search().list(q=search_terms, part=’snippet’, type=’video’, order=’viewCount’, maxResults=50).execute()


    Код возвращает объект JSON, который можно парсить для поиска соответствующей информации. Например, для нахождения даты публикации можно индексировать results следующим образом:

    publishedAt = results[‘items’][0][‘snippet’][‘publishedAt’]


    Есть полезная серия видео, в которой подробно описывается процесс использования YouTube API.

    Поиск ценных видео: задаём свою формулу


    Теперь, когда я мог запрашивать соответствующую информацию, мне нужно было использовать полученные значения для ранжирования видео по их интересности для меня.

    Это было непросто. В чём заключается интересность видео? В количестве просмотров? В количестве комментариев? В количестве подписчиков канала?

    Я решил начать с общего количества просмотров как приближенной ценности видео на первой ступени. Теоретически, интересные или хорошо раскрывающие тему видео получают положительный отзыв аудитории, активнее продвигаются, а значит, имеют большее количество просмотров.

    Однако есть аспекты, которые общее количество просмотров не учитывает:

    Во-первых, если канал накопил большую аудиторию, то ему гораздо проще получить высокий уровень просмотров по сравнению с менее популярными каналами. Частично это может отражать больший опыт авторов, что ведёт к созданию более качественных видео, но я не хотел принижать в рейтинге потенциально высококачественные видео с мелких каналов. Видео с 100 000 просмотров на канале с 10 000 подписчиков вероятно лучше, чем видео с 100 000 просмотров на канале с 1 миллионом подписчиков.

    Во-вторых, видео могут получать большое количество просмотров не по тем причинам, например, из-за кликбэйтных названий или превью, или из-за того, что вызывали споры. Лично мне меньше интересны подобные видео.

    Мне нужно было как-то учесть эти метрики. Следующий параметр — это количество подписчиков.

    Я протестировал рейтинги, основанные исключительно на соотношении просмотров к подписчикам (т.е. поделив просмотры на количество подписчиков).

    # Function to calculate view-to-sub ratio def view_to_sub_ratio(viewcount, num_subscribers): if num_subscribers == 0: return 0 else: ratio = viewcount / num_subscribers return ratio


    При изучении результатов некоторые из них выглядели многообещающе. Однако я заметил проблему: для видео с очень малым количеством подписчиков оценка сильно возрастает и они поднимаются наверх.


    Хотя верхнее видео потенциально выглядит интересными, второе и третье — это совсем не то, что я искал.

    Я предпринял меры, чтобы устранить эти отрицательные граничные случаи:

    • Задал минимальное количество просмотров — 5000
    • Задал максимальное соотношение просмотров и подписчиков — 5

    # Calculating ratio while removing edge cases (of low views or low subscribers) def custom_score(viewcount, ratio, days_since_published): ratio = min(ratio, 5) score = (viewcount * ratio) return score


    Я поэкспериментировал с разными пороговыми значениями, и мне показалось, что именно эти достаточно хорошо отфильтровывают видео с малым количеством подписчиков и просмотров. Протестировав код на нескольких разных темах, я наконец начал получать довольно приличные результаты.

    Однако я заметил ещё одну проблему: видео, опубликованные раньше, имели более высокую вероятность получить больше просмотров. У них просто было больше времени на накопление просмотров.

    Я планировал запускать этот код раз в неделю, поэтому решил ограничить поиск видеороликами, опубликованными за последние 7 дней.

    # Function to create string for search start date def get_start_date_string(search_period_days): """Returns string for date at start of search period.""" search_start_date = datetime.today() – timedelta(search_period_days) date_string = datetime(year=search_start_date.year,month=search_start_date.month, day=search_start_date.day).strftime(‘%Y-%m-%dT%H:%M:%SZ’) return date_string # Creating date string and executing search date_string = get_start_date_string(7) results = youtube_api.search().list(q=search_terms, part=’snippet’, type=’video’, order=’viewCount’, maxResults=50, publishedAfter=date_string).execute()


    Также я добавил в метрику ранжирования параметр «количество дней после публикации». Я решил делить предыдущую оценку на количество дней, чтобы окончательная метрика была пропорциональна времени после публикации.

    # Adding days since published into custom score def custom_score(viewcount, ratio, days_since_published): if ratio > 5: ratio = 5 score = (viewcount * ratio) / days_since_published return score


    Продолжив тестировать код, я выяснил, что он достаточно стабильно определяет отличные видео, которые мне хотелось бы посмотреть. Я поэкспериментировал с различными вариациями и весами компонентов моей формулы, но понял, что это неточная наука, поэтому остановился на следующей формуле, в которой, как мне показалось, есть баланс простоты с эффективностью:


    Функция ценности

    Тестируем новый инструмент


    Сначала я протестировал его на запросе «medical school». Были получены следующие результаты:


    Затем я зашёл на YouTube и вручную поискал видео, связанные с медициной и медицинскими образовательными учреждениями. Оказалось, что мой инструмент обнаружил все видео, которые мне было бы интересно посмотреть. В частности, мне понравилось видео доктора Кевина Джаббала (Kevin Jabbal).

    Я протестировал ещё один поисковый запрос, «productivity», и снова был вполне доволен результатами:


    Второе видео оказалось слегка неожиданным и не тем, что мне было нужно. Но я не смог придумать простого способа отсеивать эти видео, которые подбирались из-за другого значения поискового запроса.

    Спустя несколько месяцев компания OpenAI выпустила очень интересную новую нейронную сеть под названием GPT-3. Я решил протестировать свой поисковик с поисковым запросом «GPT-3», и нашёл такое видео:


    Это интересное видео автора всего с несколькими тысячами подписчиков.

    Если бы я ввёл тот же запрос на YouTube.com, мне пришлось бы проскроллить все видео о GPT-3 всех крупных каналов, прежде чем найти это видео на 31-м месте.


    Видео про GPT-3 на каналах с более крупными аудиториями

    Поиск таких интересных видео со свежим взглядом намного проще выполнять при помощи написанного мной кода Video Finder.

    За последние несколько месяцев я пробовал различные поисковые запросы по моим интересам, например, «artificial intelligence», «medical AI» и «Python programming». В пяти лучших видео, предложенных Video Finder, почти без сбоев всегда было хотя бы одно интересное видео.

    Подготовка рабочего процесса


    Я причесал код и загрузил его на GitHub.

    Если описывать в общих чертах, мой код теперь работал следующим образом:

    1. Используем поисковые запросы, временной интервал и ключ API для извлечения информации с YouTube
    2. Парсим интересующие нас метрики видео
    3. Используем «функцию ценности» для ранжирования этих видео по прогнозируемой интересности
    4. Сохраняем соответствующую информацию видео в DataFrame
    5. Выводим в консоль подробности (в том числе ссылки) верхних пяти видео


    Мне нужен был способ автоматического выполнения скрипта, и я решил использовать AWS Lambda (бессерверную платформу). Lambda позволяет писать код, который «спит», пока не включается (например, раз в неделю или на основании события).

    В идеале процесс заключался бы в отправке при помощи Lambda автоматического письма со списком видео на мой ящик. Благодаря этому я мог бы выбирать видео из прошлого, которые бы хотел посмотреть на предстоящей неделе, и мне больше никогда не придётся заходить на главную страницу YouTube.

    Однако этого не случилось.

    Я впервые использовал Lambda и, как ни старался, у меня не получилось заставить одновременно работать все импортированные библиотеки. Для работы коду требуется клиент электронной почты boto3, OAuth для вызова API, Pandas для хранения результатов и множество других подзависимостей. Обычно установка этих пакетов тривиальна, но на Lambda появились дополнительные сложности. Во-первых, существуют ограничения памяти на загрузку, поэтому мне нужно было запаковать библиотеки в zip, а после загрузки распаковать их. Во-вторых, AWS Lambda использует специализированную сборку Linux, что усложняло импорт правильных перекрёстно совместимых библиотек. В-третьих, мой Mac вёл себя странно с этими виртуальными средами.

    Потратив примерно 10-15 часов на изучение StackOverFlow, многократную загрузку разных кодовых баз и консультации с друзьями, я так и не смог заставить систему работать. Поэтому в конечном итоге, к своему разочарованию, был вынужден сдаться. (Если у вас есть идеи, то пишите!)

    Поэтому я остановился на плане Б: вручную запускаю скрипт на моём локальном компьютере раз в неделю (после автоматического уведомления по электронной почте). Честно говоря, это не так уж страшно.

    В заключение


    В целом это оказался очень интересный проект. Я научился пользоваться YouTube API, познакомился с AWS Lambda и создал инструмент, который буду применять в дальнейшем.

    Использование моего кода при выборе видео для просмотра, похоже, повышает мою продуктивность, если у меня хватает силы воли не нажимать на ссылки в конце видео. Возможно, я пропускаю некоторые интересные видео, но моя цель заключается не во всеобъемлющем отслеживании качественных видео, стоящих просмотра (я вообще не думаю, что это возможно). Вместо этого я хочу повысить планку качества видео, которые я смотрю.

    Этот проект — одна из множества моих идей, связанных с автоматизированной обработкой информации. Я считаю, что у нас есть огромный потенциал в повышении продуктивности и экономии времени благодаря осмысленному минимализму пользования цифровой средой.

    Потенциальные следующие шаги


    В целом, проект ещё довольно сырой и с ним можно сделать намного больше.

    • Метрика ранжирования видео довольно груба и её можно ещё совершенствовать. Логичным следующим шагом может быть учёт соотношения лайков/дизлайков.
    • Также многое зависит от поисковых запросов. Если текста нет в названии или описании, то видео не будет выбрано. Можно исследовать возможность решения этой проблемы.
    • Также можно создать интерфейс, в который пользователи вводят только поисковые запросы и временной интервал. Код при этом станет более удобным, а также позволит пользователям просматривать видео, даже не переходя на youtube.com.
    • Пока код выполняется довольно медленно. Я не особо занимался оптимизацией его скорости, учитывая, что планирую запускать его только раз в неделю. Но в нём есть очевидные неэффективные фрагменты, которые можно улучшить.




Добавить
Загрузка...

Войти на сайт

Регистрация