[譯] Python 中的無監督學習演算法

趙小生發表於2018-09-26

無監督學習是一種用於在資料中查詢模式的機器學習技術。提供給無監督演算法的資料是沒有標記的,這意味著只給出輸入變數(X)而沒有相應的輸出變數。在無監督學習中,演算法自己來發現資料中有趣的結構。

[譯] Python 中的無監督學習演算法

人工智慧研究主任 Yan Lecun 解釋說,無監督學習 —— 在不明確告訴他們所做的一切是對還是錯的情況下教機器自我學習 —— 是“真正的”人工智慧的關鍵所在。

監督學習 Vs 無監督學習。

在監督學習中,系統試圖從先前給出的示例中學習。(另一方面,在無監督學習中,系統會嘗試直接從給定的示例中查詢模式。)因此,如果資料集被標記則為監督問題,如果資料集未標記,則是無監督問題。

[譯] Python 中的無監督學習演算法

src

上面的影象是監督學習的一個例子; 我們使用迴歸演算法找到特徵之間的最佳擬合線。在無監督學習中,輸入的資料以特徵為基礎而被分隔成不同的群集,並且預測它所屬的群集。

重要術語

Feature: 用於進行預測的輸入變數。

Predictions: 輸入示例時的模型輸出。

Example: 一行資料集。一個 example 包含一個或多個特徵以及可能的標籤。

Label: 特徵結果。

無監督學習資料準備

在本文中,我們使用鳶尾花(Iris)資料集進行第一次預測。資料集包含一組有 150 個記錄的集合,擁有 5 個屬性 —— 花瓣長度、花瓣寬度、萼片長度、萼片寬度和類別。Iris Setosa、Iris Virginica 和 Iris Versicolor 是這三個類別。在我們的無監督演算法中,我們給出了鳶尾花的這四個特徵並預測它屬於哪個類別。

我們使用 Python 中的 sklearn 庫來載入鳶尾花資料集,使用 matplotlib 庫來實現資料視覺化。以下是用於研究資料集的程式碼段。

# 引入模組
from sklearn import datasets
import matplotlib.pyplot as plt

# 載入資料集
iris_df = datasets.load_iris()

# 資料集上的可用方法
print(dir(iris_df))

# 特徵
print(iris_df.feature_names)

# 目標
print(iris_df.target)

# 目標名稱
print(iris_df.target_names)
label = {0: 'red', 1: 'blue', 2: 'green'}

# 資料集切片
x_axis = iris_df.data[:, 0]  # Sepal Length
y_axis = iris_df.data[:, 2]  # Sepal Width

# 繪製
plt.scatter(x_axis, y_axis, c=iris_df.target)
plt.show()
複製程式碼
['DESCR', 'data', 'feature_names', 'target', 'target_names']
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']

[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]

['setosa' 'versicolor' 'virginica']
複製程式碼

[譯] Python 中的無監督學習演算法

紫色:Setosa,綠色: Versicolor,黃色:Virginica

聚類

在群集中,資料分為幾組。簡而言之,目的是將具有相似特徵的群體分開並將其分配到對應的群集中。

視覺化的例子,

[譯] Python 中的無監督學習演算法

在上圖中,左邊的影象是未進行分類的原始資料,右邊的影象是聚類的(資料根據其特徵進行分類)。當給出要預測的輸入時,它根據它的特徵檢查它所屬的群集,並進行預測。

Python 中的 K-均值 聚類演算法

K 均值是一種迭代聚類演算法,旨在在每次迭代中找到區域性最大值。最初選擇所需數量的群集。由於我們知道涉及 3 個類別,因此我們將演算法程式設計為將資料分組為 3 個類別,方法是將引數 “n_clusters” 傳遞給我們的 K 均值模型。現在隨機將三個點(輸入)分配到三個群集中。基於每個點之間的質心距離,下一個給定的輸入被分配到相應的群集。現在,重新計算所有群集的質心。

群集的每個質心都是一組特徵值,用於定義結果組。檢查質心特徵權重可用於定性地解釋每個群集代表什麼型別的組。

我們從 sklearn 庫匯入 K 均值模型,擬合特徵並預測。

Python 中的 K 均值演算法實現。

# 引入模組
from sklearn import datasets
from sklearn.cluster import KMeans

# 載入資料集
iris_df = datasets.load_iris()

# 宣告模型
model = KMeans(n_clusters=3)

# 擬合模型
model.fit(iris_df.data)

# 預測單個輸入
predicted_label = model.predict([[7.2, 3.5, 0.8, 1.6]])

# 預測整個資料
all_predictions = model.predict(iris_df.data)

# 列印預測結果
print(predicted_label)
print(all_predictions)
複製程式碼
[0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 1 1 1 2 1 1 1 1 1 1 2 2 1 1 1 1 2 1 2 1 2 1 1 2 2 1 1 1 1 1 2 1 1 1 1 2 1 1 1 2 1 1 1 2 1 1 2]
複製程式碼

分層聚類

顧名思義,分層聚類是一種構建聚類層次結構的演算法。該演算法從分配給自己的群集的所有資料開始。然後將兩個最接近的群集合併到同一群集中。最後,當只剩下一個群集時,該演算法結束。

