本章概述

本章将带你进入数据分析的奇妙世界 🌍!我们将学习如何使用 Python 中两个超级强大的工具:Pandasscikit-learn,来实现各种数据分析任务。

注记

内容概要:

  • 🗂️ 分类方法: 像侦探一样🕵️‍♀️,把数据分门别类 (例如:识别不同种类的动物 🐶🐱🐰)
  • 📈 回归方法: 像预言家一样🔮,预测未来 (例如:预测股票价格 💸)
  • 🤝 聚类方法: 像组织者一样🧑‍🤝‍🧑,把相似的东西聚集起来 (例如:市场细分,把顾客分成不同的群体 🎯)

我们将深入探讨这些技术背后的奥秘,并通过有趣的案例来演示它们的神奇应用!

📚 核心概念

在开始我们的探险之前,让我们先来认识一些重要的伙伴:

  • Pandas: Python 数据分析的瑞士军刀🇨🇭!它提供了 DataFrame 数据结构,让我们可以像操作 Excel 表格一样轻松处理数据。

    • 💡 就像一个超级 Excel 表格,可以进行数据清洗、转换、分析等操作。可以对数据进行排序、筛选、分组、聚合等操作。
  • scikit-learn: 机器学习的百宝箱🧰!它提供了各种分类、回归、聚类算法,以及模型评估、选择等工具。

    • 🤖️ 就像一个机器学习工具箱,包含了各种常用的算法和工具。可以用来构建预测模型、进行数据挖掘等。

📚 核心概念

  • 分类 (Classification): 将数据划分到不同的类别中。

    • 🍎🍊 将水果分成苹果和橘子。
    • 📧 垃圾邮件识别:将邮件分成垃圾邮件和正常邮件。
  • 回归 (Regression): 预测一个连续值。

    • 📈 预测明天的气温。
    • 🏠 房价预测:根据房屋的特征(面积、位置等)预测房价。
  • 聚类 (Clustering): 将相似的数据点分组到一起。

    • 👥 将客户分成不同的群体,以便进行更有针对性的营销。
    • 📰 新闻主题分类:将新闻文章按照主题进行分组。

📚 核心概念

  • Python: 一种流行的编程语言,以其易学性和强大的数据科学生态系统而闻名。
    • 🐍 是一种解释型、高级和通用的编程语言。
    • Python 由 Guido van Rossum 创建,并于 1991 年首次发布。
    • Python 的设计哲学强调代码的可读性和简洁的语法 (尤其是使用空格缩进来划分代码块,而不是使用大括号或关键字)。
    • Python 支持多种编程范式,包括面向对象、命令式、函数式和过程式编程。

📚 核心概念

  • 信息技术(Information Technology, IT):指的是利用计算机、网络、通信等技术来处理、管理和传输信息的领域。广义上,IT涵盖了硬件、软件、数据和通信等多个方面。
    • 🌐 IT是现代社会的基础设施,支持着各行各业的运作。
    • IT 的应用非常广泛,包括但不限于:
      • 数据存储和管理
      • 软件开发和应用
      • 网络和通信
      • 信息安全
      • 人工智能和机器学习

7.1 分类方法

分类方法就像一个智能分类器,能够将不同类型的数据区分开来。让我们来看看有哪些神奇的分类器吧!

Logistic 回归

  • 实现:
    • sklearn.linear_model.LogisticRegression
  • 支持:
    • 二分类 (binary) 🎯:判断是或否 (例如:是否患病)
    • 一对多分类 (one vs rest) 🥊:多个类别中选择一个 (例如:识别手写数字 0-9)
    • 多项式回归 ➕:处理非线性关系
    • 可以选择 L1 或 L2 正则化 💪:防止模型过拟合

Logistic 回归:概念解释

  • Logistic Regression: 是一种广义的线性回归分析模型,虽然名字里有“回归”,但实际上是用来解决分类问题的。它通过一个叫做 Sigmoid 的函数,将线性回归的输出映射到 0 到 1 之间,表示属于某一类的概率。
    • 📌 例如:判断一封邮件是否为垃圾邮件。

Sigmoid 函数

Sigmoid 函数,也称为逻辑函数,是一个 S 形曲线,其数学表达式为:

\[ \sigma(z) = \frac{1}{1 + e^{-z}} \]

其中:

  • \(z\) 是输入值(可以是任意实数)。
  • \(e\) 是自然对数的底数(欧拉数,约等于 2.71828)。
  • \(\sigma(z)\) 是输出值,范围在 0 到 1 之间。

Sigmoid函数的图像如下:

代码
import matplotlib.pyplot as plt
import numpy as np

def sigmoid(x):
  return 1 / (1 + np.exp(-x))

x = np.linspace(-10, 10, 100)
y = sigmoid(x)

plt.figure(figsize=(6, 4))
plt.plot(x, y)
plt.title('Sigmoid Function')
plt.xlabel('x')
plt.ylabel('sigmoid(x)')
plt.grid(True)
plt.show()
图 1: Sigmoid 函数图像

Sigmoid 函数的性质

  • S 形曲线: Sigmoid 函数的图形呈 S 形,将输入值映射到 (0, 1) 的区间内。
  • 概率解释: 输出值可以被解释为概率,表示样本属于某一类的可能性。
  • 可微性: Sigmoid 函数是可微的,这使得它在梯度下降等优化算法中非常有用。
  • 非线性: Sigmoid 函数是非线性的,这使得逻辑回归可以处理非线性关系。

Logistic 回归中的正则化

  • 正则化 (Regularization): 一种防止模型过拟合的技术。模型过拟合指的是模型在训练数据上表现很好,但在新数据上表现很差。
    • L1 正则化: 倾向于产生稀疏的模型 (很多参数为 0),可以用来进行特征选择。
      • L1 正则化通过向损失函数添加参数向量的 L1 范数(绝对值之和)的惩罚项来实现。
    • L2 正则化: 倾向于产生参数值较小的模型,可以提高模型的泛化能力。
      • L2 正则化通过向损失函数添加参数向量的 L2 范数(平方和的平方根)的惩罚项来实现。

Logistic回归solver选择

Case Solver
L1 正则 “liblinear”, “saga”
多项式损失 (multinomial loss) “lbfgs”, “sag”, “saga”, “newton-cg”
大数据集 (n_samples) “sag”, “saga”

Logistic回归solver选择

  • liblinear:
    • 应用了坐标下降算法(Coordinate Descent),基于 C++ 库实现,速度较快。
    • 对于小数据集和二分类问题,liblinear 是一个不错的选择。
    • 不是真正意义上的多分类模型,而是基于“one-vs-rest”思想,为每个类别训练了一个二元分类器。
  • lbfgs, sagnewton-cg:
    • 只支持 L2 惩罚项,对某些高维数据收敛更快。
    • lbfgs 是一种拟牛顿法(Quasi-Newton method),适用于中小型数据集。
    • newton-cg 是一种牛顿法(Newton’s method),需要计算海森矩阵(Hessian matrix),适用于特征维度较少的数据集。
    • sag (Stochastic Average Gradient) 是一种随机平均梯度下降算法,适用于大型数据集。
    • 参数 multi_class 设为 “multinomial” 即为真正的分类,其预测比 liblinear 更为准确。

