首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

清理、处理和可视化数据集,第 2 部分 从干净的数据集中获取宝贵洞察-1

清理、处理和可视化数据集,第 2 部分 从干净的数据集中获取宝贵洞察-1

数据是有价的,但来自数据的洞察是无价的。当您得到一个数据集时,如何理解该数据并利用它来获取知识呢?为了帮助您实现此目标,我将向您展示两种处理已清理数据集的方法。
本系列包含 3 部分,本教程是第 2 部分,将继续讨论我在中发起的关于散乱数据的讨论,展示如何对已清理的数据集应用机器学习方法。第 3 部分将继续探讨数据可视化方法。
图 1. 数据处理管道回想,我清理了一个包含动物特征的数据集,以便可以使用该数据集进行聚类。现在,我将使用两种无监督学习算法为此数据进行聚类。第一种算法名为矢量量化                    (VQ),最初被开发为一种基于分组编码原理的数据压缩算法(尽管您也可以用它来解决聚类问题)。第二种算法名为自适应共振理论                    (ART),是利用内存模板的概念开发的,后者可应用于具有相似性的特征。ART                还包含一个重要功能,那就是动态调节所使用的聚类次数,这个特性在聚类领域具有独特的优势。
矢量量化VQ                最初在信号处理中被作为一种压缩数据的方法,它对要传输的数据进行分段,以便最小化将要传输的数据量。通过将类似数据聚类到各个分组中,可以传输集群标识符而不是特征数据,从而最小化传输的数据量。因为可以将不同的特征聚集到一起,所以该方法是有损的,在传输中会丢失一些信息。但是,通过将类似的特征矢量分组到一起,可以实现典型的聚类。
VQ 的结构如图 2                    所示。您可以将要编码(即压缩)的码字或数据作为输入应用于网络。该算法计算整个网络的输出(或码书)的方式是,将特征矢量输入乘以与每个输出节点相关的权重,然后选择具有最小值的输出节点作为最接近的集群。最后,该算法对权重稍作调节,让                VQ 质心向输入方向移动。VQ 以这种方式按照给定迭代次数对网络应用整个码字集(或者直到没有码字更改输出码书的成员关系)。
图 2. 一种矢量量化网络经过训练后,您可以对网络应用新的码字来标识它们的码书(即它们的成员集群)。在数据压缩上下文中,此方法将一个高维特征空间映射到一个低维子空间。
此方法还被应用于数据更正,方法是将损坏的码字应用于网络,然后选择的输出码书表明了该分组的质心,以便重建输入。
实现 VQ通过 VQ                进行聚类可简单定义为:使用一个无标签的数据集来训练网络。在生产环境中,您可以对网络应用新的观察值,并采用胜者全得的方法从输出节点中识别结果集群。我在                GitHub 上提供了一个 。此实现被拆分为两个源文件,但其中一个在各种机器学习算法中是通用的。如图 3 所示,文件 learn.c 实现了 VQ 和                ART 都在使用的通用元素,包括解析来自命令行的用户选项,打开和关闭文件,并解析来自输入文件的观察值。文件 vq.c 包含拆分为初始化、训练和验证的                VQ 实现。
图 3. VQ 实现样本的高级流程图后续讨论将专注于 VQ 实现的细节。
首先,注意所需的结构和符号的集合,如下所示。我定义了输出节点(码书)的数量;学习率;输出计算数组;权重(涵盖指向输出的特征矢量的二维权重,如上面图 2                所示);以及网络的输入矢量。
清单 1. VQ                的关键结构和符号
1
2
3
4
5
6
7
8
#define OUTPUTS            7
#define MAX_FEATURES      21

#define RATE            0.01

static double  outputs[ OUTPUTS ];
static double  weights[ OUTPUTS ][ MAX_FEATURES ];
static int     input_feature_vector[ MAX_FEATURES ];




