Data Science

Использование машинного обучения без учителя, чтобы выяснить, что «от бренда» для корпоративных постов в Instagram

Использование веб-скрапинга, уменьшения размерности и неконтролируемого машинного обучения в более чем 15000 постов в Instagram от 500 крупнейших компаний США, чтобы попытаться создать стиль обычного корпоративного поста.

Раньше, когда я помогал планировать и управлять мероприятиями в колледже, фраза «Руководство по стилю» использовалась каждый день. Идея заключается в том, что все, что вы публикуете, должно иметь одинаковые шрифты, размеры, цветовую палитру и т. Д. Я подумал, что было бы интересным упражнением посмотреть, в каких отраслях больше всего разнообразных постов с изображениями (или наименее стандартного руководства по стилю), а также текстовых подписей. вне Instagram.

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

Я сделал это в три этапа:

  1. Получите изображения и текстовые данные сообщений от каждой компании
  2. PCA и t-SNE для изображений и текстовых данных
  3. Обнаружение аномалий с помощью модели гауссовой смеси

Для всех интерактивных графиков вам нужно будет загрузить html-файл из этой папки и открыть его в браузере.

Получите изображения и текстовые данные сообщений от каждой компании

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

  1. Получите инстаграмм компании S&P 500 (2 часа)
  2. Получите список ссылок для публикаций на странице каждой компании (4 часа)
  3. Получите список ссылок на источники фото из каждого поста на странице (6 часов)

Для выполнения этих шагов я использовал и selenium, и beautifulsoup4. Для первого шага создать сценарий было несложно. Я просто открыл веб-драйвер с селеном и продолжил поиск name-of-company + ‘ instagram’, а затем взял третий текстовый элемент, содержащий (@. Сначала импортируйте эти пакеты:

import pandas as pd
import numpy as np
import datetime
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait

Тогда код выглядит так:

Вы можете получить xpath, щелкнув правой кнопкой мыши html после проверки элемента на странице, а затем просто перейдя к copy → xpath. Иногда лучше использовать CSS selector, так как xpath будет меняться для разных сообщений.

Чтобы очистить сообщения, я бы прокрутил следующее:

  1. driver.get(“instagram.com/” + username)
  2. Прокрутите три раза, прежде чем потянуть driver.page_source
  3. Вытяните ссылку на сообщение в каждой карточке во фрейм данных с помощью bs4

Instagram, кажется, выгружает ссылки на сообщения из html, если вы прокрутите слишком далеко вниз, вы можете вытащить html и как-то добавить его, но я чувствовал, что 16 711 сообщений будет достаточно для этого упражнения. Последний шаг - перебрать каждую ссылку публикации и вытащить src изображения и текст публикации. На всякий случай я сохранил изображения на рабочий стол, но вам это не нужно. Было небольшое тестирование для разных случаев (разные типы сообщений, отсутствие сообщений, старые форматы и т. Д.), Но это не заняло много времени. Я оставил это на ночь, а затем сохранил в файле Excel.

Я читаю фотографии в плоские массивы с помощью этой функции:

Как только я сохранил все фотографии, я распараллелил чтение значений массива с помощью этого кода (где sorted_files - это просто путь ко всем моим файлам изображений, названным по индексу):

Хотя этап конкатенации занял больше времени, сэкономленного параллельным применением, поэтому я решил просто использовать вместо этого swifter (он выбирает векторизацию поверх распараллеливания Dask в зависимости от задачи). Это займет около 4 минут.

import swifter
sorted_files["Photo"] = sorted_files[0].swifter.apply(lambda x: PC_to_image_flat(x))

Если у вас есть место на диске, сохраните их в массиве байтов с помощью этой функции:

PCA и t-SNE для изображений и текстовых данных

Есть отличные примеры уменьшения размерности набора данных MNIST, например, этот здесь. Для изображений мы должны свернуть фотографию 1080x1080 в массив. Поскольку это RGB, это становится image.reshape(-1,3), а не просто image.reshape(-1). Не все посты были изображениями, 4000 - видео. Я изменил размер каждого изображения до 225x225, потому что в следующем коде я продолжал выходить за пределы памяти (32 ГБ ОЗУ).

График PCA в оттенках серого выглядит так:

Плоскость идет от черных квадратов от BLM затемнения слева (-10k, -20k) до белых квадратов с мелким текстом справа (0,30k). Середина - это спектр, который идет от таких предметов, как автомобили и инструменты → здания → фотографии групп и толп → фотографии одного человека → более абстрактное искусство и сообщения → сообщения с большим количеством белого пространства. Самый верх и низ - это просто разные среды (горы наверху и многолюдные фотографии внизу). Это также говорит мне о том, что большинство постов на самом деле более темного цвета, учитывая более высокую концентрацию на левой стороне.

С цветом мне пришлось уменьшить размер до 100x100x3, но PCA дал мне:

Я быстро собрал приложение Dash, чтобы исследовать изображения, когда мы наводим курсор на точки данных, используя px.imshow. Из-за изменения размера некоторые данные о цвете были потеряны, что могло повлиять на наши результаты. Ниже вы можете увидеть, что я использовал рисунок t-SNE при локальном размещении приложения, верхний правый угол - черные квадраты, а нижний левый - белые квадраты.

Это согласуется с тенденциями PCA (просто перевернутыми справа налево), но вы можете видеть, что на этой диаграмме есть много небольших кластеров, в которых есть похожие стили сообщений. Кажется, что более крупные кластеры связаны с макетом, цветом и окружающей средой поста. Кластер строк от (10,10) до (15,10) - это все проводки типа BLM, где много проводок в центре вокруг (0,0) - это общие здания и фотографии окружающей среды. Многие фотографии при изменении формы имеют ярко-синий цвет, на самом деле я не совсем уверен, почему это так - вероятно, это связано с тем, как интерполяция обрабатывается cv2.resize().

После векторизации слов с nltk и применения тех же преобразований мы получаем:

и t-SNE:

Похоже, что хотя в текстовых подписях есть шаблоны, они не сильно различаются по отраслям или содержанию. Центр PCA много говорит о любви, путешествиях и мире - что имеет смысл. Кластеры по краям были сообщениями, которые содержали много «ссылок в биографии» или подобных строк в конце сообщения, что было не так популярно, как я ожидал.

Обнаружение аномалий с помощью модели гауссовой смеси

Если вы не знакомы с K-means, обязательно сначала прочтите об этом. По сути, мы на один шаг выше K-средних, вычисляя вероятность того, что точка принадлежит тому или иному кластеру.

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

А теперь самое интересное. Давайте посмотрим, сможем ли мы создать GMM, который предсказывает, когда опубликованное изображение будет отличаться от обычного стиля в отрасли. Вы можете найти полный обзор кода (и неконтролируемого обучения в целом) здесь. После нескольких прогонов модели, чтобы выяснить, какой K лучше всего использовать, я остановился на 5.

Давайте проверим, составляет ли сумма вероятностей по пространству 1:

Достаточно близко! Вот график GMM в 2D:

И, наконец, выбросы показаны ниже с использованием порога плотности 4%.

Это не выглядит очень полезным для нашей первоначальной теории, особенно с учетом того, что это BIC 76280. Также из нашего более раннего анализа этот набор данных, вероятно, содержит примеры большинства типов сообщений Instagram. Придется очень постараться, чтобы создать аномалию. Модели для конкретных компаний тоже не будут работать, поскольку большинство из них разбросаны по всему пространству, например 3M:

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

Заключение

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