Привет, дорогие по-читатели Хабра!

Автор статьи: Ольга Шерман

Выпускница курса Machine Learning. Professional

Исследование выполнено под руководством Марии Тихоновой (тг-канал @mashkka_ds ) в рамках выпускного проекта на курсе Machine Learning в OTUS.

Предыстория

Моим датасетом стало собрание картин Музея современного искусства (MoMA), Нью-Йорк. В нем представлено описание работ 20 956 авторов. Набор данных произведений искусства содержит 130 262 записи.

Мне очень хотелось поработать именно с этим датасетом. Этому способствовали три обстоятельства. Первое — на меня произвело неизгладимое впечатление то, что исследователи Музея MoMA изучают легитимность владения произведениями, созданными до 1946 года и/или приобретенными после 1932 года, которые могли находиться в Европе при нацизме, чтобы выявить любые незаконные приобретения в коллекции Музея.

Второе обстоятельство — данные находятся в открытом доступе:

Museum of Modern Art Collection

https://github.com/MuseumofModernArt

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

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

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

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

В связи с развитием компьютерного зрения и робототехники, сейчас все большую популярность получают искусственные виды данных. Они не требуют больших затрат на сбор и обработку, не ограничены по объему и требованиями конфиденциальности. Модели, обученные и тренированные на них более устойчивы к различным изменениям.

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

Идею работы: «Похоже ли произведение искусства из коллекции музея на работы автора?» я придумала конкретно под этот датасет. Конечно, хотелось бы установить: Оригинал или подделка? Но для ответа на такой категоричный вопрос данных оказалось недостаточно, о чем я поведаю далее.

У проекта было несколько целей:            

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

2. Провести исследование различных моделей машинного обучения для выявления схожести работ, таких как Logistic Regression, Decision Tree, Random Forest, LightGBM, CatBoost. Оценить точность и эффективность моделей, выбрать лучшую.

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

1. Работа с данными

1.2. Описание признаков

Датасет представлял из себя 130 262 образцов произведений искусств из коллекции музея, включающих 21 параметр.

Категориальные признаки:

  • Title (название)

  • Name (имя художника)

  • Medium (материалы для живописи)

  • Credit (способ приобретения)

  • Catalogue(каталог)

  • Department (департамент)

  • Classification (классификация)

Classification (классификация):

  • Print (рисунок) 30807

  • Photograph (фото) 29909

  • Illustrated Book (иллюстрированная книга) 26160

  • Drawing (гравюра) 11735

  • Design (дизайн) 11223

  • Mies van der Rohe Archive(Людвиг Мис ван дер Роэ) 3331

  • Painting (картины) 2270 …..

Medium (живописные материалы):

  • Gelatin silver print (Серебряно-желатиновый отпечаток)

  • Lithograph (Литография)

  • Albumen silver print (Альбуминовый серебряный отпечаток)

  • Lithograph, printed in color (Литография, цветная печать) …

Числовые признаки:

  • Date (дата создания)

  • Dimensions (размеры)

  • Acquisition Date (дата приобретения)

  • Height (cm) (высота полотна)

  • Width (cm) (ширина полотна)

Порядковые признаки:

  • Artwork ID (ID произведения искусства)

  • Artist ID (ID художника)

  • Object Number (номер объекта)

2. Предобработка данных

По правилам хорошего тона в ML, вначале надо сделать предобработку данных, избавиться от признаков, содержащих меньше 91% информации и от пропусков данных (NaN). Однако я решила нарушить эти неписанные правила и предварительно выбрать объекты для своей модели, а потом принимать решение: удалить ячейки с пропущенными данными или восстановить недостающие значения. Задачу несколько усложняло, что восстанавливать надо было категориальные признаки.

2.1. Отбор претендентов для модели

Теперь мне надо было выбрать наиболее широко представленный в коллекции вид искусства и Автора с максимальным количеством работ в этом искусстве.

2.1.1.Выбор вида искусства

