search icon search icon ВЕРСИЯ ДЛЯ СЛАБОВИДЯЩИХ

Инженерный тур. 3 этап

Общая информация

Участникам предстоит разработать алгоритм оценки популярности публикаций в социальной сети.

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

Легенда задачи

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

Требования к команде и компетенциям участников

Число участников в команде: 3 человека.

Компетенции, которыми должны обладать члены команды:

  • Аналитик придумывает идеи решения.
  • Программист реализует идеи в виде программы.
  • Тестировщик тестирует программы и настраивает гиперпараметры.
Оборудование и программное обеспечение
Наименование Описание
All Cups https://cups.online/ Платформа для проведения соревнований по машинному обучению.
Yandex DataSphere https://datasphere.yandex.cloud/ Сервис для ML-разработки. Используется для анализа данных и обучения моделей.
Docker ПО для виртуализации. Используется для отправки решения в тестирующую систему.
Описание задачи

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

Набор данных

Каждая строка в наборе данных кодирует какую-то одну публикацию. Набор данных состоит из следующих столбцов:

  • view — число просмотров публикации;
  • like — число отметок «мне нравится»;
  • comment — число комментариев;
  • hide — число скрытий публикации;
  • expand — число раскрытий публикации;
  • open_photo — число открытий фотографии;
  • open — число открытий публикации;
  • share_to_message — число пересылок публикации;
  • text — текст публикации;
  • photo — прикрепленная к публикации фотография в кодировке base64.

Пример содержит способ преобразования изображения.

Тренировочный набор данных, который находится в файле train.csv, включает все эти характеристики.

При запуске решения в контейнере тестовый набор данных будет доступен в файловой системе по пути /tmp/data/test.csv. Тестовый набор данных состоит из колонок: view, text и photo. Файл sample_test.csv содержит пример тестового набора данных с идентичной структурой.

В результате работы в контейнере решение должно создать CSV-файл result в папке /var/log/. Он должен содержать колонки: like, comment, hide, expand, open_photo, open и share_to_message с оценками соответствующих характеристик.

Система оценивания

Максимальный балл — 100.

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

Формат входных данных

При запуске решения в контейнере тестовый набор данных будет доступен в файловой системе по пути /tmp/data/test.csv. Обратите внимание, что в примере он сначала копируется в рабочую папку, перед запуском решения.

Тестовый набор данных состоит из колонок: view, text и photo. Файл sample_test.csv содержит пример тестового набора данных с идентичной структурой.

Формат выходных данных

В результате работы в контейнере решение должно создать CSV-файл result в папке /var/log/. Он должен содержать колонки: like, comment, hide, expand, open_photo, open и share_to_message с оценками соответствующих характеристик.

Решение задачи

Для решения необходимо выделить признаки из текста и изображений. Для выделения признаков из текста можно воспользоваться CountVectorizer, а для изображений — посчитать различные статистики по пикселям, либо воспользоваться какой-нибудь предобученной сверхточной сетью.

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

Ниже приведен пример авторского решения.

Файл для fit.py обучения модели.

Python
import pandas as pd
import numpy as np
import base64
from io import BytesIO
from PIL import Image
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.dummy import DummyRegressor
from sklearn.ensemble import GradientBoostingRegressor
import pickle
text_vectorizer = CountVectorizer(max_features=777)
def img_vectorizer(photo_base64):        
    img = np.array(Image.open(BytesIO(base64.b64decode(photo_base64))))    
    
    s = img.shape
    if (len(s) == 2):
        img = np.repeat(img, 3)
        
    h, w = s[0], s[1]
    img.resize((h * w, 3))    
    
    stats = []
    stats.append(np.array([h,w]))
    stats.append(img.min(axis=0))
    stats.append(img.max(axis=0))
    stats.append(img.mean(axis=0))
    stats.append(img.std(axis=0))
    stats.append(np.median(img, axis=0))
    cm = np.corrcoef(img.T)
    stats.append(cm[np.triu_indices(len(cm), k = 1)])
    return np.concatenate(stats) 
train = pd.read_csv("train.csv")
X_train_img = np.vstack(train['photo'].map(img_vectorizer))
X_train_text = text_vectorizer.fit_transform(train["text"].fillna("")).toarray()
X_train = np.hstack([X_train_img, X_train_text])
model = {
    'like': GradientBoostingRegressor(n_estimators=77),
    'comment': DummyRegressor(),
    'hide': DummyRegressor(),
    'expand': GradientBoostingRegressor(n_estimators=77),
    'open_photo': GradientBoostingRegressor(n_estimators=77),
    'open': GradientBoostingRegressor(n_estimators=77),
    'share_to_message': GradientBoostingRegressor(n_estimators=77)
}
for target, reg in model.items():
    y_train = train[target] / train['view']
    reg.fit(X_train, y_train)    
with open('model.pickle', 'wb') as f
    pickle.dump(text_vectorizer, f)
    pickle.dump(model, f)

Файл predict.py для вывода модели.

Python
with open('text_vectorizer.pickle', 'rb') as f:
    text_vectorizer = pickle.load(f)
    model = pickle.load(f)
test = pd.read_csv("test.csv")
X_test_img = np.vstack(test['photo'].map(img_vectorizer))
X_test_text = text_vectorizer.fit_transform(test["text"].fillna("")).toarray()
X_test = np.hstack([X_test_img, X_test_text])
prediction = pd.DataFrame()
for target, reg in model.items():
    prediction[target] = reg.predict(X_test) * test['view']
prediction.to_csv("submission.csv", index=False)

Файл requirements.txt с используемыми версиями библиотек.

text
pandas==2.2.3
scikit-learn==1.6.1
pillow==10.4.0
Dockerfile: 
FROM python:3
WORKDIR /bdml
COPY run.sh .
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY model.pickle .
COPY predict.py .
CMD ["bash", "run.sh"]

Материалы доступны по ссылке: https://disk.yandex.ru/d/ng3EGZLMueC79Q.

Материалы для подготовки
  1. Учебник по машинному обучению: https://education.yandex.ru/handbook/ml.
  2. Документация к Python библиотеке для машинного обучения: https://scikit-learn.ru/.
  3. Документация к Python библиотеке для анализа данных: http://pandas.geekwriter.ru/.
text slider background image text slider background image
text slider background image text slider background image text slider background image text slider background image