【问题标题】:Convert list of dicts with dicts as values to ML features将具有 dicts 作为值的 dicts 列表转换为 ML 特征
【发布时间】:2021-07-25 23:10:51
【问题描述】:

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

$ 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 用于其他作为 dicts 列表的功能,但这些 dicts 没有 dicts 作为值,就像这个数据源的情况一样。

【问题讨论】:

  • 您能否详细说明这些行在您想要的输出中代表什么?是否要将faces 中的每个值转换为一行?
  • @AlexanderL.Hayes 每行代表一张通过 Google Vision API 解析的图像。对于图像中的每张脸,GVA 引擎为以下 5 个字段“快乐/惊喜/愤怒/悲伤/头饰”中的每一个生成一个分数。预测分数分为“非常不像/不像/可能/像/非常像”类别。这些类别不是独立的,因此希望将它们转换为 0-5 之间的分数(0 表示“未观察到”,5 表示“极有可能”)。每张图像中有 0-8 张面孔,所以我最终会得到 40 个特征(8 个潜在面孔中的每一个有 5 个面部表情)。希望它有意义吗?
  • 总而言之,是的,所需输出中的每一行都代表一个图像。
  • 你可以做两件事。将字典转换为数据框。然后使用分类编码器将您的字符串编码为整数。首先转换为df。然后一个简单的谷歌搜索可以产生编码的解决方案。

标签: python machine-learning scikit-learn feature-extraction feature-engineering


【解决方案1】:

我不知道有什么开箱即用的方法可以处理以用户定义的方式将序数值(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 轻松扩展。

【讨论】:

  • 非常感谢亚历山大!这看起来是个不错的方法。我马上试试。 / 乌尔里克
  • 更新:像亚历山大一样的魅力。再次感谢。
  • 不错!如果它解决了问题,请随时接受答案。如果您更喜欢 pandas.DataFrame 路线,可能会有一个很好的替代解决方案(对于这类问题,我个人更喜欢 numpy,但 pandas 确实使一些下游分析更容易)。
猜你喜欢
  • 1970-01-01
  • 2017-05-17
  • 2020-10-15
  • 2014-12-17
  • 2013-05-25
  • 1970-01-01
  • 2016-11-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多