Logistic回归solver选择

  • sag:
    • 基于平均随机梯度下降算法(Stochastic Average Gradient descent)。
    • 在大数据集上的表现更快,大数据集指样本量大且特征数多。
  • saga:
    • sag 的变体,它支持非平滑的 L1 正则选项 penalty="l1"
    • 对于稀疏多项式 logistic 回归效果较好。
    • saga 也适用于大型数据集。

Logistic回归代码示例

import numpy as np
from sklearn import linear_model, datasets

# 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris.data
Y = iris.target

# 创建 LogisticRegression 对象,并设置 solver 为 'liblinear'
log_reg = linear_model.LogisticRegression(solver='liblinear')

# 使用 fit 方法训练模型
log_reg.fit(X, Y)

# 使用 predict 方法对新的数据点进行预测
print(log_reg.predict([[5.1, 3.5, 1.4, 0.2]])) # 预测结果为类别 0 (Setosa)

# 预测概率
print(log_reg.predict_proba([[5.1, 3.5, 1.4, 0.2]])) # 第一个类别的概率最高
[0]
[[8.78030305e-01 1.21958900e-01 1.07949250e-05]]

Logistic回归代码示例:代码解释

  1. 导入必要的库
    • numpy 用于数值计算。
    • sklearn 中的 linear_model 用于逻辑回归。
    • datasets 用于加载示例数据集。
  2. 加载 iris 数据集:这是一个常用的数据集,包含了三种不同类型的鸢尾花(Setosa, Versicolour, Virginica)的萼片和花瓣的长度和宽度。
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) target species
0 5.1 3.5 1.4 0.2 0.0 setosa
1 4.9 3.0 1.4 0.2 0.0 setosa
2 4.7 3.2 1.3 0.2 0.0 setosa
3 4.6 3.1 1.5 0.2 0.0 setosa
4 5.0 3.6 1.4 0.2 0.0 setosa

Logistic回归代码示例:代码解释

  1. 将数据集分为特征 X (萼片和花瓣的长度和宽度) 和目标 Y (鸢尾花的种类)。
  2. 创建一个 LogisticRegression 对象,并设置 solver 参数为 'liblinear'
  3. 使用 fit 方法训练模型。
  4. 使用 predict 方法对新的数据点 [5.1, 3.5, 1.4, 0.2] 进行预测。
  5. predict_proba 方法返回的是一个数组,数组中的每一个数字分别代表属于每一个类别的概率。

SVM (支持向量机)

  • 实现:
    • sklearn.svm.SVC():C-支持向量分类。
    • sklearn.svm.NuSVC():Nu-支持向量分类。
    • sklearn.svm.LinearSVC():线性支持向量分类。
  • 区别:
    • SVCNuSVC 比较接近,两者参数略有不同。SVC 使用参数 C 来控制正则化强度,而 NuSVC 使用参数 nu 来控制支持向量的数量。
    • LinearSVC 仅支持线性核函数的分类,速度更快,适用于大规模数据集。

SVM:概念解释

  • SVM: 一种强大的分类算法,它试图找到一个最佳的超平面,将不同类别的数据分隔开。这个超平面被称为“决策边界”。
    • 🗂️ 就像在不同类别的数据之间画一条线 (或者在高维空间中画一个平面、超平面),使得不同类别的数据点到这条线的距离尽可能远。
  • 支持向量 (Support Vectors): 离决策边界最近的那些数据点,它们决定了决策边界的位置。

SVM:核函数

  • 核函数 (Kernel Function): 将数据映射到更高维空间,使得数据更容易被分隔。常用的核函数有:
    • 线性核函数 (Linear Kernel): 不做任何映射,直接在原始空间中寻找超平面。
    • 多项式核函数 (Polynomial Kernel): 将数据映射到多项式空间。
    • 径向基核函数 (RBF Kernel): 将数据映射到无限维空间。
  • 支持向量机的目标是找到能够最大化类别之间边距的超平面,从而提高分类的准确性和鲁棒性。它特别适用于高维空间的数据分类问题。

SVM 代码示例

import numpy as np
from sklearn import svm, datasets

# 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris.data
Y = iris.target

# 创建 SVC 对象,并设置 kernel 为 'rbf' (径向基核函数)
clf1 = svm.SVC(kernel='rbf')

# 创建 NuSVC 对象
clf2 = svm.NuSVC()

# 创建 LinearSVC 对象
clf3 = svm.LinearSVC(max_iter=10000)

# 使用 fit 方法训练模型
clf1.fit(X, Y)
clf2.fit(X, Y)
clf3.fit(X, Y)

# 使用 predict 方法对新的数据点进行预测
print(clf1.predict([[5.1, 3.5, 1.4, 0.2]])) # 预测结果为类别 0 (Setosa)
print(clf2.predict([[5.1, 3.5, 1.4, 0.2]])) # 预测结果为类别 0 (Setosa)
print(clf3.predict([[5.1, 3.5, 1.4, 0.2]])) # 预测结果为类别 0 (Setosa)
[0]
[0]
[0]

SVM:支持向量的获取

  • support_vectors_: 全部支持向量
  • support_: 支持向量在原始数据集中的索引
  • n_support: 各类别的支持向量的数量 (LinearSVC 不支持)
# 获取支持向量
print(clf1.support_vectors_)

# 获取支持向量的索引
print(clf1.support_)

# 获取各类别的支持向量的数量
print(clf1.n_support_)

Nearest Neighbors (最近邻)

  • 实现:
    • sklearn.neighbors.KNeighborsClassifier():K-近邻分类器。
    • sklearn.neighbors.RadiusNeighborsClassifier():半径近邻分类器。
  • 区别:
    • KNeighborsClassifier: 基于每个查询点的 k 个最近邻实现。对于一个新的数据点,找到离它最近的 k 个训练数据点,然后根据这 k 个点的类别进行投票,票数最多的类别就是新数据点的预测类别。
      • k 是用户指定的整数值,通常需要通过交叉验证等方法来选择最佳的 k 值。
    • RadiusNeighborsClassifier: 基于每个查询点的固定半径 r 内的邻居数量实现。对于一个新的数据点,找到所有离它距离小于等于 r 的训练数据点,然后根据这些点的类别进行投票,票数最多的类别就是新数据点的预测类别。
      • 其中 r 是用户指定的浮点数值,需要根据数据的分布情况来选择合适的 r 值。

Nearest Neighbors:概念解释

  • Nearest Neighbors: 一种简单且直观的分类算法,它基于“物以类聚”的思想。对于一个新的数据点,找到离它最近的训练数据点(即“邻居”),然后根据这些邻居的类别来预测新数据点的类别。
    • 🚶 就像根据你周围的人群来判断你属于哪个群体。如果你周围大部分人都是医生,那么你很可能也是医生。

