跳转到主要内容

TensorFlow™在砖

集群和k - means

我们现在进入我们的第一个应用程序,它与k - means聚类算法。聚类是数据挖掘的练习,采取一系列的数据和我们发现的点组相似。k - means算法是伟大的寻找集群在许多类型的数据集。

更多关于集群和k - means,看到scikit-learn文档在其k - means算法或者看这个视频:

生成样本

首先,我们需要生成一些样品。我们可以随机生成样本,但这可能会给我们非常稀疏的点,或只是一个大集团,而不是为集群非常激动人心的。

相反,我们要通过生成三个重心,然后随机选择(正态分布)。首先,这是一个方法:

进口tensorflow作为特遣部队进口numpy作为np
                   defcreate_samples(n_clusters、n_samples_per_cluster n_features embiggen_factor,种子):np.random.seed(种子)片= []质心= []#为每个集群创建样本范围(n_clusters):样品=特遣部队。random_normal (n_samples_per_cluster n_features),意思是=0.0stddev =5.0,dtype =特遣部队。float32种子=种子,name =“cluster_ {}”格式(我))current_centroid = (np.random.random ((1n_features)) * embiggen_factor) - (embiggen_factor /2)centroids.append (current_centroid)+ = current_centroid样品slices.append(样本)#创建一个大数据集“样本”样品= tf.concat(片,0、名称=“样本”)质心= tf.concat(重心,0、名称=“重心”)返回重心,样品

把这段代码放在functions.py

这样的工作方式是创建n_clusters随机(使用不同的重心np.random。随机((n_features))点)和使用这些作为中心tf.random_normal。的tf.random_normal函数生成正态分布随机值,然后添加到当前的中心观点。这将创建一个点在中心。然后记录下质心(centroids.append)和生成的样本(slices.append(样本))。最后,我们创建了“一个大的样品列表”使用tf.concat,把重心TensorFlow变量,也使用tf.concat

保存这个create_samples方法在一个文件中调用functions.py可以让我们这些方法导入脚本(下)课。创建一个新文件generate_samples.py,下面的代码:

进口tensorflow作为特遣部队进口numpy作为np功能进口create_samplesn_features =2n_clusters =3n_samples_per_cluster =500年种子=700年embiggen_factor =70年
                   np.random.seed(种子)
                   重心、样品= create_samples (n_clusters、n_samples_per_cluster n_features, embiggen_factor,种子)
                   模型= tf.global_variables_initializer ()tf.Session ()作为会话:sample_values = session.run(样本)centroid_values = session.run(重心)

这只是设置集群的数量和特性(我建议保持特征的数量,稍后让我们想象他们),并生成样本的数量。增加了embiggen_factor将增加“传播”或集群的大小。我选择了一个值,它提供了良好的学习机会,因为它产生视觉识别集群。

结果的可视化,允许创建一个绘图函数使用matplotlib。将此代码添加到functions.py:

defplot_clusters(重心,all_samples n_samples_per_cluster):进口matplotlib.pyplot作为plt#划分不同的集群#为每个集群选择不同的颜色颜色= plt.cm.rainbow (np.linspace (0,1,len(重心)))我,重心列举(重心):#抓住只是样品玻璃钢给定的集群,并把它们与一个新的颜色样品= all_samples[我* n_samples_per_cluster: (i +1)* n_samples_per_cluster]plt.scatter(样本(:,0),样品(:,1],c =颜色[我])#还阴谋重心plt.plot(质心[0),重心1),markersize =35标志=“x”颜色=“k”新=10)plt.plot(质心[0),重心1),markersize =30.标志=“x”颜色=“米”新=5)plt.show ()

把这段代码放在functions.py

所有这些代码是块样品从每个集群使用一个不同的颜色,并创建一个大的红色X质心的位置。质心作为参数给出,很方便。

更新generate_samples.py通过添加导入这个功能从函数导入plot_clusters文件的顶部。然后,添加下面这行代码:

plot_clusters (sample_values centroid_values n_samples_per_cluster)

运行generate_samples.py现在应该给你如下图:

初始化

k - means算法从初始质心的选择开始,这只是随机猜测的实际质心数据。下面的函数将随机选择一个数量的样本数据集作为初始猜测:

defchoose_random_centroids(样本,n_clusters):步骤0:初始化:选择“n_clusters”数量的随机点n_samples = tf.shape(样本)0]random_indices = tf.random_shuffle (tf。范围(0,n_samples))开始= [0,)大小= (n_clusters,)大小(0]= n_clusterscentroid_indices =特遣部队。(开始random_indices大小)initial_centroids =特遣部队。收集(样本,centroid_indices)返回initial_centroids

把这段代码放在functions.py