可以使用樹形圖顯示分層聚類的完成過程。現在讓我們看一下穀物資料的層次聚類的例子。資料集可以在這裡找到。

Python 中分層聚類演算法的實現。

# 引入模組
from scipy.cluster.hierarchy import linkage, dendrogram
import matplotlib.pyplot as plt
import pandas as pd

# 讀入 DataFrame
seeds_df = pd.read_csv(
    "https://raw.githubusercontent.com/vihar/unsupervised-learning-with-python/master/seeds-less-rows.csv")

# 從 DataFrame 中刪除穀物種類,稍後再儲存
varieties = list(seeds_df.pop('grain_variety'))

# 將測量值提取為 NumPy 陣列
samples = seeds_df.values

"""
使用帶有 method ='complete' 關鍵字引數的
linkage()函式對樣本執行分層聚類。
將結果合併。
"""
mergings = linkage(samples, method='complete')

"""
在合併時使用 dendrogram() 函式繪製樹形圖,
指定關鍵字引數 labels = varieties,leaf_rotation = 90 
和 leaf_font_size = 6。
"""
dendrogram(mergings,
           labels=varieties,
           leaf_rotation=90,
           leaf_font_size=6,
           )

plt.show()
複製程式碼

[譯] Python 中的無監督學習演算法

K 均值和分層聚類之間的差異

  • 分層聚類不能很好地處理大資料,但 K 均值聚類可以。這是因為 K 均值的時間複雜度是線性的,即 O(n),而分層聚類的時間複雜度是二次的,即 O(n2)。
  • 在 K 均值聚類中,當我們從任意選擇的聚類開始時,通過多次執行演算法生成的結果可能會有所不同。然而在分層聚類中結果是可重現的。
  • 當群集的形狀是超球形時(如 2D 中的圓圈,3D 中的球體),我們發現 K 均值工作良好。
  • K-均值不允許噪聲資料,而在分層聚類中我們可以直接使用噪聲資料集進行聚類。

t-SNE聚類

它是視覺化的無監督學習方法之一。t-SNE 代表 t 分佈的隨機嵌入鄰域。它將高維空間對映到可以視覺化的 2 維或 3 維空間。具體地,它通過二維或三維點對每個高維物件建模,使得相似物件由附近點建模,而非相似物件由遠點以高概率建模。

用於鳶尾花資料集的 Python 中的 t-SNE 聚類實現

# 引入模組
from sklearn import datasets
from sklearn.manifold import TSNE
import matplotlib.pyplot as plt

# 載入資料集
iris_df = datasets.load_iris()

# 定義模型
model = TSNE(learning_rate=100)

# 擬合模型
transformed = model.fit_transform(iris_df.data)

# 繪製二維的 t-Sne
x_axis = transformed[:, 0]
y_axis = transformed[:, 1]

plt.scatter(x_axis, y_axis, c=iris_df.target)
plt.show()
複製程式碼

[譯] Python 中的無監督學習演算法

紫色:Setosa,綠色:Versicolor,黃色:Virginica

這裡,由於鳶尾花資料集具有四個特徵(4d),因此它被轉換並以二維圖形表示。類似地,t-SNE 模型可以應用於具有 n 個特徵的資料集。

DBSCAN 聚類

DBSCAN(具有噪聲的基於密度的聚類方法)是一種流行的聚類演算法,用於替代預測分析中的 K 均值。它不需要輸入群集的數量就能執行。但是,你必須調整另外兩個引數。

scikit-learn 實現提供了 eps 和 min_samples 引數的預設值,但是你通常需要調整這些引數。eps 引數是要在同一鄰域中考慮的兩個資料點之間的最大距離。min_samples 引數是鄰域中被視為群集的資料點的最小數量。

Python 中的 DBSCAN 聚類

# 引入模組
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
from sklearn.cluster import DBSCAN
from sklearn.decomposition import PCA

# 載入資料集
iris = load_iris()

# 宣告模型
dbscan = DBSCAN()

# 擬合
dbscan.fit(iris.data)

# 使用PCA進行轉換
pca = PCA(n_components=2).fit(iris.data)
pca_2d = pca.transform(iris.data)

# 基於類別進行繪製
for i in range(0, pca_2d.shape[0]):
    if dbscan.labels_[i] == 0:
        c1 = plt.scatter(pca_2d[i, 0], pca_2d[i, 1], c='r', marker='+')
    elif dbscan.labels_[i] == 1:
        c2 = plt.scatter(pca_2d[i, 0], pca_2d[i, 1], c='g', marker='o')
    elif dbscan.labels_[i] == -1:
        c3 = plt.scatter(pca_2d[i, 0], pca_2d[i, 1], c='b', marker='*')

plt.legend([c1, c2, c3], ['Cluster 1', 'Cluster 2', 'Noise'])
plt.title('DBSCAN finds 2 clusters and Noise')
plt.show()
複製程式碼

[譯] Python 中的無監督學習演算法

更多無監督技術:

  • 主成分分析 (PCA)
  • 異常檢測
  • 自動編碼
  • 深度信念網路
  • 赫布型學習
  • 生成式對抗網路(GANs)
  • 自組織對映

重要連結:

Python 中的監督學習演算法.

後記

感謝閱讀。如果你發現這篇文章有用,請點選下面的 ❤️ 來傳遞愛吧。

如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章