Материалы воркшопа с зимней школы Искусственный интеллект в психологии 2020.
В современной науке всё большее значение принимают методы, основанные на машинном обучении и анализе данных. Мы попробуем использовать анализ данных для того, чтобы сделать некоторые (исключительно грубые) выводы о человеческой психологии на основа анализа изображений.
В нашем случае мы будем использовать небольшое количество изображений, для ускорения процесса обработки. Поэтому выводы, которые мы сможем сделать, не будут статистически обоснованы. Однако в случае, если в нашем распоряжении окажется большее количество фотографий, мы сможем попробовать получить более достоверные результаты с помощью такой же методики.
Большое количество контента в интернет/соц.сетях - это изображения. Мы можем использовать нейросетевые модели для извлечения из изображений глубинной информации о содержимом, например:
В нашем случае мы сконцентрируемся на извлечении информации о людях. Для этого будем использовать облачный сервис Microsoft Azure Face API.
Для использования Face API нам необходим специальный ключ, а также интернет-адрес для вызова сервиса (Endpoint URL). Есть несколько способов получить ключ:
Важно: При использовании бесплатной категории Face API, будут некоторые ограничения по количеству изображений, которые вы сможете обработать (несколько тысяч), а также по частоте запросов (не более 20 запросов в минуту). Для обеспечения работы без ошибок, возможно, придется вставлять паузы между запросами к сервису.
Полученный ключ и адрес Endpoint URL введите в ячейке ниже:
key = '--INSERT YOUR KEY HERE--'
endpoint = 'https://westus2.api.cognitive.microsoft.com'
# You might need different endpoint, check the cognitive services page!
Для работы с Face API нам нужно установить специальную библиотеку, а также убедиться, что другие важные библиотеки Python установлены:
import sys
!{sys.executable} -m pip install --quiet --user matplotlib pandas ipyplot
!{sys.executable} -m pip install --quiet --user azure-cognitiveservices-vision-face
import os, matplotlib.pyplot as plt, json, pickle
Все вызовы к Face API производятся с помощью модуля cognitive_face
, который мы для краткости назовём cf
:
import azure.cognitiveservices.vision.face as cf
from msrest.authentication import CognitiveServicesCredentials
cli = cf.FaceClient(endpoint,CognitiveServicesCredentials(key))
Основные функции для обработки лица -- face.detect_with_url
и face.detect_with_stream
. Они извлекают из лица разную информацию в зависимости от передаваемых параметров. Например. попробуем проанализировать следующее изображение:
res = cli.face.detect_with_url('https://2016.dotnext-piter.ru/assets/images/people/soshnikov.jpg',
return_face_attributes=['emotion','age','gender'], return_face_id=False)
print(res[0].as_dict())
{'face_rectangle': {'width': 127, 'height': 127, 'left': 83, 'top': 87}, 'face_attributes': {'age': 39.0, 'gender': 'male', 'emotion': {'anger': 0.0, 'contempt': 0.0, 'disgust': 0.0, 'fear': 0.0, 'happiness': 1.0, 'neutral': 0.0, 'sadness': 0.0, 'surprise': 0.0}}}
Проанализируем фотографии с летней школы ИИ, расположенные в интернет вот тут. Можно заметить, что все фотографии имеют адрес http://psy.msu.ru/science/conference/summer/2019/photo/xxx.jpg, где xxx - номер фото, от 000 до 131.
urls = ["http://psy.msu.ru/science/conference/summer/2019/photo/{:03d}.jpg".format(i) for i in range(1,131)]
import pandas as pd
import ipyplot
ipyplot.plot_images(urls[::10],img_width=150)
data = []
for x in urls:
print("Analyzing {} ...".format(x),end='')
res = cli.face.detect_with_url(x, return_face_attributes=['emotion','age','gender'], return_face_id=False)
nfaces = len(res)
print(nfaces, ' faces')
for t in res:
fa = t.as_dict()['face_attributes']
em = fa['emotion']
z = { 'gender' : fa['gender'], 'age' : fa['age'], 'nfaces' : nfaces }
data.append(dict(list(z.items())+list(em.items())))
print("Found {} faces".format(len(data)))
with open('data.json','w') as f:
json.dump(data,f)
Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/001.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/002.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/003.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/004.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/005.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/006.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/007.jpg ...3 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/008.jpg ...3 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/009.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/010.jpg ...3 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/011.jpg ...4 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/012.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/013.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/014.jpg ...2 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/015.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/016.jpg ...3 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/017.jpg ...3 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/018.jpg ...2 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/019.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/020.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/021.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/022.jpg ...4 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/023.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/024.jpg ...2 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/025.jpg ...2 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/026.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/027.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/028.jpg ...8 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/029.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/030.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/031.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/032.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/033.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/034.jpg ...2 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/035.jpg ...4 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/036.jpg ...2 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/037.jpg ...3 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/038.jpg ...3 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/039.jpg ...3 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/040.jpg ...3 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/041.jpg ...3 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/042.jpg ...6 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/043.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/044.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/045.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/046.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/047.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/048.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/049.jpg ...5 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/050.jpg ...2 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/051.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/052.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/053.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/054.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/055.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/056.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/057.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/058.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/059.jpg ...4 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/060.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/061.jpg ...2 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/062.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/063.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/064.jpg ...3 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/065.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/066.jpg ...2 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/067.jpg ...7 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/068.jpg ...4 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/069.jpg ...2 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/070.jpg ...6 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/071.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/072.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/073.jpg ...4 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/074.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/075.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/076.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/077.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/078.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/079.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/080.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/081.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/082.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/083.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/084.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/085.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/086.jpg ...5 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/087.jpg ...5 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/088.jpg ...5 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/089.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/090.jpg ...5 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/091.jpg ...6 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/092.jpg ...3 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/093.jpg ...7 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/094.jpg ...6 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/095.jpg ...6 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/096.jpg ...7 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/097.jpg ...6 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/098.jpg ...5 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/099.jpg ...7 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/100.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/101.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/102.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/103.jpg ...5 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/104.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/105.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/106.jpg ...2 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/107.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/108.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/109.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/110.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/111.jpg ...4 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/112.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/113.jpg ...7 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/114.jpg ...7 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/115.jpg ...12 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/116.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/117.jpg ...0 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/118.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/119.jpg ...1 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/120.jpg ...10 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/121.jpg ...12 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/122.jpg ...2 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/123.jpg ...7 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/124.jpg ...6 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/125.jpg ...2 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/126.jpg ...5 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/127.jpg ...6 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/128.jpg ...8 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/129.jpg ...7 faces Analyzing http://psy.msu.ru/science/conference/summer/2019/photo/130.jpg ...9 faces Found 333 faces
df = pd.DataFrame(data)
df
gender | age | nfaces | anger | contempt | disgust | fear | happiness | neutral | sadness | surprise | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | female | 24.0 | 1 | 0.0 | 0.000 | 0.0 | 0.0 | 0.991 | 0.009 | 0.000 | 0.0 |
1 | female | 23.0 | 1 | 0.0 | 0.000 | 0.0 | 0.0 | 1.000 | 0.000 | 0.000 | 0.0 |
2 | female | 23.0 | 3 | 0.0 | 0.000 | 0.0 | 0.0 | 1.000 | 0.000 | 0.000 | 0.0 |
3 | female | 24.0 | 3 | 0.0 | 0.000 | 0.0 | 0.0 | 1.000 | 0.000 | 0.000 | 0.0 |
4 | female | 25.0 | 3 | 0.0 | 0.000 | 0.0 | 0.0 | 1.000 | 0.000 | 0.000 | 0.0 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
328 | female | 19.0 | 9 | 0.0 | 0.000 | 0.0 | 0.0 | 1.000 | 0.000 | 0.000 | 0.0 |
329 | female | 28.0 | 9 | 0.0 | 0.000 | 0.0 | 0.0 | 0.904 | 0.096 | 0.000 | 0.0 |
330 | female | 22.0 | 9 | 0.0 | 0.001 | 0.0 | 0.0 | 0.350 | 0.647 | 0.001 | 0.0 |
331 | female | 18.0 | 9 | 0.0 | 0.000 | 0.0 | 0.0 | 0.864 | 0.136 | 0.000 | 0.0 |
332 | female | 28.0 | 9 | 0.0 | 0.000 | 0.0 | 0.0 | 1.000 | 0.000 | 0.000 | 0.0 |
333 rows × 11 columns
Мы загрузили все данные в DataFrame
по имени df
, и дальше попробуем его проанализировать. Ниже, когда мы загрузим данные из другого источника, мы сможем перейти снова к этой ячейке и построить графики, просто выполняя ячейки одну за другой.
Можем сохранить данные на диск, что впоследствии можно было для демонстрации их быстро загрузить
df.to_pickle('data_conf.pkl')
df = pd.read_pickle('data_conf.pkl')
Посмотрим на распределение возрастов на конференции:
df.hist('age')
array([[<matplotlib.axes._subplots.AxesSubplot object at 0x0000024FBB72D7C8>]], dtype=object)
А как распределен уровень счастья?
df.hist('happiness')
array([[<matplotlib.axes._subplots.AxesSubplot object at 0x0000024FBB183148>]], dtype=object)
Можем также построить зависимость счастья от возраста:
df.plot.scatter('age','happiness')
<matplotlib.axes._subplots.AxesSubplot at 0x24fbaed2f48>
Посмотрим на распределение счастья в зависимости от пола:
df.groupby('gender').mean()['happiness'].plot.bar()
<matplotlib.axes._subplots.AxesSubplot at 0x24fbb3b11c8>
Вывод: девушки более счастливы!
И в зависимости от количества лиц на фотографии:
df.groupby('nfaces').mean()['happiness'].plot.bar()
<matplotlib.axes._subplots.AxesSubplot at 0x24fbb42f088>
Вывод: фотографироваться в компании немного веселее, но не сильно.
Наконец, распределение среднего счасться по возрастным группам:
df.groupby('age').mean()['happiness'].plot.bar()
<matplotlib.axes._subplots.AxesSubplot at 0x24fbb4cf988>
df['age_group'] = (df['age'] // 10)*10
df.groupby('age_group').mean()['happiness'].plot.bar()
<matplotlib.axes._subplots.AxesSubplot at 0x24fbb5ef548>
Если счастье убывает, то интересно посмотреть, какие эмоции возрастают. Например, аналогичная динамика для грусти:
df.groupby('age_group').mean()['sadness'].plot.bar()
<matplotlib.axes._subplots.AxesSubplot at 0x24fbb655bc8>
Посмотрим на средние эмоции людей:
df.mean()[['happiness','sadness','anger','contempt','disgust','fear']].plot.bar()
<matplotlib.axes._subplots.AxesSubplot at 0x24fbea37b48>
Тоже самое по мужчинам и по женщинам:
df.groupby('gender').mean()[['happiness','sadness','anger','contempt','disgust','fear']].T.plot.bar()
<matplotlib.axes._subplots.AxesSubplot at 0x24fbebab088>
Разместим коллекцию фотографий в директории images
. Самый простой способ сделать это - загрузить фотографии вручную через интерфейс Azure Notebooks. Для примера я загружу заранее заготовленные фото:
!wget http://www.soshnikov.com/temp/psyimages.zip
!unzip psyimages.zip
!rm psyimages.zip
import PIL, glob, numpy as np
data = []
for fn in glob.glob("images/*"):
print("Processing {}".format(fn),end=' ')
with open(fn,'rb') as f:
res = cli.face.detect_with_stream(f,return_face_landmarks=False,return_face_id=False,return_face_attributes=['emotion','age','gender'])
nfaces = len(res)
print(nfaces,' faces')
im = PIL.Image.open(fn)
img = np.array(im)
for t in res:
fa = t.as_dict()['face_attributes']
em = fa['emotion']
fr = t.as_dict()['face_rectangle']
face = img[fr['top']:fr['top']+fr['height'],fr['left']:fr['left']+fr['width'],:]
z = { 'gender' : fa['gender'], 'age' : fa['age'], 'nfaces' : nfaces, 'face' : face, 'img' : img }
data.append(dict(list(z.items())+list(em.items())))
print("Found {} faces".format(len(data)))
Processing images\IMG_0306.jpg 1 faces Processing images\IMG_0521.jpg 3 faces Processing images\IMG_0600.jpg 1 faces Processing images\IMG_0781.jpg 3 faces Processing images\IMG_0809.jpg 4 faces Processing images\IMG_0872.jpg 4 faces Processing images\IMG_0908.jpg 13 faces Processing images\IMG_0923.jpg 7 faces Processing images\IMG_0985.jpg 1 faces Processing images\IMG_1018.jpg 5 faces Processing images\IMG_1199.jpg 2 faces Processing images\IMG_1241.jpg 2 faces Processing images\IMG_1256.jpg 6 faces Found 52 faces
df_full = pd.DataFrame(data)
df = df_full.drop(['img','face'],1)
df.to_pickle('data_faces.pkl')
Мы снова загрузили данные в список data
, поэтому мы можем перейти вверх к ячейке Смотрим на результаты графически и выполнить ячейки, изучая результаты и делая выводы.
Поскольку в этом случае у нас также есть сами изображения, попробуем найти самые ярко-выраженные эмоции на фотографиях:
emotions = ['happiness','sadness','surprise','fear','contempt']
emos = { t:(0,None) for t in emotions}
for x in data:
for k,v in emos.items():
if x[k]>=v[0]:
emos[k]=(x[k],x['face'])
fix,ax = plt.subplots(1,len(emos.keys()))
for i,e in enumerate(emos.keys()):
if emos[e][1] is not None:
ax[i].imshow(emos[e][1])
ax[i].axis('off')
ax[i].set_title(e)
plt.show()
Теперь найдём наиболее "противоречивую" эмоцию, в которой две составляющих проявлены наиболее сильно. Для этого ищем лицо, в котором максимально значение второй по величине эмоции, не считая нейтральной:
mx = 0
img = None
emo = None
for x in data:
em = { k: x[k] for k in emotions }
snd = sorted(em.values())[-2]
if snd>mx:
mx = snd
img = x['face']
emo = em
plt.imshow(img)
plt.show()
emo
{'happiness': 0.087, 'sadness': 0.0, 'surprise': 0.057, 'fear': 0.0, 'contempt': 0.0}
Полученные результаты могут использоваться для дальнейших исследований с помощью алгоритмов машинного обучения. Например, мы увидели выше интресное сочетание эмоций. Можем посмотреть, выделяются ли среди всех лиц некоторые "типичные" конфигурации. Для этого необходимо применить алгоритм кластеризации, который реализован в библиотеке Scikit Learn:
import sklearn.cluster
inp = np.array([ [ x[e] for e in emotions ] for x in data])
centroid, labels, inertia = sklearn.cluster.k_means(inp,3)
Мы попросили разбить все лица на 3 кластера, на основе расстояний между векторами эмоций. Теперь посмотрим на то, какие конфигурации эмоций у нас получились в центре таких кластеров (они возвращены в переменной centroids
), и на наиболее "характерные" (близкие по расстоянию) лица для каждого из кластеров
def closest_face(e):
mi = 999
el = None
for i,x in enumerate(data):
if np.linalg.norm(inp[i]-e)<mi:
mi=np.linalg.norm(inp[i]-e)
el=x
return el['face']
fig,ax = plt.subplots(2,len(centroid),figsize=(10,4))
for i,x in enumerate(centroid):
ax[0,i].bar([t[0:2] for t in emotions],x)
ax[1,i].imshow(closest_face(x))
plt.show()
Посмотрим на все лица в интересном кластере 0:
res = [x['face'] for x,i in zip(data,labels) if i==0]
fig,ax = plt.subplots(1,len(res),figsize=(20,4))
for i,x in enumerate(res):
ax[i].imshow(x)
ax[i].axis('off')
plt.show()
Не забывайте, что вы можете всегда загрузить новые фотографии в директорию images
, и повторить данный эксперимент для новых данных. Более того, вы можете использовать этот ноутбук как заготовку для дальнейших исследований и экспериментов! Если у вас будет получаться что-то интересное --- делитесь результатами!
Контакты:
!rm images/*