機器學習模型| 無監督學習


 

無監督學習

相對監督學習(輸入進x,有對應的y),沒有標注

聚類

  • k均值
  • 基於密度的聚類
  • 最大期望聚類

降維

  • 潛語義分析(LSA)
  • 主成分分析(PCA)
  • 奇異值分解(SVD)

 

 

 

 

k 均值(k-means)是聚類算法中最為簡單、高效的,屬於無監督學習算法
核心思想:由用戶指定k個初始質心(initial centroids),以作為聚類的類別(cluster),重復迭代直至算法收斂
基本算法流程:

  • 選取k個初始質心(作為初始cluster);
  • repeat:
    對每個樣本點,計算得到距其最近的質心,將其類別標為該質心所對應的cluster;
    重新計算k個cluser對應的質心;
until 質心不再發生變化或迭代達到上限

  kmeans代碼實現

import numpy as np
import matplotlib.pyplot as plt

# 從sklearn中直接生成聚類數據
from sklearn.datasets.samples_generator import make_blobs

加載數據

x, y = make_blobs( n_samples=100, centers=6, random_state=1234, cluster_std=0.6 )
#100個樣本,centers生成的樣本中心(類別)數; random_state --seed used by the random number generator;
#cluster_std為每個類別設置不同的方差
#x.shape #(100, 2)
plt.figure(figsize=(6,6))
plt.scatter(x[:,0], x[:,1], c=y)  #c=y 6類,變得有顏色
plt.show()

          

 

 

算法實現

# 引入scipy中的距離函數,默認計算歐式距離
from scipy.spatial.distance import cdist

class K_Means(object):
    # 初始化,參數 n_clusters(K)、迭代次數max_iter、初始質心 centroids
    def __init__(self, n_clusters=5, max_iter=300, centroids=[]):
        self.n_clusters = n_clusters
        self.max_iter = max_iter
        self.centroids = np.array( centroids, dtype=np.float )
        
    # 訓練模型方法,k-means聚類過程,傳入原始數據
    def fit(self, data):
        # 假如沒有指定初始質心,就隨機選取data中的點作為初始質心
        if( self.centroids.shape == (0,) ):
            # 從data中隨機生成0到data行數的6個整數,作為索引值
            self.centroids = data[ np.random.randint( 0, data.shape[0], self.n_clusters ) ,: ]
            
        # 開始迭代
        for i in range(self.max_iter):
            # 1. 計算距離矩陣,得到的是一個100*6的矩陣
            distances = cdist(data, self.centroids)
            
            # 2. 對距離按有近到遠排序,選取最近的質心點的類別,作為當前點的分類
            c_ind = np.argmin( distances, axis=1 ) #axis=1保留最近一列
            
            # 3. 對每一類數據進行均值計算,更新質心點坐標
            for i in range(self.n_clusters ):
                # 排除掉沒有出現在c_ind里的類別
                if i in c_ind:
                    # 選出所有類別是i的點,取data里面坐標的均值,更新第i個質心
                    #data[c_ind==i]布爾索引,拿到為true的值
                    self.centroids[i] = np.mean( data[c_ind==i], axis=0 )
    
    # 實現預測方法
    def predict(self, samples):
        # 跟上面一樣,先計算距離矩陣,然后選取距離最近的那個質心的類別
        distances = cdist(samples, self.centroids)
        c_ind = np.argmin( distances, axis=1 )
        
        return c_ind
##測試下,二維數組5 * 4(4個質心點),行數代表有幾個點,一行數是跟每一個質心的距離
dist = np.array([[121,221,32,43],
                [121,1,12,23],
                [65,21,2,43],
                [1,221,32,43],
                [21,11,22,3],])
c_ind = np.argmin( dist, axis=1 )
print(c_ind) #每一個元素跟哪一類最近 [2 1 2 0 3]
x_new=x[0:5] 
print(x_new)#
print(c_ind==2) #[ True False  True False False]
print(x_new[c_ind==2])
np.mean(x_new[c_ind==2], axis=0) #每一個坐標每一列對應的平均值

----->>

[2 1 2 0 3]
[[-0.02708305  5.0215929 ]
 [-5.49252256  6.27366991]
 [-5.37691608  1.51403209]
 [-5.37872006  2.16059225]
 [ 9.58333171  8.10916554]]
[ True False  True False False]
[[-0.02708305  5.0215929 ]
 [-5.37691608  1.51403209]]
Out[14]:
array([-2.70199956,  3.26781249])

測試

# 定義一個繪制子圖函數
def plotKMeans(x, y, centroids, subplot, title):
    # 分配子圖,121表示1行2列的子圖中的第一個
    plt.subplot(subplot)
    plt.scatter(x[:,0], x[:,1], c='r')
    # 畫出質心點
    plt.scatter(centroids[:,0], centroids[:,1], c=np.array(range(5)), s=100)
    plt.title(title)
#centroids指定初始點
kmeans = K_Means(max_iter=300, centroids=np.array([[2,1],[2,2],[2,3],[2,4],[2,5]]))

plt.figure(figsize=(16, 6))
#初始狀態的圖
plotKMeans( x, y, kmeans.centroids, 121, 'Initial State' )

# 開始聚類
kmeans.fit(x)

plotKMeans( x, y, kmeans.centroids, 122, 'Final State' )

# 預測新數據點的類別
x_new = np.array([[0,0],[10,7]])
y_pred = kmeans.predict(x_new)

print(kmeans.centroids)
print(y_pred)

plt.scatter(x_new[:,0], x_new[:,1], s=100, c='black') 

---->>
[[ 5.76444812 -4.67941789]
 [-2.89174024 -0.22808556]
 [-5.89115978  2.33887408]
 [-2.8455246   5.87376915]
 [ 9.20551979  7.56124841]]
[1 4]

               

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM