TensorFlow学习(二) 数据聚类分析

本文通过K均值算法作为例子研究数据聚类分析

一、无监督学习概念

无监督学习可以从给定的数据集中找到感兴趣的模式。

无监督学习,一般不给出模式的相关信息。所以,无监督学习算法需要自动探索信息是怎样组成的,并识别数据中的不同结构。

二、什么是聚类

聚类就是对大量未知标注的数据集,按数据的内在相似性将数据集划分为多个类别,使类别内的数据相似度较大而类别间的数据相似度较小。

 

聚类中没有任何指导信息,完全按照数据的分布进行类别划分。

聚类的大小和结构都没有事先假定。

聚类属于无监督学习。

三、K均值算法

1.基本原理

k均值算法试图将给定的数据分割为k个不相交的组(group)或者簇(cluster),每个簇的指标就是该组所有成员的均值。这个点通常称为质心,指具有相同名称的算术实体,并且可以被表示为任意维度中的向量。

判据和目标是最小化簇成员到包含该成员的簇的实际质心的平方距离的总和。这也称为惯性最小化,k均值的损失函数如下:

2.具体流程

(1)设置初始类别数K,人为设置K个类别中心;

(2)根据样本和类别中心的距离进行类别划分,样本划分到距离最近的类别;

(3)重新计算当前类别划分下每类的中心(类别样本平均值);

(4)在得到类别中心下继续进行类别划分;

(5)如果连续两次的类别划分结果不变则停止算法;否则循环2~5 ;

3.如何确定数据之间的相似度

可以采用欧式距离、曼哈顿距离、余弦相似度等等。这里就不对具体的相似度计算进行探讨。

四、使用TensorFlow进行数据聚类分析。

首先导入数据集,使用sklearn生成数据集

blobs数据集设置类别K为4

circle数据集设置类别K为2

import tensorflow as tf
import numpy as np
import time
import matplotlib
import matplotlib.pyplot as plt

from sklearn.datasets.samples_generator import make_blobs
from sklearn.datasets.samples_generator import make_circles

DATA_TYPE = 'blobs'
N=200
# Number of clusters, if we choose circles, only 2 will be enough
if (DATA_TYPE == 'circle'):
    K=2
else:
    K=4

centers为我们指定的初始质心

生成数据集并且使用matplotlib绘制数据集

centers = [(-2, -2), (-2, 1.5), (1.5, -2), (2, 1.5)]
if (DATA_TYPE == 'circle'):
    data, features = make_circles(n_samples=200, shuffle=True, noise= 0.01, factor=0.4)
else:
    data, features = make_blobs (n_samples=200, centers=centers, n_features = 2, cluster_std=0.8, shuffle=False, random_state=42)

fig, ax = plt.subplots()
ax.scatter(np.asarray(centers).transpose()[0], np.asarray(centers).transpose()[1], marker = 'o', s = 250)
plt.show()

fig, ax = plt.subplots()
if (DATA_TYPE == 'blobs'):
    ax.scatter(np.asarray(centers).transpose()[0], np.asarray(centers).transpose()[1], marker = 'o', s = 250)
    ax.scatter(data.transpose()[0], data.transpose()[1], marker = 'o', s = 100, c = features, cmap=plt.cm.coolwarm )
    plt.show()

points用于存放数据集的坐标

cluser_assignments用于存放每个数据的类别

centroids用于存储每个组质心的坐标

points=tf.Variable(data)
cluster_assignments = tf.Variable(tf.zeros([N], dtype=tf.int64))               # 样本归属聚类中心……

centroids = tf.Variable(tf.slice(points.initialized_value(), [0,0], [K,2]))    # 初始聚类中心……

初始化模型的参数

sess = tf.Session()
sess.run(tf.global_variables_initializer())

sess.run(centroids)

计算所有样本与聚类中心的距离。

对所有的质心做N次复制,对每个 样本做K次复制,这样,样本点和质心的形状都是N*K*2。我们就可以计算每一个样本到每一个质心点之间在所有维度上的距离

rep_centroids = tf.reshape(tf.tile(centroids, [N, 1]), [N, K, 2])
rep_points = tf.reshape(tf.tile(points, [1, K]), [N, K, 2])

对所有维度求和,得到“和最小”的那个索引(这个索引就是每个点所属的新的类)Centroids也会在每个迭代之后由bucket_mean函数更新。

sum_squares = tf.reduce_sum(tf.square(rep_points - rep_centroids), 
reduction_indices=2)
best_centroids = tf.argmin(sum_squares, 1)           # 样本对应的聚类中心索引

停止条件是所有的质心不再变化

did_assignments_change = tf.reduce_any(tf.not_equal(best_centroids, cluster_assignments))

def bucket_mean(data, bucket_ids, num_buckets):
	total = tf.unsorted_segment_sum(data, bucket_ids, num_buckets)
	count = tf.unsorted_segment_sum(tf.ones_like(data), bucket_ids, num_buckets)
	return total / count

means = bucket_mean(points, best_centroids, K)

使用control_dependencies来控制是否更新质心

with tf.control_dependencies([did_assignments_change]):
	do_updates = tf.group(
	centroids.assign(means),
	cluster_assignments.assign(best_centroids))

更新质心

changed = True
iters = 0

fig, ax = plt.subplots()
if (DATA_TYPE == 'blobs'):
    colourindexes=[2,1,4,3]
else:
    colourindexes=[2,1]
while changed and iters < MAX_ITERS:
	fig, ax = plt.subplots()
	iters += 1
	[changed, _] = sess.run([did_assignments_change, do_updates])
	[centers, assignments] = sess.run([centroids, cluster_assignments])
	ax.scatter(sess.run(points).transpose()[0], sess.run(points).transpose()[1], marker = 'o', s = 200, c = assignments, cmap=plt.cm.coolwarm )

打印结果

ax.scatter(centers[:,0],centers[:,1], marker = '^', s = 550, c = colourindexes, cmap=plt.cm.plasma)
	ax.set_title('Iteration ' + str(iters))
	plt.savefig("kmeans" + str(iters) +".png")


ax.scatter(sess.run(points).transpose()[0], sess.run(points).transpose()[1], marker = 'o', s = 200, c = assignments, cmap=plt.cm.coolwarm )
plt.show()


end = time.time()
print(("Found in %.2f seconds" % (end-start)), iters, "iterations")
print("Centroids:")
print(centers)
print("Cluster assignments:", assignments)

运行结果

 

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值