使用不同形状的数据进行训练。填充是替代品吗?

数据挖掘 Python 可视化 数据清理 数据 无监督学习
2022-02-21 07:11:24

我有一个大约 1k 个样本的数据集,我想应用一些无监督的技术来对这些数据进行聚类和可视化。

数据可以解释为电子表格的表格,不幸的是它没有非常明确的结构模式。表格行数不同,但列数不同。

数据结构如下:

sample 1:

{
  "table1": {
    "column1": [
      "-",
      "-",
      "-"
    ],
    "column2": [
      "2017-04-16 10:00",
      "2017-04-16 10:00",
      "2017-04-16 10:00"
    ],
    "column3": [
      "-",
      "-",
      "-"
    ],
    "column4": [
      "name X",
      "name Y",
      "name Z"
    ],
    "column5": [
      "0",
      "0",
      "0"
    ],
  }
}


sample 2:

{
  "table1": {
    "column1": [
      "-",
      "-",
      "-",
      "-",
      "-",
      "-",
      "-",
      "-"
    ],
    "column2": [
      "2017-04-10 22:00",
      "2017-04-10 22:00",
      "2017-04-10 22:00",
      "2017-04-10 22:00",
      "2017-04-10 22:00",
      "2017-04-10 22:00",
      "2017-04-10 22:00",
      "2017-04-10 22:00"
    ],
    "column3": [
      "-",
      "-",
      "-",
      "-",
      "-",
      "-",
      "-",
      "-"
    ],
    "column4": [
      "name A",
      "name Z",
      "name B",
      "name X",
      "name C",
      "name D",
      "name E",
      "name F"
    ],
    "coumn5": [
      "",
      "",
      "3",
      "1",
      "0",
      "3",
      "0",
      "0"
    ]
  }
}

这些样本来自一个系统生成的警报,该系统从许多节点收集信息(这些节点被命名为“名称 A”、“名称 B”......)。我的目标是将这些数据转换为矩阵 (n_samples x n_features) 以应用聚类和可视化算法。

如何使用这些数据进行无监督训练?填充是解决这个问题的方法吗?如果是这样,我该如何在这种情况下应用填充?

1个回答

填充是否合适实际上取决于数据集的整个结构、不同变量/列的相关性以及最终要运行的模型类型。

将使用填充,因此您必须固定每个样本的长度(最长样本的长度或固定长度 - 较长的样本将被修剪或过滤以适应该长度)。作为字符串的变量可以用空字符串填充,带数字的变量可以用零填充。然而,还有许多其他的填充方法,例如使用数值变量的平均值,甚至基于模型的填充,使用“最有意义”的值填充特定样本中的空白。像这样深入研究可能更普遍地称为插补,而不是填充 - 这在时间序列数据中很常见,其中间隙并不总是在样本的一端。

下面我概述了一种填充或标准化每个样本长度的方法。它没有专门填充。

由于您没有提到编程语言,我将给出Python中的代码片段,但在RJulia等其他语言中也很容易实现

该方法

根据您提供的两个示例,似乎每个示例都是一个日历日,其中有可变数量的观察。

还有一些列是字符串,而其他列是数字字符串(例如示例 2 中的第 5 列)。

在一般的时间序列分析中,希望有一个连续的数据频率。这意味着有一天给一个输入。因此,我的方法是将您的数据转换为类似于每个样本的每个变量(即列)的单个输入的形式。

这是一种通用方法,您将不得不尝试或进行更多研究,以了解这对于您的特定数据在现实中的表现。

时间戳

我会将它们用作一种索引,例如Pandas DataFrame中的索引。一行 = 一个时间戳。然后,多个变量是不同的列。

处理字符串

我将假设您的数据集在每列中具有有限数量的可能字符串。例如,第 4 列(包含名称)将始终包含给定集合中的名称。可以执行set(table2['column 4'])以查看存在哪些值(删除重复项)。甚至:

# Gather a single list containing all strings in column 4 of all samples
all_names = []
[]    # list comprehension to loop

# Check how many strings there are
from collections import Counter
counter = Counter(table2['column4'])
print(len(counter))                 # see how many unique values exist
print(counter)                      # see how many times each string appears
print(counter.most_common(5))       # see the most common 5 strings

现在假设这表明存在有限数量(很可能是这种情况),您可以考虑使用每个样本的稀疏表示(这意味着每天)。例如,如果整个数据集中的所有单词都是:(['hi', 'hello', 'wasup', 'yo', 'bonjour']删除了重复项),那么对于一个第 4 列包含 eg 的单个样本['hi', 'hello', 'yo', 'hi'],您对该样本的稀疏表示将是:[2, 1, 0, 1, 0],因为该样本有两个“hi”,一个 '你好',零'wasup'等等。然后,此稀疏表示将成为时间戳(该单个样本)的第 4 列的单个输入。

可能值得研究一下Scikit-Learn的DictVectorizerCountVectorizer之类的东西。

处理数字列

正如我在开头提到的那样,您可以将它们填充到选定的长度,可能与上面基于字符串的表示的长度相匹配(或不匹配!),具体取决于您的最终模型。然后,您可以使用对您的模型有意义的值填充输入(请参阅我在答案开头提到的选项类型)。这应该再次为您提供给定日期的单个向量,其中包含数字列中的信息。