自组织映射(Self-Organizing Map, SOM)是一种聚类方法,它属于非线性降维技术。SOM 的主要思想是将原始数据映射到一个较低维的子空间,同时保持数据之间的原始结构和关系。SOM 的特点是可视化程度较高,可以直观地展示数据中的簇结构和关联关系。
SOM 的基本原理是基于神经网络的自组织特性。在 SOM 中,神经网络的输入层和输出层都对应于原始数据的特征空间,而隐藏层则表示数据的低维表示。通过不断调整神经网络的权重,使得输入数据在隐藏层中能够被有效地压缩和编码,同时保持原始数据之间的相似性关系。
使用 SOM 进行聚类自组织映射的步骤如下:
- 数据预处理:对原始数据进行预处理,如去除异常值、填补缺失值、归一化等,以提高聚类效果。
- 初始化 SOM 网络:随机初始化 SOM 网络的权重,包括输入层、隐藏层和输出层。
- 训练 SOM 网络:根据原始数据,通过梯度下降等优化算法不断调整 SOM 网络的权重,使得输入数据在隐藏层中能够被有效地压缩和编码。
- 计算相似性:使用 SOM 网络的输出层计算原始数据之间的相似性,通常采用余弦相似度。
- 划分簇:根据计算得到的相似性,将数据划分为不同的簇。可以将相似度较高的数据点分配到同一个簇,相似度较低的数据点分配到不同的簇。
- 评估聚类效果:使用一些评估指标(如轮廓系数、误差平方和等)来评估聚类的效果,以便选择最佳聚类算法和参数。
在实际应用中,SOM 聚类自组织映射可以用于可视化高维数据、分析市场细分、生物信息学等领域。需要注意的是,SOM 方法需要适当调整网络参数,例如学习率、神经元数量等,以获得较好的聚类效果。
Softmax classification
Import the usual libraries:
%matplotlib inline
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
Generated some initial 2D data:
learning_rate = 0.01
training_epochs = 1000
num_labels = 3
batch_size = 100
x1_label0 = np.random.normal(1, 1, (100, 1))
x2_label0 = np.random.normal(1, 1, (100, 1))
x1_label1 = np.random.normal(5, 1, (100, 1))
x2_label1 = np.random.normal(4, 1, (100, 1))
x1_label2 = np.random.normal(8, 1, (100, 1))
x2_label2 = np.random.normal(0, 1, (100, 1))
plt.scatter(x1_label0, x2_label0, c='r', marker='o', s=60)
plt.scatter(x1_label1, x2_label1, c='g', marker='x', s=60)
plt.scatter(x1_label2, x2_label2, c='b', marker='_', s=60)
plt.show()
Define the labels and shuffle the data:
xs_label0 = np.hstack((x1_label0, x2_label0))
xs_label1 = np.hstack((x1_label1, x2_label1))
xs_label2 = np.hstack((x1_label2, x2_label2))
xs = np.vstack((xs_label0, xs_label1, xs_label2))
labels = np.matrix([[1., 0., 0.]] * len(x1_label0) + [[0., 1., 0.]] * len(x1_label1) + [[0., 0., 1.]] * len(x1_label2))
arr = np.arange(xs.shape[0])
np.random.shuffle(arr)
xs = xs[arr, :]
labels = labels[arr, :]
We'll get back to this later, but the following are test inputs that we'll use to evaluate the model:
test_x1_label0 = np.random.normal(1, 1, (10, 1))
test_x2_label0 = np.random.normal(1, 1, (10, 1))
test_x1_label1 = np.random.normal(5, 1, (10, 1))
test_x2_label1 = np.random.normal(4, 1, (10, 1))
test_x1_label2 = np.random.normal(8, 1, (10, 1))
test_x2_label2 = np.random.normal(0, 1, (10, 1))
test_xs_label0 = np.hstack((test_x1_label0, test_x2_label0))
test_xs_label1 = np.hstack((test_x1_label1, test_x2_label1))
test_xs_label2 = np.hstack((test_x1_label2, test_x2_label2))
test_xs = np.vstack((test_xs_label0, test_xs_label1, test_xs_label2))
test_labels = np.matrix([[1., 0., 0.]] * 10 + [[0., 1., 0.]] * 10 + [[0., 0., 1.]] * 10)
Again, define the placeholders, variables, model, and cost function:
train_size, num_features = xs.shape
X = tf.placeholder("float", shape=[None, num_features])
Y = tf.placeholder("float", shape=[None, num_labels])
W = tf.Variable(tf.zeros([num_features, num_labels]))
b = tf.Variable(tf.zeros([num_labels]))
y_model = tf.nn.softmax(tf.matmul(X, W) + b)
cost = -tf.reduce_sum(Y * tf.log(y_model))
train_op = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
correct_prediction = tf.equal(tf.argmax(y_model, 1), tf.argmax(Y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
Train the softmax classification model:
with tf.Session() as sess:
tf.global_variables_initializer().run()
for step in range(training_epochs * train_size // batch_size):
offset = (step * batch_size) % train_size
batch_xs = xs[offset:(offset + batch_size), :]
batch_labels = labels[offset:(offset + batch_size)]
err, _ = sess.run([cost, train_op], feed_dict={X: batch_xs, Y: batch_labels})
if step % 100 == 0:
print (step, err)
W_val = sess.run(W)
print('w', W_val)
b_val = sess.run(b)
print('b', b_val)
print("accuracy", accuracy.eval(feed_dict={X: test_xs, Y: test_labels}))
0 109.861
100 11.1746
200 7.66511
300 6.14837
400 7.36667
500 6.21197
600 5.20238
700 6.67839
800 5.75361
900 4.70638
1000 6.39738
1100 5.49439
1200 4.38705
1300 6.25161
1400 5.32159
1500 4.16287
1600 6.16709
1700 5.19838
1800 3.9968
1900 6.11495
2000 5.10726
2100 3.8689
2200 6.08159
2300 5.03829
2400 3.76737
2500 6.05979
2600 4.98517
2700 3.68479
2800 6.04543
2900 4.94369
w [[-2.54555464 0.36140779 2.18415737]
[-0.09027337 1.47717059 -1.38689983]]
b [ 10.06975937 -2.41784143 -7.65189791]
accuracy 0.966667