Ng-機器學習(Day 8)

一、 無監督學習

1 K-Means

  • K-Means聚類分析方法的步驟:
  1. 首先隨機初始化K個點(K取決於需要分成的類別數)

  2. 將離初始化點近的點分別歸類,比如下圖,藍色的原點離藍色的×比較近,所以就被歸爲此類。紅色的也同理
    在這裏插入圖片描述

  3. 再計算每個類的均值,將聚類中心點移動到每類均值上

  4. 再計算距離分類

  5. 如此循環3、4兩個步驟

在這裏插入圖片描述

在這裏插入圖片描述

  • 輸入的值:
  1. K:類別數
  2. 數據
    在這裏插入圖片描述
  • 優化目標:
  1. c(i):樣本x(i)被分配到類的索引
  2. μk: 第k個簇的中心
  3. μ_c(i): 樣本x(i)被分配到類的類中心點

目標:最小化代價函數。
在這裏插入圖片描述

  • 如何隨機初始化聚類中心點
  1. 首先保證K<m(樣本總數)
  2. 其次選擇K個樣本點作爲初始的聚類中心點
    在這裏插入圖片描述
  • 局部最優問題:
    根據隨機初始化聚類中心點的不同,我們最終所獲得的聚類結果也會有所不同,很有可能出現局部最優。
    在這裏插入圖片描述

  • 那麼如何避免出現局部最優?
    一般情況下是嘗試多次初始化聚類中心,依此計算代價函數值,最後選擇一個代價函數值最小的作爲初始化點。

  • 如何確定K的值呢?

  1. 肘部法
    逐個嘗試k的值,並計算代價函數,然後選擇肘部作爲合適的點。但有時候可能不會出現肘部。
    在這裏插入圖片描述

  2. 從商業的角度考慮

看分成幾類比較好,比如說將T-shirt的尺寸分爲三種比較有利呢?還是5種比較有利。
在這裏插入圖片描述

2 Dimensionality Reduction

(1) 數據壓縮

就是把一個三維的數據投影到一個二維的平面上,因此這樣就可以使用一個二維的平面來表示原來的數據。
在這裏插入圖片描述

(2) PCA(主成分分析)

假設我們有一組數據分佈如下,PCA就是找到一個平面,使得每個樣本與該投影的到這個平面的線段長度最小。
在這裏插入圖片描述

  • PCA就是找到一個向量μ(i)來最小化這個間距平方的誤差,將2維數據降成1維數據。也可將N維的向量轉化維K維的向量。

  • PCA就是找到一個平面或一條線,使得實際樣本點與該樣本點在該平面或直線上的間距最小化。
    在這裏插入圖片描述

  • PCA與Linear regression的區別

  1. 線性迴歸是左圖,將作圖點到直線距離最小化。PCA是右圖,即將點到垂直於直線的距離最小化。
  2. 線性迴歸是爲了預測某一個值,而在PCA當中,沒有某一個值是要被預測的,所有的特徵值都是被同等對待的。

在這裏插入圖片描述

(3) PCA應用

  1. 首先對數據進行預處理。將每個值轉換爲(實際值-該特徵值的均值)/該特徵值的標準差
    在這裏插入圖片描述

  2. 然後找到一條線或一個平面,對數據進行降維 在這裏插入圖片描述

  • 計算協方差
    在這裏插入圖片描述

  • 通過SVD得到矩陣U,計算UT*X,就可以都得到一個K維的數據
    在這裏插入圖片描述

(4) 壓縮重現

  • 用U*Z可以近似重現原始數據
    在這裏插入圖片描述

  • 如何選擇PCA的目標維數K

使得每個樣本點到映射點的距離方差/樣本點的方差<0.01(1%-5%)
在這裏插入圖片描述

或者使用S來計算。分子爲k個對角線的數的和, 分母爲對角線數之和。
在這裏插入圖片描述

(5) 使用PCA的建議

  1. 面對維數較多的數據時,首先提取沒有標籤的值,然後再使用PCA進行降維,計算U時只能通過訓練集來進行計算,然後可以使用到交叉驗證集和測試集上。
    在這裏插入圖片描述

3 代碼實戰

K-means

  1. 讀取數據
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sb
from scipy.io import loadmat

data = loadmat('E:/Data/Ng/Coursera-ML-AndrewNg-Notes-master/code/ex7-kmeans and PCA/data/ex7data2.mat')
X = data['X']
initial_centroids = np.array([[2,5],[2,2],[8,3]])#初始化聚類中心
  1. 相關函數
def init_centroids(X,k):
    """隨機初始化聚類中心點
    Params:
        X:原始數據
        k:簇數
    return:
        centroids:隨機初始化的聚類中心點"""
    m,n =X.shape
    index = np.random.randint(0,m,k) #從0到m內選擇k個值(對應的是X的索引)
    centroids = np.zeros((k,n))
    for i in range(k):#取k個聚類中心
        centroids[i,:] = X[index[i],:]
    return centroids

