将以字典作为值的字典列表转换为 ML 特征

Convert list of dicts with dicts as values to ML features

我想将 Google 视觉 API 面部识别的输出转换为 ML 分类器的特征集。对于每个训练实例,我得到一个预测面孔列表,它表示为字典列表,其中值本身就是字典,这些 'value dictionaries' 的值本质上是分类的,如下所示:

$ faces[191:197]


[{'face_1': {'joy': 'VERY_UNLIKELY',
   'surprise': 'UNLIKELY',
   'anger': 'VERY_UNLIKELY',
   'sorrow': 'VERY_UNLIKELY',
   'headwear': 'VERY_UNLIKELY'}},
 {},
 {},
 {'face_1': {'joy': 'VERY_LIKELY',
   'surprise': 'LIKELY',
   'anger': 'VERY_UNLIKELY',
   'sorrow': 'VERY_UNLIKELY',
   'headwear': 'VERY_UNLIKELY'},
  'face_2': {'joy': 'VERY_UNLIKELY',
   'surprise': 'VERY_UNLIKELY',
   'anger': 'VERY_UNLIKELY',
   'sorrow': 'VERY_UNLIKELY',
   'headwear': 'VERY_LIKELY'}},
 {'face_1': {'joy': 'VERY_LIKELY',
   'surprise': 'VERY_UNLIKELY',
   'anger': 'VERY_UNLIKELY',
   'sorrow': 'VERY_UNLIKELY',
   'headwear': 'VERY_UNLIKELY'},
  'face_2': {'joy': 'POSSIBLE',
   'surprise': 'VERY_UNLIKELY',
   'anger': 'VERY_UNLIKELY',
   'sorrow': 'VERY_UNLIKELY',
   'headwear': 'VERY_UNLIKELY'}}]

我的目标是将其转换为 ML 可读格式。我想使用如下所示的编码(n 是整个数据集中预测人脸的最大数量):

         joy_1  surprise_1 , ...., anger_n    sorrow_n    headwear_n
img_1      1       2       , ....,  0           0            0
img_2      0       0       , ....,  0           0            0
img_3      0       0       , ....,  0           0            0
img_4      5       4       , ....,  0           0            0
  .
  .
  .

我已经将 sklearn dictVectorizer 和 labelEncoder 用于其他作为字典列表的功能,但这些字典没有像此数据源那样将字典作为值。

我不知道有什么开箱即用的方法可以处理将序数值(VERY_UNLIKELY、...、VERY_LIKELY)映射到用户中的整数定义方式,同时还处理字典中可能的键。

像下面这样的东西在这里可能是最简单的:

# Include `images` list-of-dicts from question

# images = [{'face_1': {'joy': 'VERY_UNLIKELY',
#            ...]

import numpy as np

observations = ["joy", "surprise", "anger", "sorrow", "headwear"]
levels = {
    "VERY_UNLIKELY": 0,
    "UNLIKELY": 1,
    "POSSIBLE": 2,
    "LIKELY": 3,
    "VERY_LIKELY": 4,
}

N_IMAGES = len(images)
N_OBSERVATIONS = len(observations)
N_PEOPLE_PER_IMAGE = 2

vector = np.zeros((N_IMAGES, N_PEOPLE_PER_IMAGE * N_OBSERVATIONS))

for i, image in enumerate(images):
    for j, face in enumerate(image):
        if not face:
            continue
        else:
            t = (j * N_OBSERVATIONS)
            e = (j * N_OBSERVATIONS) + N_OBSERVATIONS
            obs_vector = [levels[image[face][obs]] for obs in observations]
            vector[i][t:e] = obs_vector

print(vector)

结果:

[[0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [4. 3. 0. 0. 0. 0. 0. 0. 0. 4.]
 [4. 0. 0. 0. 0. 2. 0. 0. 0. 0.]]

如果每张图片最多有 8 张面孔,可以通过设置 N_PEOPLE_PER_IMAGE = 8 轻松扩展。