vq_initialize 函数初始化输出数组和权重数组。
vq_train 函数实现了网络的训练循环(参见 清单 2)。需要向此函数传递要在训练中执行的测试数据文件和迭代次数。该算法首先分配前                    n 个观察值作为类原型(但也可以随机分配观察值)。get_observation                函数从输入文件中获取一个新观察值,vq_set_input_vector                将这个观察值转换为输入矢量。vq_updateweights                函数更新输出节点(类)的权重,以便向输入特征方向移动(提供一个较小的学习率来最大程度地减少更改)。
然后,我对训练循环执行了指定的迭代次数。此循环获取一个新观察值(而且如果循环到达文件末尾,则回到起点重新开始),然后在观察值上执行一个类似的训练周期。该观察值被馈送到网络的输入矢量中(通过                vq_set_input_vector),然后在网络中对输入进行前馈处理以识别最近的类(通过                vq_feedforward)。然后,这一步返回了最近的类,我使用该类更新此输出节点的权重。
清单 2. 训练 VQ 网络的 vq_train                    函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
void vq_train( FILE *fptr, long iterations )
{
   int result;
   observation obs;
   long iteration = 0;

   // Initialize the first N observations to the N classes.
   for ( int class = 0 ; class < OUTPUTS ; class++ )
   {
      result = get_observation( fptr, &obs );
      vq_set_input_vector( &obs );
      vq_updateweights( class );
   }

   while ( iteration < iterations )
   {
      result = get_observation( fptr, &obs );

      if ( !result )
      {
         // Reset the file position to the beginning.
         fseek( fptr, 0L, SEEK_SET );
         iteration++;
      }
      else
      {
         vq_set_input_vector( &obs );
         int class = vq_feedforward( );
         vq_updateweights( class );
      }
   }

   return;
}




清单 3 提供了 vq_feedforward                函数,该函数执行网络,并识别代表离观察值最近的类的获胜输出节点。为此,该函数会迭代每个输出节点,并计算来自输入矢量的权重的欧氏距离之和。该结果会为每个输出节点的权重提供输入特征矢量的类似指标,其中最小的数字表示最近的集群。该函数的后半部分将跟踪最佳的输出节点,然后将其返回给调用方。
清单 3. 执行 VQ 网络的                    vq_feedforward                函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
int vq_feedforward( void )
{
   int best;
   double best_value;

   // Given the current input feature vector, compute each output node.
   for ( int output = 0 ; output < OUTPUTS ; output++ )
   {
      outputs[ output ] = 0.0;
      for ( int feature = 0 ; feature < MAX_FEATURES ; feature++ )
      {
         outputs[ output ] +=
            distance( NORMALIZE( weights[ output ][ feature ] ),
                      input_feature_vector[ feature ] );
      }

      // Keep track of the best activation
      if ( output == 0 )
      {
         best = 0;
         best_value = outputs[ output ];
      }
      else
      {
         if ( outputs[ output ] < best_value )
         {
            best = output;
            best_value = outputs[ output ];
         }
      }
   }
   return best;
}




清单 4 中所示的 vq_updateweights 函数实现了 VQ                的学习部分。一旦找到离输入矢量最近的输出节点,就可以更新此输出节点的权重,以便将它们朝新特征方向移动。为此,我采用了一个学习率来调节每个权重,调节幅度为特征矢量值与(获胜输出节点的)此特征权重的差值,以便减少观察值的总体变化。
清单 4. 学习最新特征矢量的                    vq_updateweights                函数
1
2
3
4
5
6
7
8
9
10
11
void vq_updateweights( int class )
{
   for ( int feature = 0 ; feature < MAX_FEATURES ; feature++ )
   {
      weights[ class ][ feature ] += RATE *
         ( ( double ) NORMALIZE( input_feature_vector[ feature ] ) -
                      weights[ class ][ feature ] );
   }

   return;
}




验证函数(vq_validate,未具体展示)用于测试新观察值,但不包括新的学习,所以无法验证将网络推广到未见过的观察值的效果。在来自我的测试数据文件的观察值集中,此函数识别每个观察值的获胜节点(或类)。
返回列表