![](https://habrastorage.org/getpro/habr/upload_files/999/e88/524/999e88524205ee0c09a68e795e081803.jpg)
Привет, дорогие по-читатели Хабра!
Исследование выполнено под руководством Марии Тихоновой (тг-канал @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.Выбор вида искусства
![](https://habrastorage.org/getpro/habr/upload_files/4bf/b5b/3d4/4bfb5b3d492f96485d64d737517a6ae3.jpg)
Поскольку наиболее информативным признаком были материалы для живописи (столбец '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](https://habrastorage.org/getpro/habr/upload_files/a66/0a4/05e/a660a405e57f113e69667513bc8118a9.jpg)
Графики ROC-AUC для Автора 3373
![](https://habrastorage.org/getpro/habr/upload_files/cc5/8f2/03e/cc58f203e9c303b561d97a7113ebabaa.jpg)
На графике отображаются значения метрики 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()
![](https://habrastorage.org/getpro/habr/upload_files/f71/a92/011/f71a9201194b86e7d6b988e522a2d094.jpg)
# Оценка сетки гиперпараметров классификатора
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
![](https://habrastorage.org/getpro/habr/upload_files/3eb/c8e/546/3ebc8e54601729b4a2399165d43dc81f.jpg)
![](https://habrastorage.org/getpro/habr/upload_files/0d2/df4/d76/0d2df4d76972ef75f4066eac9e1fa7e0.jpg)
Выводы:
1. Все модели обеспечивают примерно одинаковую точность
2. Применение Greed Search и настройка гиперпараметров не повлияли на точность.
![ROC-AUC ROC-AUC](https://habrastorage.org/getpro/habr/upload_files/90d/fe7/644/90dfe7644acc48338a876ddf00affe65.jpg)
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, что говорит о средней эффективности модели в определении схожести его работ.
Выводы и интерпретация результатов
В целом, примененная модель машинного обучения показала, что обладает предсказательной силой.
Путем сравнения полученных результатов, была установлена зависимость между ROC_AUC и качеством выборки в зависимости от объема выборки. Видно, что выборки размером 342 работы модели недостаточно для обучения.
Несмотря на несбалансированные классы применение датасета с реальными данными в целом, показало себя хорошо.
5. Рекомендации для дальнейшего улучшения системы выявления схожести произведений искусства
Увеличить размер обучающей выборки для каждого автора, особенно для авторов с небольшим количеством работ. Больший объем данных может помочь модели лучше понять уникальные особенности стиля каждого автора и улучшить точность предсказаний.
Проанализировать дополнительные характеристики произведений искусства, которые могут быть связаны с авторством, такие как палитра, композиция и т. д. Это может помочь модели выявить более тонкие нюансы искусства и улучшить идентификацию авторства. Но эта задача уже для computer vision.
Было бы интересно рассчитать модель с искусственно модифицированным датасетом с выравненным соотношением классов и провести сравнительный анализ оценки производительностей моделей на реальных данных и искусственных.
Заключение
В этой работе была исследована задача: может ли модель ML предсказать Автора на основе набора данных живописных материалов. Модель показала хорошую предсказательную силу. Была продемонстрирована работа с реальными данными и теми проблемами, которые возникают при их использовании. Выяснена разница при возникновении дисбаланса классов, вследствие перекоса из-за значительного количества объектов одного класса и вследствие перекоса в целевой переменной. А также, какие метрики для какого случая лучше применять. Установлено, что для конкретного случая дисбаланса из-за перекоса в целевой переменной, наиболее продуктивной метрикой для оценки модели будет ROC-AUC. Она показала себя лучше, чем Precision.