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)
這段代碼將:
- 生成樣本初始質心
- 隨機選擇初始質心
- 將每個樣本對其最近的重心
- 更新每個質心相關樣本的均值
這是一個迭代的k - means !我鼓勵你去嚐試去做練習,將這轉化為一個迭代版本。
1)種子選項傳遞給generate_samples
確保“隨機”生成的樣本你每次運行腳本是一致的。我們沒有通過種子的choose_random_centroids
函數,這意味著這些最初的重心是不同的每次運行腳本。更新腳本包含一個新的隨機種子質心。
2)k - means算法進行迭代,從先前的迭代中更新的重心是用來指定集群,然後用來更新重心,等等。換句話說,該算法調用之間的交替assign_to_nearest
和update_centroids
。更新代碼來執行這個迭代10次,之前停止。你會發現產生的重心更平均的k - means更多的迭代。(對於那些有經驗與k - means,未來的教程將著眼於收斂函數和其他的停止標準。)