def find_closest_centroids(X,initial_centroids):
    """找到每個樣本點的離初始聚類中心點的最近距離,並進行分類
    Params:
        X:原始數據集
        initial_centrodis: 隨機初始化的聚類中心點
    return:
        index:存放每一個樣本對應類別標籤的列表"""
    m = X.shape[0]
    n = initial_centroids.shape[0]
    index = np.zeros(m)
    for i in range(m):
        min_dist = 1000000
        for j in range(n):
            dist = np.sum((X[i,:]-initial_centroids[j,:])**2)
            if dist < min_dist:
                min_dist = dist
                index[i] = j
    return index

def compute_centroids(X,index,k):
    """計算聚類中心點
    Params
        X : 原始數據
        index:存放每個樣本對應的類別標籤的列表
        k:類別總數
    return
        centroids:移動後的聚類中心點"""
    m,n = X.shape #獲取數據的特徵值數
    centroids = np.zeros((k,n)) #初始化聚類中心矩陣
    for i in range(k): #逐個極端聚類中心點
        indeices = np.where(index == i ) #找到index當中爲i的所有樣本的索引值
        centroids[i,:] = (np.sum(X[indeices,:],axis=1)/len(indeices[0])).ravel()
    return centroids

def run_k_means(X,initial_centroids,max_iter):
    """迭代找到每個樣本所屬的類別,以及最佳聚類中心
    Params:
        X:原始數據
        initial_centroids:初始化的聚類中心點
        max_iter:最大迭代次數
    return:
        index:存放每個樣本對應的類別標籤的列表
        centroids:最終的聚類中心點
        """
    m,n = X.shape
    index = np.zeros(m)
    k = initial_centroids.shape[0]
    centroids = initial_centroids
    for i in range(max_iter):
        index = find_closest_centroids(X,centroids)
        centroids = compute_centroids(X,index,k)
    return index,centroids

if __name__ ==  '__main__':
    initial_centroids = init_centroids(X,3)
    index,centroids = run_k_means(X,initial_centroids,50)
    cluster1 = X[np.where(index == 0)[0],:]
    cluster2 = X[np.where(index == 1)[0],:]
    cluster3 = X[np.where(index == 2)[0],:]
    fig,ax = plt.subplots(figsize = (12,8))
    ax.scatter(cluster1[:,0],cluster1[:,1],s = 30 ,color='orange',label='Cluster1')
    ax.scatter(cluster2[:,0],cluster2[:,1],s = 30 ,color='red',label='Cluster2')
    ax.scatter(cluster3[:,0],cluster3[:,1],s = 30 ,color='blue',label='Cluster3')
    plt.legend(loc=1)
    plt.show()

結果如下:

在這裏插入圖片描述

2 PCA

  1. 讀取數據,查看數據分佈:
data = loadmat('E:/Data/Ng/Coursera-ML-AndrewNg-Notes-master/code/ex7-kmeans and PCA/data/ex7data1.mat')
X= data['X']
fig, ax = plt.subplots(figsize=(12,8))
ax.scatter(X[:,0],X[:,1],s=60,color='red')
plt.show()

結果如下:
在這裏插入圖片描述

  1. 特徵值縮放,並計算sigma值,並獲取矩陣U

在這裏插入圖片描述
在這裏插入圖片描述

X_process = (X - X.mean())/X.std()
def sigma(data):
    m= data.shape[0]
    sigma = (data.T @ data)/m
    return sigma
cov=sigma(X_process)
U,S,V=np.linalg.svd(cov) #得到U
  1. 相關函數
def prepare_data(data):
    """數據預處理"""
    X = (data-data.mean())/data.std()
    return X

def sigma(X):
    X = np.mat(X)
    m = X.shape[0]
    return np.dot(X.T,X)

def pca(sigma):
    U,S,V=np.linalg.svd(sigma)
    return U,S,V

def project_data(X,U,k):
    U_reduce = U[:,k:]
    return np.dot(X,U_reduce)

def recover(z,U,k):
    U_reduce = U[:,:k]
    return np.dot(z,U_reduce.T)

if __name__ == '__main__':
	X_process=prepare_data(X)
	cov=sigma(X_process)
	U,S,V = pca(sigma)
	z = project_data(X,U,k)
	X_recover = recover(z,U,1)
	fig,ax = plt.subplots(figsize=(12,8))
	ax.scatter(list(X_recover[:,0]),list(X_recover[:,1]))
	plt.show()

在這裏插入圖片描述

參考資料:

  1. Ng機器學習
  2. 黃博筆記
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章