Поскольку наиболее информативным признаком были материалы для живописи (столбец 'Medium'), то мне надо было удостовериться, что выбранный вид искусства имеет минимальную долю пропущенных значений в 'Medium' (в %) для каждого значения 'Classification':

  • Print 30807 - 2.8

  • Photograph 29909 - 0.6

  • Illustrated Book 26160 - 34.0

  • Drawing 11735 - 0.8

  • Design 11223 - 4.3

  • Architecture 2947 - 0.3

  • Painting 2270 - 0.04

Материалы для живописи 'Medium' наиболее полно были расписаны для Photograph и Painting. Поэтому для своей модели я выбрала именно эти виды искусства.

2.1.2. Выбор Artist_ID по частоте работ для выбранного вида искусства Painting

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

Провела группировку 'Artist ID' со значением 'Painting' из столбца 'Classification' в порядке убывания и получила, что наиболее представленным художником в музее MoMa является Пабло Пикассо. Он оказался первым в списке сортировки по количеству картин. Общее число его картин составило 55. (Несмотря на то, что коллекция Пабло Пикассо в музее MoMA считается самой полной -1295 работ). Стало понятно, что при таком ничтожном объеме данных, Painting, как ни жаль, из дальнейших исследований исключается.

2.1.3. Выбор Artist_ID по частоте работ для выбранного вида искусства Photograph

Группировка 'Artist ID'со значением 'Photograph' из столбца 'Classification' выделила наиболее частотных авторов:

  • Artist ID     Count of Photograph

  • 2002                 1313

  • 3373                  479

  • 1533                  407

  • 6399                  342

Я вернулась к предобработке данных и выполнила их очистку. Доля пропущенных значений “Medium” для Photograph составила 0,6%, поэтому я не стала заниматься восстановлением категориальных данных.

2.2. Применение векторизации текстов для преобразования столбца “Medium” в числовые признаки: очистка параметра Medium от стоп-слов и применение tf-idf

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

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

«Алгоритм стемминга — это вычислительная процедура, которая приводит все слова с одним и тем же корнем… к общей форме, обычно путем удаления из каждого слова словообразовательных и флективных суффиксов». Есть несколько видов стеммеров, среди них: стеммер Портера, стеммер Ланкастера. Стеммер Портера один из популярных. Он достаточно консервативен, т.е. не так активно обрезает слова в поисках основы.

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

Я использовала стеммер Портера. В моем случае он хорошо себя показал. Целевая переменная: работа похожа на работы Автора (1) или не похожа (0)

from nltk.stem import PorterStemmer 
from nltk.corpus import stopwords
stop = stopwords.words('english')
data = data_artworks.query("Classification == 'Photograph'")[["Artist ID", "Artwork ID", "Medium"]].dropna().drop_duplicates()

Очистка текста от стоп-слов и неалфавитных символов

def normalize_word(word):
    ps= PorterStemmer()
    return ps.stem(re.sub('[^A-Za-z]+', '', word))
data["normalize_medium"] = (data['Medium']
               .apply(lambda x: ' '.join([normalize_word(word) for word in x.split() if word not in (stop)]))
                           )

Векторизаця - Метод: Tfidfvectorizer

# работаем с импортированным классом TfidfVectorizer
vectorizer = TfidfVectorizer()
# рассчитываем TF-IDF слов
tfidf_data = vectorizer.fit_transform(data["normalize_medium"]).toarray()
tf_idf_df = pd.DataFrame(tfidf_data, columns=vectorizer.get_feature_names_out(), index=data.index)
print(tf_idf_df.shape)
tf_idf_df.head(3)

Модель

# Относится ли данное произведение (Artwork ID) к выбранному Artist id (да - 1, нет - 0).
model_Artist = data[["Artist ID", "Artwork ID"]].merge(tf_idf_df, right_index=True, left_index=True)
model_Artist["target"] = np.where(model_Artist["Artist ID"] == '2002', 1, 0)
print(model_Artist.shape)
model_Artist.head(3)

 (22793, 492)

3. Обучение модели

Для обучения модели, которая будет определять схожесть между произведениями искусства и работами автора использовался метод бинарной классификации на 5 моделях: Logistic Regression, Decision Tree, Random Forest, LightGBM, CatBoost

