python 機器學習(一)無監督學習 + 監督學習 + 聚類算法 + k-means算法自實現

一、機器學習


1. 概念


在歷史數據中去發現規律,然後利用規律,在新的數據中進行預測、與指導


2. 人工智能基礎(數據分析、數據挖掘)


如果想要一個好的機器學習結果,就必須有一個好的數據處理


3. 數據分析、與數據挖掘的區別


  • 數據分析主要偏向於業務(是對數據的一種操作手段)
    是指用適當的統計分析方法對收集來的大量數據進行分析,提取有用信息和形成結論而對數據加以詳細研究和概括總結的過程。
  • 數據挖掘主要偏向於對數據價值的挖掘(是對數據分析手段後的信息,進行價值化的分析)
    又譯爲資料探勘、數據採礦。它是數據庫知識發現中的一個步驟。數據挖掘一般是指從大量的數據中通過算法搜索隱藏於其中信息的過程。

4. 無監督學習


根據類別未知(沒有被標記)的訓練樣本解決模式識別中的各種問題,稱之爲無監督學習。

特點:

  • 數據:無目標值數據
  • 研究:研究的是樣本與樣本之間的關係

5, 監督學習


利用一組已知類別的樣本調整分類器的參數,使其達到所要求性能的過程;監督學習是從標記的訓練數據來推斷一個功能的機器學習任務。
在監督學習中,每個實例都是由一個輸入對象(通常爲矢量)和一個期望的輸出值(也稱爲監督信號)組成。

特點:

  • 數據:既有特徵值,又有目標值
  • 研究:研究的是特徵與目標之間的關係

6. 無監督學習和監督學習的區別


  1. 監督學習方法必須要有訓練集與測試樣本。在訓練集中找規律,而對 測試樣本使用這種規律。而非監督學習沒有訓練集,只有一組數據,在該 組數據集內尋找規律。
  2. 監督學習的方法就是識別事物,識別的結果表現在給待識別數據加上 了標籤。因此訓練樣本集必須由帶標籤的樣本組成。而無監督學習方法只 知 有要分析的數據集的本身,預先沒有什麼標籤。如果發現數據集呈現某種 識 聚集性,則可按自然的聚集性分類,但不予以某種預先分類標籤對上號爲 講解 目的。

何時使用:

簡單的方法就是從定義入手,有訓練樣本則考慮採用監督學習方法;無 訓練樣本,則一定不能用監督學習方法。但是,現實問題中,即使沒有訓 練樣本,我們也能夠憑藉自己的雙眼,從待分類的數據中,人工標註一些 樣本,並把它們作爲訓練樣本,這樣的話,可以把條件改善,用監督學習 方法來做。對於不同的場景,正負樣本的分佈如果會存在偏移(可能大的 偏移,可能比較小),這樣的話,監督學習的效果可能就不如用非監督學 習了。


7. 聚類算法


聚類分析是一種分類的多元統計分析方法。按照個體或樣品的特徵將它們 分類,使同一類別內的個體具有儘可能高的同質性(homogeneity),而不同類別 之間則應具有儘可能高的異質性(heterogeneity)。

利用樣本的特徵,使最終的結果,同一類別內的樣本具有較高的相似性,不同類別的樣本具有較高相異性
其利用的就是k-means算法

  • k-means算法原理
    在這裏插入圖片描述

8. k-means算法自實現


import numpy as np  ## 科學計算庫
import matplotlib.pyplot as plt  ## 數據可視化庫
import pandas as pd  ## 數據處理庫

def built_data():
    """
    構建數據
    :return: 數據
    """
    # 加載數據
    # 1. open
    # 2. np.loadtxt np.genfromtxt
    # 3. pandas.read_table
    # 參數1 文件路徑 + 名稱
    # delimiter sep 都可以指定分隔符
    data = pd.read_table('test.txt',sep='\t',header=None)

    # 將data轉換爲矩陣
    data = np.mat(data.values)
    return data

def center_init(data,k):
    """
    聚類中心初始化
    :param data: 數據
    :param k: 聚類的類別數目
    :return: center
    """

    # 隨機選擇所有樣本中的四個樣本作爲最開始的聚類中心
    # 隨機選取四個聚類中心 行的範圍
    index_num = data.shape[0]
    # 確定隨機四核聚類中心的列數
    column_num = data.shape[1]
    # 初始化一個全爲0的聚類中心數組
    center = np.zeros(shape=(k,column_num))
    # 定義一個計數器,計4次
    i = 0
    # 創建一個列表
    r_list = []
    while True:
        # 隨機選取行下標
        r = np.random.randint(low=0,high=index_num)
		# 創建一個r列表,選取四個不重複的聚類中心
        if r not in r_list:
            # 對聚類中心進行賦值
            r_list.append(r)
            # 四行替換爲隨機的行作爲聚類中心
            center[i,:]=data[r,:]
        else:
            continue
        # 初始化中心的退出條件
        if len(r_list) == k:
            break
        i += 1
    return center

def distance(v1,v2):
    """
    距離運算
    :param v1: 點1
    :param v2: 點2
    :return: 距離
    """
    # 方法1:
    # 計算距離
    # sum_ = 0
    # # 將v1由二維降爲1維(2,)
    # # 將矩陣轉換爲數組
    # # 矩陣視圖 ----------矩陣.A -----------》數組
    # v1 = v1.A[0]
    # if v1.shape == v2.shape:
    #     for i in range(len(v1)):
    #         sum_ += (v1[i]-v2[i])**2
    # dist = np.sqrt(sum_)

    # 方法2
    dist = np.sqrt(np.sum(np.power((v1-v2),2)))
    return dist