Nearest Neighbors 参数

  • n_neighborsradius 参数:设置 k、r 值
  • weights 参数:对近邻进行加权。不同的权重策略会影响预测结果。
    • uniform: 各个“邻居”权重相等。每个邻居对预测结果的贡献相同。
    • distance: 按照距离给各个“邻居”权重,较近点产生的影响更大。距离越近的邻居对预测结果的贡献越大。
    • 自定的函数:可以自定义一个函数,根据距离或其他因素来计算权重。
  • algorithm 参数:指定查找最近邻算法。不同的算法适用于不同的数据规模和维度。
    • ball_tree: 使用球树 (Ball Tree) 数据结构,适用于高维数据。
    • kd_tree: 使用 KD 树 (K-D Tree) 数据结构,适用于低维数据。
    • brute: 使用暴力搜索 (Brute-Force Search),对每个查询点都计算与所有训练数据点的距离,适用于小规模数据集。
    • auto: 自动选择最合适的算法。

Nearest Neighbors 代码示例

import numpy as np
from sklearn import neighbors, datasets

# 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris.data
Y = iris.target

# 创建 KNeighborsClassifier 对象,并设置 n_neighbors 为 5
kclf = neighbors.KNeighborsClassifier(n_neighbors=5)

# 创建 RadiusNeighborsClassifier 对象,并设置 radius 为 1.0
rclf = neighbors.RadiusNeighborsClassifier(radius=1.0)

# 使用 fit 方法训练模型
kclf.fit(X, Y)
rclf.fit(X, Y)

# 使用 predict 方法对新的数据点进行预测
print(kclf.predict([[5.1, 3.5, 1.4, 0.2]])) # 预测结果为类别 0 (Setosa)
print(rclf.predict([[5.1, 3.5, 1.4, 0.2]])) # 预测结果为类别 0 (Setosa)
[0]
[0]

Decision Tree (决策树)

  • 实现:

    • sklearn.tree.DecisionTreeClassifier()
  • 概念解释:

    • Decision Tree: 决策树是一种树状结构的分类算法,它通过一系列的 if-else 问题来对数据进行分类。
      • 🌳 就像一棵树,每个内部节点表示一个特征或属性,每个分支代表一个测试输出,每个叶节点代表一个类别。
      • 从根节点开始,根据数据的特征进行判断,沿着不同的分支向下走,直到到达叶节点,叶节点所代表的类别就是预测结果。

决策树:更详细的解释

  • 决策树是一种直观且易于理解的分类方法。它通过递归地将数据集划分为更小的子集,并在每个子集上构建一个决策节点,最终形成一个树状结构。
  • 优点
    • 易于理解和解释,可以可视化决策过程。
    • 可以处理数值型和类别型数据。
    • 不需要对数据进行预处理(如归一化)。
  • 缺点
    • 容易过拟合,需要进行剪枝等处理。
    • 对数据中的噪声比较敏感。
    • 可能会产生偏向于某些特征的决策树。

Decision Tree 代码示例

import numpy as np
from sklearn import tree, datasets

# 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris.data
Y = iris.target

# 创建 DecisionTreeClassifier 对象
clf = tree.DecisionTreeClassifier()

# 使用 fit 方法训练模型
clf.fit(X, Y)

# 使用 predict 方法对新的数据点进行预测
print(clf.predict([[5.1, 3.5, 1.4, 0.2]])) # 预测结果为类别 0 (Setosa)
[0]

Stochastic Gradient Descent (随机梯度下降)

  • 实现:

    • sklearn.linear_model.SGDClassifier()
  • 支持:

    • 多种 loss functions (损失函数)
    • 多种 penalties for classification (分类处罚)
  • 概念解释:

    • Stochastic Gradient Descent: 随机梯度下降是一种优化算法,常用于训练机器学习模型,尤其是大规模数据集上的线性模型。
      • 🚀 就像一个探险家,每次只看一小步 (随机选择一个样本),但最终也能到达目的地 (找到最优解)。

随机梯度下降:更详细的解释

  • 与传统的梯度下降算法不同,SGD 每次迭代只使用一个样本来计算梯度,并更新模型参数。这样做的好处是可以大大加快训练速度,尤其是在数据集非常大的情况下。
  • 优点
    • 训练速度快,适用于大规模数据集。
    • 可以用于在线学习 (Online Learning),即模型可以随着新数据的到来不断更新。
  • 缺点
    • 收敛过程可能不稳定,需要仔细调整学习率等参数。
    • 容易陷入局部最优解。

随机梯度下降的参数设置

  • loss 参数:设置损失函数
    • hinge (默认):soft-margin SVM,适用于线性 SVM 分类器。
    • modified_huber:平滑的 hinge 损失,对噪声更鲁棒。
    • log:logistic 回归,适用于概率分类。
    • hingemodified_huber 是惰性的,能够提高训练效率
  • class_weight 参数:设置分类权重,用于处理类别不平衡问题。
    • 默认所有类别权重相等,均为 1。
    • 用形如 “{class: weight}” 的 dict 指明权重,可以手动调整每个类别的权重。
    • 声明为 “balanced” 自动设置各类权重与其出现概率成反比,可以自动平衡类别权重。

Stochastic Gradient Descent 代码示例

import numpy as np
from sklearn import linear_model, datasets

# 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris.data
Y = iris.target

# 创建 SGDClassifier 对象,并设置 loss 为 'log_loss' (logistic 回归)
clf = linear_model.SGDClassifier(loss='log_loss', max_iter=1000, tol=1e-3)

# 使用 fit 方法训练模型
clf.fit(X, Y)

# 使用 predict 方法对新的数据点进行预测
print(clf.predict([[5.1, 3.5, 1.4, 0.2]])) # 预测结果为类别 0 (Setosa)
[0]

提示

使用时,需要预先打乱训练数据或在声明时将 “shuffle” 参数设置为 “True” (默认即为 “True”) 以在每次迭代后打乱数据

Gaussian Process Classification (高斯过程分类)

  • 实现:
    • sklearn.gaussian_process.GaussianProcessClassifier()
  • 支持多元分类:
    • ovr (默认): 每个类都训练一个二元高斯过程分类器,将该类与其余类分开
    • ovo: 每两个类训练一个二元高斯过程分类器,将两个类分开
    • 对于高斯过程分类,“ovo” 策略可能在计算上更有效,但是不支持预测概率估计。

Gaussian Process Classification:概念解释

  • Gaussian Process: 高斯过程是一种概率模型,它假设任意有限个数据点的联合分布都是一个多元高斯分布。
  • 高斯过程分类是一种基于概率的分类方法。它假设数据点是由一个潜在的高斯过程生成的,并使用贝叶斯推断来估计后验概率。可以用于对函数的分布进行建模。
    • 📊 可以理解为对函数的“函数”进行建模,不仅可以预测函数值,还可以估计预测的不确定性。
  • 优点
    • 可以提供预测的置信度。
    • 可以处理非线性关系。
  • 缺点
    • 计算复杂度较高,不适用于大规模数据集。
    • 对核函数的选择比较敏感。