此代码首先创建为每个样本(使用一个索引特遣部队。范围(0,n_samples),然后随机打乱。从那里,我们选择一个固定的号码(n_clusters)指标的使用tf.slice。这些指数相关初始质心,然后组合在一起使用tf.gather形成初始质心的数组。

添加这个新的choose_random_centorids函数functions.py,并创建一个新的脚本(或更新你的前一个)如下:

进口tensorflow作为特遣部队进口numpy作为np功能进口create_samples、choose_random_centroids plot_clustersn_features =2n_clusters =3n_samples_per_cluster =500年种子=700年embiggen_factor =70年
                   重心、样品= create_samples (n_clusters、n_samples_per_cluster n_features, embiggen_factor,种子)n_clusters initial_centroids = choose_random_centroids(样本)
                   模型= tf.global_variables_initializer ()tf.Session ()作为会话:sample_values = session.run(样本)updated_centroid_value = session.run (initial_centroids)
                   plot_clusters (sample_values updated_centroid_value n_samples_per_cluster)

这里的主要变化是,我们为这些初始质心,创建一个变量,计算其价值在会话中。然后我们描绘那些第一次猜测plot_cluster,而不是被用来生成数据的实际重心。

运行这个将净上面类似的图像,但重心将在随机位置。几次尝试运行这个脚本,并指出重心的移动。

更新重心

后开始与一些猜的质心位置,然后k - means算法根据数据更新这些猜测。分配每个样本的过程是一个集群的数字,代表质心接近。更新之后,重心是所有样品的方式分配给集群。下面的代码处理分配给最近的集群步骤:

defassign_to_nearest(样本,重心):#发现最近的质心为每个样本#从https://esciencegroup.com/2016/01/05/an-encounter-with-googles-tensorflow/expanded_vectors = tf.expand_dims(样本,0)expanded_centroids = tf.expand_dims(重心,1)距离=特遣部队。reduce_sum (tf.square (tf.subtract(expanded_vectors, expanded_centroids)),2)分钟= tf.argmin(距离,0)从https://esciencegroup.com/2016/01/05/an-encounter-with-googles-tensorflow/ #结束nearest_indices =分钟返回nearest_indices

请注意,我已经借了一些代码这个页面有不同类型的k - means算法,和许多其他有用的信息。

这样的工作方式是计算每个样本和质心之间的距离,而发生的距离=线。这里的距离计算欧氏距离。是一个重要的点tf.subtract会自动扩大两个参数的大小。这意味着在我们的样本矩阵,和重心一个列向量将产生它们之间的两两比较。为了做到这一点,我们使用tf.expand_dims创建一个额外的维度对样品和重心,迫使这种行为的tf.subtract

下一个代码的手更新重心一点:

defupdate_centroids(样本,nearest_indices n_clusters):#更新的质心与之关联的所有样本的均值。nearest_indices = tf.to_int32 (nearest_indices)分区=特遣部队。dynamic_partition(样例、nearest_indices n_clusters)new_centroids = tf.concat ([tf.expand_dims (tf.reduce_mean(分区,0),0)分区分区),0)返回new_centroids

这段代码将最近的指标对于每一个样本,并抓住这些单独的组织使用tf.dynamic_partition。在这里,我们使用tf.reduce_mean在一个组发现的平均组,形成新的重心。从在这里,我们只是tf.concat他们在一起形成我们新的重心。

现在我们有一块,我们可以将这些调用添加到脚本(或创建一个新的):

进口tensorflow作为特遣部队进口numpy作为np功能进口*n_features =2n_clusters =3n_samples_per_cluster =500年种子=700年embiggen_factor =70年
                   
                   data_centroids、样品= create_samples (n_clusters、n_samples_per_cluster n_features, embiggen_factor,种子)n_clusters initial_centroids = choose_random_centroids(样本)initial_centroids nearest_indices = assign_to_nearest(样本)updated_centroids = update_centroids(样本,nearest_indices n_clusters)
                   模型= tf.global_variables_initializer ()tf.Session ()作为会话:sample_values = session.run(样本)updated_centroid_value = session.run (updated_centroids)打印(updated_centroid_value)
                   plot_clusters (sample_values updated_centroid_value n_samples_per_cluster)

这段代码将:

  1. 生成样本初始质心
  2. 随机选择初始质心
  3. 将每个样本对其最近的重心
  4. 更新每个质心相关样本的均值

这是一个迭代的k - means !我鼓励你去尝试去做练习,将这转化为一个迭代版本。

1)种子选项传递给generate_samples确保“随机”生成的样本你每次运行脚本是一致的。我们没有通过种子的choose_random_centroids函数,这意味着这些最初的重心是不同的每次运行脚本。更新脚本包含一个新的随机种子质心。

2)k - means算法进行迭代,从先前的迭代中更新的重心是用来指定集群,然后用来更新重心,等等。换句话说,该算法调用之间的交替assign_to_nearestupdate_centroids。更新代码来执行这个迭代10次,之前停止。你会发现产生的重心更平均的k - means更多的迭代。(对于那些有经验与k - means,未来的教程将着眼于收敛函数和其他的停止标准。)