def k_means_owns(data,k):
    """
    # 自實現k-means原理
    :param data: 數據
    :param k: 聚類的類別數目
    :return: None
    """
    # 初始化聚類中心----隨機初始化
    # 隨機在所有樣本中選取四個聚類中心
    center = center_init(data,k)
    # 確定距離最近以及距離該聚類中心的距離數組的行數(應該是每個數據都有一個最小距離)
    index_num = data.shape[0]

    # 定義一個數組來保存 該樣本最近的聚類中心以及距離該聚類中心的距離
    # 初始化全爲0
    new_data = np.zeros(shape=(index_num,2))
    flag = True
    while flag:
        flag = False
    # 計算每一個訓練樣本與聚類中心的距離
    ## 雙層循環 -- 外層 -- 訓練樣本
    #              內層 -- 聚類中心
        for i in range(index_num):
            min_dist = 10000000000000
            min_index = -1
            for j in range(k):
            ## 計算距離
            # 高維度的數組使用下標 會降維
            # 矩陣是特殊的二維數組
                dist = distance(data[i,:],center[j,:])
                # print(dist)
                if dist < min_dist:
                    min_dist = dist
                    min_index = j
            # 如果當前計算的樣本屬於聚類中心的類別與上次不一致
            if new_data[i,0] != min_index:
                flag = True
                new_data[i,:] = min_index,min_dist

        if flag:
            # 計算新的聚類中心
            # 計算每一簇的均值 --- 每一簇的中心
            for p in range(k):
                # 返回布爾數組
                bool_index = new_data[:,0] == p
                # print(bool_index)
                # 選定簇;選定k所對應索引的行
                p_cluster = data[bool_index,:]

                # 新的聚類中心
                center[p,:] = p_cluster[:,0].mean(),p_cluster[:,1].mean()
            # 如果新的聚類中心與上一次的聚類中心重合----結束
            # 如果這一次 所有樣本所屬的聚類中心 與上一次 所有樣本所屬的聚類中心的類別 一致 ---- 結束

    return new_data,center

def show_res_owns(data,new_data,center):
    """
    結果展示
    :param data: 原始數據
    :param new_data: 保存着各個樣本最終的類別
    :param center: 最終的聚類中心
    :return: None
    """
    # 1. 創建畫布
    plt.figure()
    # 需要更改RC參數讓其支持中文
    plt.rcParams['font.sans-serif'] = 'SimHei' # 影響負號,需要加下面的
    plt.rcParams['axes.unicode_minus'] = False


    # 設置顏色列表
    c_list = ['r','g','y','pink']
    marker_list = ['*','o','d','D']
    # 2. 繪圖
    for i in range(data.shape[0]):
        # 繪製散點圖
        plt.scatter(data[i,0],data[i,1],c=c_list[int(new_data[i,0])],marker=marker_list[int(new_data[i,0])])
    # 繪製聚類中心
    plt.plot(center[:,0],center[:,1],'bx',markersize=12)
    # 增加名稱
    plt.title("聚類結果展示")
    # 保存圖片
    plt.savefig("聚類結果.png")
    # 3. 展示
    plt.show()

def main():
    # 第一步:構建數據
    data = built_data() # 返回一個矩陣
    # print("data:\n",data)
    # print("data的類型:\n",type(data))
    # print("data的數據類型:\n",data.dtype)

    # 第二步:自實現k-means算法原理
    # 確定聚類的類別數目
    k = 4
    new_data, center = k_means_owns(data,k)


    # 第三步:結果展示
    show_res_owns(data,new_data,center)


if __name__ == '__main__':
    main()

9. KMeans算法實現聚類


import numpy as np  ## 科學計算庫
import matplotlib.pyplot as plt  ## 數據可視化庫
import pandas as pd  ## 數據處理庫
from sklearn.cluster import KMeans # KMeans算法

def built_data():
    """
    構建數據
    :return: 數據
    """
    data = pd.read_table('test.txt',sep='\t',header=None)
    # 將data轉換爲矩陣
    data = np.mat(data.values)
    return data


def show_res(data,y_predict,center):
    """
    結果展示
    :param data: 原始數據
    :param new_data: 樣本的預測類別
    :param center: 最終的聚類中心
    :return: None
    """
    # 1. 創建畫布
    plt.figure()
    # 需要更改RC參數讓其支持中文
    plt.rcParams['font.sans-serif'] = 'SimHei' # 影響負號,需要加下面的
    plt.rcParams['axes.unicode_minus'] = False

    # 設置顏色列表
    c_list = ['r','g','y','pink']
    marker_list = ['*','o','d','D']
    # 2. 繪圖
    for i in range(data.shape[0]):
        # 繪製散點圖
        plt.scatter(data[i,0],data[i,1],c=c_list[y_predict[i]],marker=marker_list[y_predict[i]])
    # 繪製聚類中心
    plt.plot(center[:,0],center[:,1],'bx',markersize=12)
    # 增加名稱
    plt.title("聚類結果展示")
    # 3. 展示
    plt.show()

def main():
    # 第一步:構建數據
    data = built_data() # 返回一個矩陣

    # 2. 使用sllearn中的KMeans進行聚類分析
    # 確定聚類的類別數目
    k = 4
    # (1)構建算法實例
    # n_clusters指定聚類的類別
    km = KMeans(n_clusters=k)
    # (2)進行訓練數據
    km.fit(data)
    # (3)驗證模型的好壞-----即得到預測值
    y_predict = km.predict(data)
    # K-means 算法----聚類中心
    center = km.cluster_centers_
    print("預測類別:\n",y_predict)
    print("聚類中心:\n",center)

    # 3. 結果可視化
    show_res(data,y_predict,center)


if __name__ == '__main__':
    main()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章