Gaussian Process Classification 代码示例

import numpy as np
from sklearn import gaussian_process, datasets

# 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris.data
Y = iris.target

# 创建 GaussianProcessClassifier 对象
clf = gaussian_process.GaussianProcessClassifier()

# 使用 fit 方法训练模型
clf.fit(X, Y)

# 使用 predict 方法对新的数据点进行预测
print(clf.predict([[5.1, 3.5, 1.4, 0.2]])) # 预测结果为类别 0 (Setosa)
[0]

Multilayer Perceptron (多层感知器 - 神经网络)

  • 实现:
    • sklearn.neural_network.MLPClassifier()
  • 部分细节:
    • MLPClassifier 只支持交叉熵损失函数,通过运行 predict_proba 方法进行概率估计
    • MLP 算法使用的是反向传播的方式,通过反向传播计算得到的梯度和某种形式的梯度下降来进行训练
    • 对于分类来说,它最小化交叉熵损失函数,为每个样本给出一个向量形式的概率估计

神经网络:从感知器到多层感知器

感知器 (Perceptron)

  • 起源: 感知器是最早的人工神经元模型,由 Frank Rosenblatt 在 1957 年提出。
  • 结构: 单层感知器由一个或多个输入节点、一个输出节点和一个激活函数组成。
  • 工作原理:
    1. 输入信号乘以权重。
    2. 对加权后的输入求和。
    3. 将求和结果输入激活函数,产生输出。
  • 激活函数: 通常使用阶跃函数 (Heaviside step function)。
  • 局限性: 单层感知器只能解决线性可分问题。

多层感知器 (Multilayer Perceptron, MLP)

  • 突破: 为了解决线性不可分问题,引入了多层感知器。
  • 结构: MLP 是一种前馈神经网络,由多个层组成:
    • 输入层: 接收原始数据。
    • 隐藏层: 对数据进行非线性变换。可以有多个隐藏层。
    • 输出层: 输出预测结果。
  • 神经元: 每个层包含多个神经元,神经元之间全连接。
  • 激活函数: 隐藏层通常使用非线性激活函数,如 Sigmoid、ReLU、tanh 等。
  • 反向传播 (Backpropagation): 一种用于训练神经网络的算法,它通过计算损失函数对每个参数的梯度,来更新神经网络的权重。

神经网络的优点和缺点

  • 优点
    • 可以学习复杂的非线性关系。
    • 具有较强的泛化能力。
    • 可以处理高维数据。
  • 缺点
    • 训练时间较长。
    • 容易陷入局部最优解。
    • 需要仔细调整网络结构和参数。
    • 可解释性较差。

神经网络的应用

  • 图像识别
  • 语音识别
  • 自然语言处理
  • 推荐系统
  • 金融预测

Multilayer Perceptron 参数设置

  • hidden_layer_sizes 参数声明中间层的单元数
    • tuple 形式,每一项为中间层各层的单元数
    • 默认为一层中间层,100 个单元
    • 例如:hidden_layer_sizes=(100,) 表示只有一个隐藏层且这个隐藏层有100个神经元。hidden_layer_sizes=(50, 50) 表示有两个隐藏层,每个隐藏层有50个神经元。

Multilayer Perceptron 代码示例

import numpy as np
from sklearn import neural_network, datasets

# 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris.data
Y = iris.target

# 创建 MLPClassifier 对象,并设置隐藏层为 (100,),即一个包含 100 个神经元的隐藏层
clf = neural_network.MLPClassifier(hidden_layer_sizes=(100,), max_iter=1000)

# 使用 fit 方法训练模型
clf.fit(X, Y)

# 使用 predict 方法对新的数据点进行预测
print(clf.predict([[5.1, 3.5, 1.4, 0.2]])) # 预测结果为类别 0 (Setosa)

# 使用 predict_proba 方法进行概率估计
print(clf.predict_proba([[5.1, 3.5, 1.4, 0.2]]))
[0]
[[9.98921958e-01 1.07804203e-03 6.25487715e-14]]

Naive Bayes (朴素贝叶斯)

  • 实现:
    • sklearn.naive_bayes.GaussianNB():高斯朴素贝叶斯,假设特征服从高斯分布。
    • sklearn.naive_bayes.MultinomialNB():多项式朴素贝叶斯,适用于多项式分布的数据,如文本数据 (单词计数)。
    • sklearn.naive_bayes.BernoulliNB():伯努利朴素贝叶斯,适用于二元分布的数据 (特征是二值的)。
  • 注意:
    • 提供 partial_fit 方法用于动态的加载数据以解决大数据量的问题
    • 首次调用 partial_fit 方法需要传递一个所有期望的类标签的列表

Naive Bayes:概念解释

  • Naive Bayes: 朴素贝叶斯是一种基于贝叶斯定理的简单概率分类器。“朴素” 的意思是假设特征之间相互独立。
    • 🧮 基于概率的分类器,它假设每个特征对分类结果的影响是独立的。
  • 贝叶斯定理: 一种计算条件概率的公式,即在已知一些条件下,事件发生的概率。
    • P(A|B) = [P(B|A) * P(A)] / P(B)
  • 优点
    • 简单、快速、高效。
    • 适用于高维数据,如文本数据。
    • 对缺失数据不敏感。
  • 缺点
    • “朴素” 的假设在现实中往往不成立,特征之间可能存在相关性。
    • 对输入数据的表达形式很敏感。

Naive Bayes 代码示例

import numpy as np
from sklearn import naive_bayes, datasets

# 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris.data
Y = iris.target

# 创建 GaussianNB 对象
gnb = naive_bayes.GaussianNB()

# 创建 MultinomialNB 对象
mnb = naive_bayes.MultinomialNB()

# 创建 BernoulliNB 对象
bnb = naive_bayes.BernoulliNB()

# 使用 fit 方法训练模型
gnb.fit(X, Y)
mnb.fit(X, Y)
bnb.fit(X, Y)

# 使用 predict 方法对新的数据点进行预测
print(gnb.predict([[5.1, 3.5, 1.4, 0.2]])) # 预测结果为类别 0 (Setosa)
print(mnb.predict([[5.1, 3.5, 1.4, 0.2]])) # 预测结果为类别 0 (Setosa)
print(bnb.predict([[5.1, 3.5, 1.4, 0.2]])) # 预测结果为类别 0 (Setosa)
[0]
[0]
[0]

7.2 回归方法

回归方法用于预测连续值,就像一个水晶球🔮,可以帮助我们预测未来!

