无监督学习是一种用于在数据中查找模式的机器学习技术. 提供给无监督算法的数据是没有标记的, 这意味着只给出输入变量 (X) 而没有相应的输出变量. 在无监督学习中, 算法自己来发现数据中有趣的结构.
人工智能研究主任 Yan Lecun 解释说, 无监督学习 -- 在不明确告诉他们所做的一切是对还是错的情况下教机器自我学习 -- 是 "真正的" 人工智能的关键所在.
监督学习 Vs 无监督学习.
在监督学习中, 系统试图从先前给出的示例中学习.(另一方面, 在无监督学习中, 系统会尝试直接从给定的示例中查找模式.)因此, 如果数据集被标记则为监督问题, 如果数据集未标记, 则是无监督问题.
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']
紫色: Setosa, 绿色: Versicolor, 黄色: Virginica
聚类
在群集中, 数据分为几组. 简而言之, 目的是将具有相似特征的群体分开并将其分配到对应的群集中.
可视化的例子,
在上图中, 左边的图像是未进行分类的原始数据, 右边的图像是聚类的(数据根据其特征进行分类). 当给出要预测的输入时, 它根据它的特征检查它所属的群集, 并进行预测.
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()
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()
紫色: 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()
更多无监督技术:
主成分分析 (PCA)
异常检测
自动编码
深度信念网络
赫布型学习
生成式对抗网络(GANs)
自组织映射
重要链接:
Python 中的监督学习算法.
用 Python 进行监督学习: 为什么是人工智能和机器学习
机器学习简介: 机器学习是一个从实例和经验中进行学习的思想, 它没有明确编程方法.
使用 Python 进行深度学习: 模仿人类的大脑.
用于深度学习的线性代数: 每个深度学习程序背后的数学.
后记
来源: https://juejin.im/post/5bab10ed6fb9a05d1f2211b6