Я выделила работы конкретного "Автора" (с большим количеством работ в одной области искусства- фотографии). Создала и обучила модель логистической регрессии на тренировочной выборке, в качестве которой использовала материалы для живописи, которые использовал автор в своих работах. Далее на тестовом наборе, я проверила распознает ли обученная модель работы автора по его живописным материалам. Сравнила результаты прогнозируемых и фактических значений. Эту процедуру я проделала для 4-х авторов.

Модель логистической регрессии для бинарной классификации (в качестве baseline) показала, что классы сильно не сбалансированы. Чтобы добиться одинакового распределения в трейне и в тесте, в разбиение train_test_split был введен параметр stratify = y.

Модель Decision Tree для бинарной классификации (в качестве иллюстрации)

Визуализация Decision Tree
Визуализация Decision Tree

Графики ROC-AUC для Автора 3373

На графике отображаются значения метрики AUC-ROC на тренировочных и тестовых данных в зависимости от количества деревьев. График позволяет оценить, как количество деревьев влияет на качество модели и выбрать оптимальное значение количества деревьев для конкретной задачи.

Из графика модели CatBoost мы наглядно видим, что нам достаточно 4-х деревьев для тренировки и тестирования модели, тогда как для модели LightGBM необходимо не меньше 12-ти деревьев.

Модель 5: Catboost

from catboost import CatBoostClassifier

X = model_Artist.drop(columns=drop_columns)
y = model_Artist["target"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42,  stratify=y)

model = CatBoostClassifier(iterations=50, logging_level='Silent')
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

# ROC-AUC до настройки 
myscore = make_scorer(roc_auc_score, needs_proba=True)
# model = OneVsRestClassifier(CatBoostClassifier())
my_value = cross_validate(model, X, y, cv=5, scoring = myscore)
cb_before=np.mean(my_value['test_score'].tolist())

# Построение feature_importances
X_columns = model_Artist.drop(columns=drop_columns)
importance_df = pd.DataFrame(model.feature_importances_, index = list(X_columns), 
             columns = ['feature importance']).sort_values('feature importance', ascending = False)[:8]

plt.title('Feature importances for CatBoost')
sns.barplot(x='feature importance', y=importance_df.index, data=importance_df)
plt.show()
# Оценка сетки гиперпараметров классификатора
param_grid = {'depth'         : [3,4,5,6,7,8,],
              'learning_rate' : [0.01, 0.04, 0.1, 0.2],
              'iterations'    : [10,20,30]
                 }
from sklearn.model_selection import GridSearchCV
model = CatBoostClassifier()
# to be standart sklearn's scorer        
myscore = make_scorer(roc_auc_score, needs_proba=True)

# Define GridSearch parameters
clf = GridSearchCV(model, param_grid, scoring=myscore, cv=5, n_jobs=-1)
                        
# Run Grid Search optimization
clf.fit(X_train, y_train)
pred = clf.predict_poba(X_test)
clf.best_params_

# depth=4, iterations=30, learning_rate = 0.2

# Обновим модель:
model_grid = CatBoostClassifier(depth=4, iterations=30, learning_rate = 0.2)
model_grid.fit(X_train, y_train)

# ROC-AUC после оптимизации гиперпараметров CatBoost
myscore = make_scorer(roc_auc_score, needs_proba=True)
model_grid = OneVsRestClassifier(CatBoostClassifier())
my_value = cross_validate(model_grid, X, y, cv=5, scoring = myscore)
cb_after=np.mean(my_value['test_score'].tolist())

4. Оценка модели

4.1. Выбор метрики

В моем случае, при работе с датасетом на основе реальных данных, одной из проблем был выбор метрики для оценки производительности модели. Изначально я предполагала, что наибольшее влияние оказывает величина несбалансированности класса в выборке, у меня – 98% для класса 1 и 2% для класса 0.

 Подсчет процента несбалансированности выборки по классам в y_train (для автора 3373):

  • процент несбалансированности класса 0 в y_train: (17851 / (17851 + 383)) * 100% = 97.90%

  • процент несбалансированности класса 1 в y_train: (383 /(17851 + 383)) * 100% = 2.10%