Linear Regression (最小二乘法)

  • 实现:

    • sklearn.linear_model.LinearRegression()
  • 概念解释:

    • Linear Regression: 线性回归是一种最简单、最常用的回归模型,它假设特征和目标变量之间存在线性关系。
      • 📏 就像用一条直线来尽可能地穿过所有的数据点,使得所有数据点到这条直线的距离之和最小。

Linear Regression:最小二乘法

  • 最小二乘法: 一种求解线性回归模型参数的方法,目标是找到一条直线,使得所有数据点到这条直线的残差平方和最小。
  • 线性回归简单、易于理解,并且在许多实际问题中表现良好。
  • 优点
    • 简单、易于理解和实现。
    • 计算效率高。
    • 可以解释模型参数的意义。
  • 缺点
    • 假设特征和目标变量之间存在线性关系,可能无法很好地拟合非线性数据。
    • 对异常值比较敏感。

Linear Regression 代码示例

import numpy as np
from sklearn import linear_model, datasets

# 加载糖尿病数据集
diabetes = datasets.load_diabetes()
X = diabetes.data
Y = diabetes.target

# 创建 LinearRegression 对象
reg = linear_model.LinearRegression()

# 使用 fit 方法训练模型
reg.fit(X, Y)

# 查看模型系数 (coef_) 和截距 (intercept_)
print(reg.coef_)
print(reg.intercept_)
[ -10.0098663  -239.81564367  519.84592005  324.3846455  -792.17563855
  476.73902101  101.04326794  177.06323767  751.27369956   67.62669218]
152.13348416289597

Ridge Regression (岭回归)

  • 实现:

    • sklearn.linear_model.Ridge()
  • 优化方案: solver 参数指定

    • autosvdcholeskylsqrsparse_cgsagsaga,默认为 auto
  • 概念解释:

    • Ridge Regression: 岭回归是一种改进的线性回归模型,它通过添加 L2 正则化项来防止过拟合。

Ridge Regression:L2 正则化

  • L2 正则化: 对模型参数的平方和进行惩罚,使得模型参数不会过大,从而提高模型的泛化能力。
  • 优点
    • 可以处理多重共线性问题 (特征之间存在高度相关性)。
    • 可以提高模型的泛化能力。
  • 缺点
    • 模型的解释性不如线性回归。

Ridge Regression 代码示例

import numpy as np
from sklearn import linear_model, datasets

# 加载糖尿病数据集
diabetes = datasets.load_diabetes()
X = diabetes.data
Y = diabetes.target

# 创建 Ridge 对象,并设置 alpha 参数 (正则化强度)
rid = linear_model.Ridge(alpha=1.0)

# 使用 fit 方法训练模型
rid.fit(X, Y)

# 查看模型系数
print(rid.coef_)
[  29.46611189  -83.15427636  306.35268015  201.62773437    5.90961437
  -29.51549508 -152.04028006  117.3117316   262.94429001  111.87895644]

Lasso

  • 实现:

    • sklearn.linear_model.Lasso()
  • 概念解释:

    • Lasso: Lasso 回归类似于岭回归,但它使用 L1 正则化项来约束模型参数。

Lasso:L1 正则化

  • L1 正则化: 对模型参数的绝对值之和进行惩罚,倾向于产生稀疏的模型,即许多模型参数为零。这使得 Lasso 回归可以用于特征选择,即选择对目标变量影响最大的特征。
  • 优点
    • 可以进行特征选择,得到更简洁、易于解释的模型。
    • 可以处理多重共线性问题。
  • 缺点
    • 当特征数量大于样本数量时,Lasso 只能选择最多样本数量个特征。
    • 对于存在高度相关性的特征,Lasso 可能会随机选择其中一个特征,导致结果不稳定。

Lasso 代码示例

import numpy as np
from sklearn import linear_model, datasets

# 加载糖尿病数据集
diabetes = datasets.load_diabetes()
X = diabetes.data
Y = diabetes.target

# 创建 Lasso 对象,并设置 alpha 参数 (正则化强度)
las = linear_model.Lasso(alpha=1.0)

# 使用 fit 方法训练模型
las.fit(X, Y)

# 查看模型系数
print(las.coef_)
[  0.          -0.         367.70385976   6.29885756   0.
   0.          -0.           0.         307.6054181    0.        ]

LassoLars

  • 实现:

    • 使用 LARS (最小角回归)
    • sklearn.linear_model.LassoLars()
  • 概念解释

    • LARS (Least Angle Regression): 最小角回归是一种逐步向前选择算法,它可以用于求解 Lasso 模型,也可以用于构建其他线性模型。
    • 优点
      • 计算效率高,尤其适用于高维数据。
      • 可以得到 Lasso 模型的完整路径 (不同 alpha 值对应的系数)。
    • 缺点
      • 对噪声比较敏感。

LassoLars 代码示例

import numpy as np
from sklearn import linear_model, datasets

# 加载糖尿病数据集
diabetes = datasets.load_diabetes()
X = diabetes.data
Y = diabetes.target

# 创建 LassoLars 对象,并设置 alpha 参数 (正则化强度)
larlas = linear_model.LassoLars(alpha=1.0)

# 使用 fit 方法训练模型
larlas.fit(X, Y)

# 查看模型系数
print(larlas.coef_)
[  0.           0.         367.70162582   6.30970264   0.
   0.           0.           0.         307.60214746   0.        ]

Bayesian Ridge Regression (贝叶斯岭回归)

  • 实现:

    • sklearn.linear_model.BayesianRidge()
  • 概念解释:

    • Bayesian Ridge Regression: 贝叶斯岭回归是一种贝叶斯版本的岭回归,它将模型参数视为随机变量,并使用先验分布来约束参数。
    • 贝叶斯方法: 将参数视为随机变量,并结合先验知识和数据来推断参数的后验分布。
    • 优点
      • 可以估计模型参数的不确定性。
      • 可以自动调整正则化强度。
    • 缺点
      • 计算复杂度较高。

Bayesian Ridge Regression 代码示例

import numpy as np
from sklearn import linear_model, datasets

# 加载糖尿病数据集
diabetes = datasets.load_diabetes()
X = diabetes.data
Y = diabetes.target

# 创建 BayesianRidge 对象
byr = linear_model.BayesianRidge()

# 使用 fit 方法训练模型
byr.fit(X, Y)

# 查看模型系数
print(byr.coef_)
[  -4.23356256 -226.32799122  513.47304015  314.90385885 -182.28434068
   -4.36854822 -159.20103916  114.63541259  506.82345986   76.25617559]

Decision Tree Regression (决策树回归)

  • 实现:
    • sklearn.tree.DecisionTreeRegressor()
  • 概念解释:
    • Decision Tree Regression: 决策树回归与决策树分类类似,但它用于预测连续值。
    • 决策树回归通过递归地将数据集划分为更小的子集,并在每个子集上计算目标变量的平均值或中位数,最终形成一个树状结构。
    • 优点
      • 易于理解和解释,可以可视化决策过程。
      • 可以处理数值型和类别型数据。
      • 不需要对数据进行预处理 (如归一化)。
    • 缺点
      • 容易过拟合,需要进行剪枝。
      • 对于高维度数据或者有很多类别的数据,决策树可能会非常复杂。
      • 决策树是基于贪心算法构建的,可能不是全局最优的。

