अधिकांश उत्तर मैंने अभी तक 2 डी संस्करण पर ध्यान केंद्रित किया है (जब आपको 2 आयामों में अंक क्लस्टर करने की आवश्यकता है)। मनमाने ढंग से आयामों में क्लस्टरिंग का मेरा कार्यान्वयन यहां दिया गया है।
n में
k-means algorithm की
बुनियादी विचार धुंधली हो जाती है:
- असाइन:
- यादृच्छिक कश्मीर शुरुआती बिंदु
- ऐसा करने तक आप धैर्य या क्लस्टर काम नहीं बदलता है से अधिक उत्पन्न प्रत्येक बिंदु निकटतम प्रारंभ बिंदु
- टी लेने के द्वारा प्रत्येक प्रारंभिक बिंदु का स्थान पुन: गणना करें वह इसे बीच औसत क्लस्टर
है किसी भी तरह के परिणाम मैं MNIST छवियों क्लस्टर करने का प्रयास करेंगे मान्य करने के लिए सक्षम होने के लिए।
import numpy as np
import tensorflow as tf
from random import randint
from collections import Counter
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/")
X, y, k = mnist.test.images, mnist.test.labels, 10
तो यहाँ एक्स क्लस्टर के लिए अपने डेटा (10000, 784)
, y वास्तविक संख्या है, और कश्मीर क्लस्टर की संख्या (जो अंक। की संख्या के रूप में ही है अब वास्तविक है एल्गोरिथ्म:।।
# select random points as a starting position. You can do better by randomly selecting k points.
start_pos = tf.Variable(X[np.random.randint(X.shape[0], size=k),:], dtype=tf.float32)
centroids = tf.Variable(start_pos.initialized_value(), 'S', dtype=tf.float32)
# populate points
points = tf.Variable(X, 'X', dtype=tf.float32)
ones_like = tf.ones((points.get_shape()[0], 1))
prev_assignments = tf.Variable(tf.zeros((points.get_shape()[0],), dtype=tf.int64))
# find the distance between all points: http://stackoverflow.com/a/43839605/1090562
p1 = tf.matmul(
tf.expand_dims(tf.reduce_sum(tf.square(points), 1), 1),
tf.ones(shape=(1, k))
)
p2 = tf.transpose(tf.matmul(
tf.reshape(tf.reduce_sum(tf.square(centroids), 1), shape=[-1, 1]),
ones_like,
transpose_b=True
))
distance = tf.sqrt(tf.add(p1, p2) - 2 * tf.matmul(points, centroids, transpose_b=True))
# assign each point to a closest centroid
point_to_centroid_assignment = tf.argmin(distance, axis=1)
# recalculate the centers
total = tf.unsorted_segment_sum(points, point_to_centroid_assignment, k)
count = tf.unsorted_segment_sum(ones_like, point_to_centroid_assignment, k)
means = total/count
# continue if there is any difference between the current and previous assignment
is_continue = tf.reduce_any(tf.not_equal(point_to_centroid_assignment, prev_assignments))
with tf.control_dependencies([is_continue]):
loop = tf.group(centroids.assign(means), prev_assignments.assign(point_to_centroid_assignment))
sess = tf.Session()
sess.run(tf.global_variables_initializer())
# do many iterations. Hopefully you will stop because of has_changed is False
has_changed, cnt = True, 0
while has_changed and cnt < 300:
cnt += 1
has_changed, _ = sess.run([is_continue, loop])
# see how the data is assigned
res = sess.run(point_to_centroid_assignment)
अब यह समय की जांच कितना अच्छा हमारे समूहों हो रहा है इस हम समूह के सभी वास्तविक संख्या कि क्लस्टर में एक साथ दिखाई उसके बाद हम सबसे लोकप्रिय विकल्प है कि क्लस्टर में देखेंगे ऐसा करने के लिए। टी के मामले में वह सही क्लस्टरिंग हमारे पास प्रत्येक समूह में केवल एक मूल्य होगा। यादृच्छिक क्लस्टर के मामले में प्रत्येक मूल्य समूह में लगभग समान रूप से प्रतिनिधित्व किया जाएगा।
[(0, 738), (6, 18), (2, 11)]
[(1, 641), (3, 53), (2, 51)]
[(1, 488), (2, 115), (7, 56)]
[(4, 550), (9, 533), (7, 280)]
[(7, 634), (9, 400), (4, 302)]
[(6, 649), (4, 27), (0, 14)]
[(5, 269), (6, 244), (0, 161)]
[(8, 646), (5, 164), (3, 125)]
[(2, 698), (3, 34), (7, 14)]
[(3, 712), (5, 290), (8, 110)]
यह बहुत अच्छी है, क्योंकि मायने रखता है के बहुमत पहले समूह में है:
nums_in_clusters = [[] for i in xrange(10)]
for cluster, real_num in zip(list(res), list(y)):
nums_in_clusters[cluster].append(real_num)
for i in xrange(10):
print Counter(nums_in_clusters[i]).most_common(3)
यह मैं कुछ इस तरह देता है। आप देखते हैं कि क्लस्टरिंग 7 और 9, 4 और 5 को भ्रमित करता है लेकिन 0 बहुत अच्छी तरह से क्लस्टर किया गया है।
कुछ दृष्टिकोण है कि यह कैसे सुधार करने के लिए:
- एल्गोरिथ्म कई बार चलाने के लिए और जब कुछ भी एक को सौंपा गया है सबसे अच्छा एक
- हैंडलिंग मामलों (समूहों के लिए दूरी के आधार पर) का चयन करें क्लस्टर। मेरे मामले में आपको
means
चर में नैन मिलेगा क्योंकि count
0.
- यादृच्छिक बिंदु प्रारंभिकरण है।
का उपयोग शायद मैं इसे थोड़ा बेहतर व्याख्या करनी चाहिए। यह एन अंक लेता है और उनकी प्रतियां बनाता है। यह के वर्तमान सेंट्रॉइड लेता है और उनमें से एन प्रतियां बनाता है। इसके बाद यह प्रत्येक बिंदु से प्रत्येक केंद्र से एन * के दूरी प्राप्त करने के लिए इन दो बड़े टेंसर को घटा देता है। यह उनसे वर्गों की दूरी की गणना करता है, और प्रत्येक बिंदु के लिए सबसे अच्छा खोजने के लिए 'argmin' का उपयोग करता है। फिर यह अपने क्लस्टर असाइनमेंट के आधार पर के विभिन्न टेंसर में बिंदुओं को समूहित करने के लिए गतिशील_ विभाजन का उपयोग करता है, उन समूहों में से प्रत्येक के माध्यम से साधन पाता है, और उस पर आधारित सेंट्रॉइड सेट करता है। – dga