Для y_test получились аналогичные значения. И это означает, что функция stratify хорошо справляется.

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

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

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

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

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

Метрика ROC-AUC (Receiver Operating Characteristic Curve) или AUC-ROC (Area Under Curve) - измеряет способность модели различать между классами. Она представляет собой площадь под кривой ROC. В случае несбалансированных классов ROC-AUC может быть полезной при оценке качества модели, поскольку она учитывает и полноту, и точность модели в зависимости от порогового значения, которое используется для принятия решения. Автор пишет: «При конвертации вещественного ответа алгоритма в бинарную метку, мы должны выбрать какой-либо порог, при котором 0 становится 1. Естественным и близким кажется порог, равный 0.5, но он не всегда оказывается оптимальным, например, при отсутствии баланса классов. Одним из способов оценить модель в целом, не привязываясь к конкретному порогу, является AUC-ROC (или ROC AUC)

Исходя из вышесказанного, я планировала рассчитывать, как метрику Precision, так и ROC-AUC. Но произведя расчет метрики Precision на всех 5-ти моделях я получила, что после Grid Search Precision = 1.0000, что делало ее бесполезной для оценки моделей. В связи с этим, я использовала только метрику ROC-AUC.

4.2. Графики ROC-AUC до и после оптимизации гиперпараметров для Автора 3373

Выводы:

1. Все модели обеспечивают примерно одинаковую точность

2. Применение Greed Search и настройка гиперпараметров не повлияли на точность.

ROC-AUC
ROC-AUC

4. Результаты исследования

1) Модель машинного обучения показала наибольшую эффективность для автора № 1533 [Jan Dibbets], у которого было 407 работ, с ROC-AUC равным 0,88. Это может быть связано как с тем, что у данного автора были более ярко выражены характеристики произведений искусства. Так и с тем, что у этого автора был относительно небольшой размер выборки (407 работ), что позволило модели лучше изучить его стиль и характеристики произведений. Более крупные выборки могут содержать больше вариаций и усложнять задачу модели.

 2) ROC-AUC для автора № 3373 [Dorothea Lange] составила 0,79, что также указывает на хорошую эффективность модели в определении подобия ее работ.

 3)  Для автора № 2002 [Lee Friedlander]  ROC-AUC составила 0,72, что говорит о средней эффективности модели в определении схожести его работ.

Выводы и интерпретация результатов

  1. В целом, примененная модель машинного обучения показала, что обладает предсказательной силой.

  2. Путем сравнения полученных результатов, была установлена зависимость между ROC_AUC и качеством выборки в зависимости от объема выборки. Видно, что выборки размером 342 работы модели недостаточно для обучения.

  3. Несмотря на несбалансированные классы применение датасета с реальными данными в целом, показало себя хорошо.

5. Рекомендации для дальнейшего улучшения системы выявления схожести произведений искусства

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

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

  3. Было бы интересно рассчитать модель с искусственно модифицированным датасетом с выравненным соотношением классов и провести сравнительный анализ оценки производительностей моделей на реальных данных и искусственных.

Заключение

В этой работе была исследована задача: может ли модель ML предсказать Автора на основе набора данных живописных материалов. Модель показала хорошую предсказательную силу. Была продемонстрирована работа с реальными данными и теми проблемами, которые возникают при их использовании. Выяснена разница при возникновении дисбаланса классов, вследствие перекоса из-за значительного количества объектов одного класса и вследствие перекоса в целевой переменной. А также, какие метрики для какого случая лучше применять. Установлено, что для конкретного случая дисбаланса из-за перекоса в целевой переменной, наиболее продуктивной метрикой для оценки модели будет ROC-AUC. Она показала себя лучше, чем Precision.

Комментарии (2)


  1. CrazyElf
    24.10.2023 10:24

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


    1. Marfa-Marfa Автор
      24.10.2023 10:24

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