Decision Tree Regression 代码示例

import numpy as np
from sklearn import tree, datasets

# 加载糖尿病数据集
diabetes = datasets.load_diabetes()
X = diabetes.data
Y = diabetes.target

# 创建 DecisionTreeRegressor 对象
reg = tree.DecisionTreeRegressor()

# 使用 fit 方法训练模型
reg.fit(X, Y)

# 使用 predict 方法对新的数据点进行预测
print(reg.predict([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]))
[306.]

Gaussian Process Regression (高斯过程回归)

  • 实现:

    • sklearn.gaussian_process.GaussianProcessRegressor()
  • 概念解释:

    • Gaussian Process Regression: 高斯过程回归是一种基于概率的回归方法,它将目标变量视为高斯过程的样本。与高斯过程分类类似,它可以用于对函数的分布进行建模。
    • 优点
      • 可以提供预测的置信度。
      • 可以处理非线性关系。
    • 缺点
      • 计算复杂度较高,不适用于大规模数据集。
      • 对核函数的选择比较敏感。

Gaussian Process Regression 代码示例

import numpy as np
from sklearn import gaussian_process, datasets

# 加载糖尿病数据集
diabetes = datasets.load_diabetes()
X = diabetes.data
Y = diabetes.target

# 创建 GaussianProcessRegressor 对象
gpr = gaussian_process.GaussianProcessRegressor()

# 使用 fit 方法训练模型
gpr.fit(X, Y)

# 使用 predict 方法对新的数据点进行预测
print(gpr.predict([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]))
[-6.55954358e-53]

Nearest Neighbors Regression (最近邻回归)

  • 实现:
    • sklearn.neighbors.KNeighborsRegressor():K-近邻回归器。
    • sklearn.neighbors.RadiusNeighborsRegressor():半径近邻回归器。
  • 参数
    • n_neighbors: 设置 k 值 (KNeighborsRegressor)。
    • radius: 设置 r 值 (RadiusNeighborsRegressor)。
    • weights: 对近邻进行加权,
      • uniform:所有邻居权重相同。
      • distance:权重与距离成反比。
      • 自定函数:可以自定义一个函数来计算权重。
  • 概念解释:
    • Nearest Neighbors Regression: 最近邻回归是一种基于“物以类聚”思想的回归方法。对于一个新的数据点,找到离它最近的训练数据点(即“邻居”),然后根据这些邻居的目标变量值来预测新数据点的目标变量值。
      • 🚶 与最近邻分类类似,只是预测的不是类别,而是连续值。
      • KNeighborsRegressor:使用 k 个最近邻的目标变量值的平均值 (或加权平均值) 作为预测值。
      • RadiusNeighborsRegressor:使用半径 r 内所有邻居的目标变量值的平均值 (或加权平均值) 作为预测值。

Nearest Neighbors Regression 代码示例

import numpy as np
from sklearn import neighbors, datasets

# 加载糖尿病数据集
diabetes = datasets.load_diabetes()
X = diabetes.data
Y = diabetes.target

# 创建 KNeighborsRegressor 对象,并设置 n_neighbors 为 5
kreg = neighbors.KNeighborsRegressor(n_neighbors=5)

# 创建 RadiusNeighborsRegressor 对象,并设置 radius 为 50.0
rreg = neighbors.RadiusNeighborsRegressor(radius=50.0)

# 使用 fit 方法训练模型
kreg.fit(X, Y)
rreg.fit(X, Y)

# 预测
print(kreg.predict([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]))
print(rreg.predict([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]))

# 可以查看邻居关系图
# print(kreg.kneighbors_graph(X).toarray())
# print(rreg.radius_neighbors_graph(X).toarray())
[209.4]
[152.13348416]

7.3 聚类方法

聚类方法用于将相似的数据点分组到一起,就像一个聪明的组织者🧑‍🤝‍🧑,把相似的东西聚集起来!

K-means

  • 实现:

    • sklearn.cluster.KMeans():K-means 聚类。
    • sklearn.cluster.MiniBatchKMeans():Mini-Batch K-means 聚类,适用于大规模数据集。
  • 参数

    • init: 指定聚类质心的初始化方法
      • k-means++ (默认): 使用一种比较智能的方法初始化,各个初始化质心彼此相距较远,能加快收敛速度。这是最常用的初始化方法。
      • random: 随机选择数据点作为初始质心。
      • 指定一个 ndarray: 可以手动指定初始质心。
    • n_init 参数: 算法将初始化 “n_init” 次,并选择结果最好的一次作为最终结果 (默认为 10 次)。多次初始化可以避免陷入局部最优解。
  • 概念解释:

    • K-means: K-means 是一种常用的聚类算法,它的目标是将数据点划分到 K 个簇中,使得每个数据点都属于离它最近的质心 (centroid) 所对应的簇。
      • 🤝 就像把一群人分成 K 组,每组的中心人物是该组的平均代表。
      • 质心 (Centroid): 每个簇的中心点,是该簇中所有数据点的平均值。

K-means:算法步骤

  1. 初始化: 随机选择 K 个数据点作为初始质心。
  2. 分配: 将每个数据点分配到离它最近的质心所对应的簇。
  3. 更新: 重新计算每个簇的质心。
  4. 重复: 重复步骤 2 和 3,直到质心不再变化或达到最大迭代次数。

K-means:优点与缺点

  • 优点
    • 简单、快速、高效。
    • 适用于大规模数据集。
  • 缺点
    • 需要事先指定簇的数量 K。
    • 对初始质心的选择比较敏感,可能会陷入局部最优解。
    • 对异常值比较敏感。
    • 只能发现球形的簇。

K-means 的参数设置

  • n_clusters 指定聚类的个数,如不指定则默认为 8
  • n_jobs 指定使用的处理器个数

K-means 代码示例

import numpy as np
from sklearn import cluster, datasets

# 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris.data

# 创建 KMeans 对象,并设置 n_clusters 为 3 (因为鸢尾花数据集有 3 个类别)
kms = cluster.KMeans(n_clusters=3, n_init = 'auto')

# 创建 MiniBatchKMeans 对象
mbk = cluster.MiniBatchKMeans(n_clusters=3, n_init = 'auto')

# 使用 fit 方法训练模型
kms.fit(X)
mbk.fit(X)

# 查看聚类中心 (cluster_centers_) 和每个数据点所属的簇 (labels_)
print(kms.cluster_centers_)
print(kms.labels_)
# print(mbk.cluster_centers_)
# print(mbk.labels_)
[[6.85384615 3.07692308 5.71538462 2.05384615]
 [5.006      3.428      1.462      0.246     ]
 [5.88360656 2.74098361 4.38852459 1.43442623]]
[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 0 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 2 0 0 0 0 2 0 0 0 0
 0 0 2 2 0 0 0 0 2 0 2 0 2 0 0 2 2 0 0 0 0 0 2 0 0 0 0 2 0 0 0 2 0 0 0 2 0
 0 2]

Affinity Propagation

  • 实现:

    • sklearn.cluster.AffinityPropagation()
  • 概念解释:

    • Affinity Propagation: 亲和力传播是一种基于消息传递的聚类算法,它不需要事先指定簇的数量。
      • 💬 就像一群人通过互相交流来找到自己的群体。每个人都可以是潜在的“聚类中心”(exemplar),通过不断地在数据点之间传递“吸引度”和“归属度”信息,最终会涌现出一些“聚类中心”,数据点会聚集到这些中心周围。
    • 优点
      • 不需要事先指定簇的数量。
      • 可以发现不规则形状的簇。
    • 缺点
      • 计算复杂度较高,不适用于大规模数据集。
      • 对参数的选择比较敏感。

Affinity Propagation 的参数

  • affinity: 相似度度量方式

    • precomputed:使用预先计算好的相似度矩阵。
    • euclidean (默认):使用欧几里得距离。
  • damping: 阻尼因子,

    • 0.5~1 之间的浮点数,用于控制算法的收敛速度。
  • preference: 偏好,值越高的点越可能被选为样本

    • vector

Affinity Propagation 代码示例

import numpy as np
from sklearn import cluster, datasets

# 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris.data

# 创建 AffinityPropagation 对象
ap = cluster.AffinityPropagation()

# 使用 fit 方法训练模型
ap.fit(X)

# 查看聚类中心 (cluster_centers_) 和每个数据点所属的簇 (labels_)
print(ap.cluster_centers_)
print(ap.labels_)
[[4.7 3.2 1.3 0.2]
 [5.3 3.7 1.5 0.2]
 [6.5 2.8 4.6 1.5]
 [5.6 2.5 3.9 1.1]
 [6.  2.7 5.1 1.6]
 [7.6 3.  6.6 2.1]
 [6.8 3.  5.5 2.1]]
[1 0 0 0 1 1 0 0 0 0 1 0 0 0 1 1 1 1 1 1 1 1 0 1 0 0 1 1 1 0 0 1 1 1 0 0 1
 1 0 1 1 0 0 1 1 0 1 0 1 0 2 2 2 3 2 3 2 3 2 3 3 2 3 2 3 2 4 3 2 3 4 3 4 2
 2 2 2 2 2 3 3 3 3 4 3 2 2 2 3 3 3 2 3 3 3 3 3 2 3 3 6 4 6 6 6 5 3 5 6 5 6
 4 6 4 4 6 6 5 5 4 6 4 5 4 6 6 4 4 6 6 5 5 6 4 4 5 6 6 4 6 6 6 4 6 6 6 4 6
 6 4]

Mean-shift

  • 实现:
    • sklearn.cluster.MeanShift()
  • 概念解释
    • Mean-shift: 均值漂移是一种基于密度估计的聚类算法,它将数据点沿着密度梯度方向移动,最终聚集到密度较高的区域。
    • 📈 就像一群人爬山,每个人都朝着最陡峭的方向 (密度梯度) 爬,最终会聚集到山顶 (密度中心)。

Mean-shift:算法步骤

  1. 初始化: 随机选择一个数据点作为起始点。
  2. 计算均值漂移向量: 计算以当前点为中心的指定半径 (带宽) 内所有数据点的均值,然后计算当前点到均值的向量。
  3. 移动: 将当前点沿着均值漂移向量的方向移动。
  4. 重复: 重复步骤 2 和 3,直到当前点不再移动或达到最大迭代次数。
  5. 聚类: 将所有收敛到同一个点的数据点归为一类。
  • 优点
    • 不需要事先指定簇的数量。
    • 可以发现任意形状的簇。
    • 对异常值不敏感。
  • 缺点
    • 计算复杂度较高,不适用于大规模数据集。
    • 对带宽参数的选择比较敏感。
  • 参数 bandwidth
    • 声明浮点数“带宽”限制搜索区域
    • 默认使用 sklearn.cluster.estimate_bandwidth 函数

Mean-shift 代码示例

import numpy as np
from sklearn import cluster, datasets

# 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris.data

# 创建 MeanShift 对象
ms = cluster.MeanShift()

# 使用 fit 方法训练模型
ms.fit(X)

# 查看聚类中心 (cluster_centers_) 和每个数据点所属的簇 (labels_)
print(ms.cluster_centers_)
print(ms.labels_)
[[6.21142857 2.89285714 4.85285714 1.67285714]
 [5.01632653 3.45102041 1.46530612 0.24489796]]
[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 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 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]

Spectral Clustering

  • 实现:
    • sklearn.cluster.SpectralClustering()
  • 概念解释
    • Spectral Clustering: 谱聚类是一种基于图论的聚类算法,它将数据点视为图中的节点,并通过图的谱分解 (特征值分解) 来进行聚类。
      • 📊 将数据点之间的相似度构建成一个图,然后将聚类问题转化为图的划分问题。

Spectral Clustering:算法步骤

  1. 构建相似度图: 根据数据点之间的相似度构建一个相似度矩阵 (或邻接矩阵)。
  2. 计算拉普拉斯矩阵: 根据相似度矩阵计算拉普拉斯矩阵。
  3. 特征值分解: 对拉普拉斯矩阵进行特征值分解,得到特征值和特征向量。
  4. 聚类: 使用 K-means 等算法对特征向量进行聚类。
  • 优点
    • 可以发现非凸形状的簇。
    • 对数据分布的假设较少。
  • 缺点
    • 计算复杂度较高,不适用于大规模数据集。
    • 对参数的选择比较敏感。

Spectral Clustering 代码示例

import numpy as np
from sklearn import cluster, datasets

# 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris.data

# 创建 SpectralClustering 对象
sc = cluster.SpectralClustering(n_clusters=3)  # 移除 n_init 参数

# 使用 fit 方法训练模型
sc.fit(X)

# 查看每个数据点所属的簇 (labels_)
print(sc.labels_)
[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 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 0 2 2 2 2 0 2 2 2 2
 2 2 0 0 2 2 2 2 0 2 0 2 0 2 2 0 0 2 2 2 2 2 0 0 2 2 2 0 2 2 2 0 2 2 2 0 2
 2 0]

Hierarchical Clustering (层次聚类)

  • 实现:
    • sklearn.cluster.AgglomerativeClustering()
  • 概念解释
    • Hierarchical Clustering: 层次聚类是一种构建层次结构的聚类算法,它可以自底向上 (凝聚式) 或自顶向下 (分裂式) 进行。
      • 🌳 就像一棵树,数据点逐渐合并成更大的簇,或者一个大簇逐渐分裂成更小的簇。
      • 凝聚式层次聚类 (Agglomerative Clustering): 从每个数据点作为一个单独的簇开始,然后逐步合并最相似的簇,直到所有数据点都合并成一个簇。
      • 分裂式层次聚类 (Divisive Clustering): 从所有数据点都在一个簇开始,然后逐步将簇分裂成更小的簇,直到每个数据点都成为一个单独的簇。
    • 优点
      • 可以得到数据的层次结构。
      • 不需要事先指定簇的数量 (可以通过观察层次结构来决定)。
    • 缺点
      • 计算复杂度较高,不适用于大规模数据集。
      • 对噪声和异常值比较敏感。
      • 一旦合并或分裂,就无法撤销。

Hierarchical Clustering 代码示例

import numpy as np
from sklearn import cluster, datasets

# 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris.data

# 创建 AgglomerativeClustering 对象,并设置 n_clusters 为 3
ag = cluster.AgglomerativeClustering(n_clusters=3)

# 使用 fit 方法训练模型
ag.fit(X)

# 查看每个数据点所属的簇 (labels_)
print(ag.labels_)
[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 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 2 2 2 2 0 2 2 2 2
 2 2 0 0 2 2 2 2 0 2 0 2 0 2 2 0 0 2 2 2 2 2 0 0 2 2 2 0 2 2 2 0 2 2 2 0 2
 2 0]

DBSCAN

  • 实现:
    • sklearn.cluster.DBSCAN()
  • 概念解释
    • DBSCAN (Density-Based Spatial Clustering of Applications with Noise): 基于密度的空间聚类算法,它可以发现任意形状的簇,并能识别噪声点。
      • 🌌 就像在星空中寻找星系,密集的地方就是一个星系 (簇),稀疏的地方就是噪声。

DBSCAN:核心概念

  • 核心点 (Core Point): 在指定半径 (eps) 内,邻居数量 (包括自身) 超过指定阈值 (min_samples) 的数据点。
  • 边界点 (Border Point): 在指定半径 (eps) 内,邻居数量少于指定阈值 (min_samples),但落在某个核心点的邻域内的数据点。
  • 噪声点 (Noise Point): 既不是核心点,也不是边界点的数据点。

DBSCAN:算法步骤

  1. 寻找核心点: 遍历所有数据点,找到所有核心点。
  2. 连接核心点: 将相互之间距离小于 eps 的核心点连接起来,形成一个簇。
  3. 合并边界点: 将边界点分配到与其相邻的核心点所在的簇。
  4. 识别噪声点: 将不属于任何簇的数据点标记为噪声点。
  • 优点
    • 可以发现任意形状的簇。
    • 可以识别噪声点。
    • 不需要事先指定簇的数量。
  • 缺点
    • 对参数 (eps 和 min_samples) 的选择比较敏感。
    • 对于密度差异较大的数据集,聚类效果可能不好。

DBSCAN 代码示例

import numpy as np
from sklearn import cluster, datasets

# 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris.data

# 创建 DBSCAN 对象,并设置 eps (邻域半径) 和 min_samples (最小邻居数)
db = cluster.DBSCAN(eps=0.5, min_samples=5)

# 使用 fit 方法训练模型
db.fit(X)

# 查看每个数据点所属的簇 (labels_),-1 表示噪声点
print(db.labels_)
[ 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  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  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]

Birch

  • 实现:

    • sklearn.cluster.Birch()
  • 概念解释

    • Birch (Balanced Iterative Reducing and Clustering using Hierarchies): 一种适用于大规模数据集的层次聚类算法。
      • 🌲 它通过构建一个叫做 CF 树 (Clustering Feature Tree) 的树状结构来存储数据的摘要信息,从而减少计算量。

Birch:CF 树

  • CF (Clustering Feature): 簇特征,包含簇中数据点的个数、数据点的线性和、数据点的平方和。
  • CF 树: 一种平衡树,每个节点包含多个 CF 条目。

Birch:算法步骤

  1. 构建 CF 树: 扫描数据集,将数据点插入到 CF 树中。
  2. 调整 CF 树: 对 CF 树进行调整,使其满足内存限制。
  3. 全局聚类: 对 CF 树的叶节点进行聚类。
  4. 聚类优化: 对聚类结果进行优化 (可选)。
  • 优点
    • 适用于大规模数据集。
    • 计算效率高。
    • 可以处理噪声数据。
  • 缺点
    • 对参数的选择比较敏感。
    • 只能发现球形的簇。

Birch 代码示例

import numpy as np
from sklearn import cluster, datasets

# 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris.data

# 创建 Birch 对象,并设置 n_clusters 为 3
bir = cluster.Birch(n_clusters=3)

# 使用 fit 方法训练模型
bir.fit(X)

# 查看每个数据点所属的簇 (labels_)
print(bir.labels_)
[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 0 0 0 1 0 0 0 1 0 1 1 0 1 0 1 0 0 1 0 1 0 1 0 0
 0 0 0 0 0 1 1 1 1 0 0 0 0 0 1 1 1 0 1 1 1 1 1 0 1 1 0 0 0 0 0 0 1 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]

总结

  • 本章介绍了使用 Pandas 和 scikit-learn 进行数据分析的各种方法,包括:
    • 分类:Logistic 回归, SVM, 最近邻, 决策树, 随机梯度下降, 高斯过程分类, 多层感知器, 朴素贝叶斯
      • 🔑 这些方法就像不同的钥匙🔑,可以打开不同类型的数据宝箱📦。
    • 回归:线性回归, 岭回归, Lasso, LassoLars, 贝叶斯岭回归, 决策树回归, 高斯过程回归, 最近邻回归
      • 🔮 这些方法就像不同的水晶球🔮,可以预测未来。
    • 聚类:K-means, Affinity Propagation, Mean-shift, Spectral Clustering, 层次聚类, DBSCAN, Birch
      • 🧑‍🤝‍🧑 这些方法就像不同的组织者🧑‍🤝‍🧑,可以将相似的数据聚集起来。
  • Pandas 提供了强大的数据处理和分析工具,就像一个超级 Excel 表格。
  • scikit-learn 提供了各种机器学习算法和工具,就像一个机器学习百宝箱🧰。
  • 通过结合使用这两个库,我们可以轻松地实现各种数据分析任务,探索数据的奥秘🔬!

思考与讨论

  • 🤔️ 不同的分类、回归、聚类算法分别适用于哪些场景?
    • 例如:什么时候应该选择 SVM,什么时候应该选择决策树?
  • 🛠️ 如何选择合适的算法和参数?
    • 例如:如何确定 K-means 中的 K 值?如何调整 SVM 中的核函数和参数?
  • 📈 如何评估模型的性能?
    • 例如:如何判断一个分类模型的好坏?如何判断一个回归模型的预测是否准确?
  • 💡 如何将这些技术应用到实际问题中?
    • 例如:如何使用聚类算法来进行客户细分?如何使用回归算法来预测房价?
  • 📚️ 还有哪些其他的数据分析方法和技术?
    • 例如:降维、特征工程、集成学习等。