小样本分类常用分类方法

小样本分类涵盖了多种技术,其中包括传统机器学习方法如朴素贝叶斯、支持向量机、k近邻算法以及逻辑回归;同时也涉及深度学习方法,例如迁移学习、少样本学习和嵌入式学习。本文主要介绍传统机器学习方法。

安装必要的库
在开始之前我们需要安装必要的库
要安装numpy、pandas、sklearn(scikit-learn)和seaborn,你可以使用Python的包管理工具pip或conda。以下是详细的安装步骤:

使用pip安装

  1. 安装numpy

    打开命令行工具(在Windows上是命令提示符CMD或PowerShell,在macOS或Linux上是终端Terminal),然后输入以下命令:

    1
    pip install numpy

    这将从Python官方的包索引(PyPI)下载并安装最新版的numpy。

  2. 安装pandas

    同样在命令行工具中,输入以下命令:

    1
    pip install pandas

    这将下载并安装最新版的pandas。

  3. 安装sklearn(scikit-learn)

    输入以下命令来安装scikit-learn:

    1
    pip install scikit-learn

    或者,由于scikit-learn通常简称为sklearn,你也可以使用以下命令(尽管两者在功能上是等价的):

    1
    pip install sklearn
  4. 安装seaborn

    输入以下命令来安装seaborn:

    1
    pip install seaborn

使用conda安装

如果你使用的是Anaconda或Miniconda这样的科学计算平台,你可以使用conda包管理器来安装这些库。

  1. 安装numpy

    在命令行工具(如Anaconda Prompt)中,输入以下命令:

    1
    conda install numpy
  2. 安装pandas

    输入以下命令:

    1
    conda install pandas
  3. 安装sklearn(scikit-learn)

    输入以下命令:

    1
    conda install scikit-learn

    或者,由于scikit-learn在conda中的包名可能也是sklearn(尽管这取决于具体的conda版本和仓库设置),你也可以尝试使用以下命令(但建议首先检查conda仓库中的包名):

    1
    conda install sklearn

    然而,为了准确性,通常推荐使用scikit-learn作为包名。

  4. 安装seaborn

    输入以下命令:

    1
    conda install seaborn

注意事项

  • 在安装这些库之前,请确保你的Python环境已经正确配置,并且pip或conda已经安装在你的系统上。
  • 如果你在中国大陆等网络访问受限的地区,可能需要使用国内的镜像源来加速下载过程。例如,你可以使用清华大学的PyPI镜像源:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple <包名>(将<包名>替换为你要安装的库的名称)。
  • 安装完成后,你可以通过导入这些库并打印其版本来验证是否安装成功。例如,对于numpy,你可以在Python解释器中输入import numpy as np; print(np.__version__)来查看安装的版本。

通过以上步骤,你应该能够成功地安装numpy、pandas、scikit-learn和seaborn这些Python数据分析与科学计算中常用的库。

层次聚类

在数据分析与机器学习的领域中,聚类是一种无监督学习方法,旨在将相似的数据点分组到不同的簇中,而无需事先知道数据点的类别标签。层次聚类(Hierarchical Clustering)是聚类算法中的一种重要方法,它通过构建数据点的层次树(也称为树状图或树形图)来实现聚类。本文将介绍层次聚类的基本原理,并通过在鸢尾花数据集上的应用展示其效果。

层次聚类原理

层次聚类可以分为凝聚(agglomerative)和分裂(divisive)两种方法。凝聚层次聚类是自下而上的过程,初始时每个数据点被视为一个单独的簇,然后逐步合并最相似的簇,直到所有点都合并成一个簇或达到某个停止条件。相反,分裂层次聚类是自上而下的过程,它从包含所有数据点的一个簇开始,逐步分裂成更小的簇。

关键步骤

  1. 计算相似度:常用的相似度度量包括欧氏距离、曼哈顿距离和夹角余弦等。
  2. 合并或分裂:根据相似度度量,选择最相似的簇进行合并或分裂。
  3. 停止条件:达到预定的簇数量、达到指定的最大或最小距离阈值,或树状图达到一定的深度。

在凝聚层次聚类中,linkage函数用于计算簇之间的距离,并决定如何合并簇。常见的linkage方法包括:

  • 单链法(Single Linkage):计算两个簇中最近数据点之间的距离。
  • 完全链法(Complete Linkage):计算两个簇中最远数据点之间的距离。
  • 平均链法(Average Linkage):计算两个簇中所有数据点之间距离的平均值。
  • Ward方法:最小化合并后簇内的总方差。

在鸢尾花数据集上的应用

下面,我们将通过Python代码展示如何在鸢尾花数据集上应用层次聚类,并评估其效果。

步骤

  1. 加载数据集:使用sklearn.datasets加载鸢尾花数据集。
  2. 应用层次聚类:使用scipy.cluster.hierarchy.linkage函数进行层次聚类,选择Ward方法。
  3. 确定簇数量:由于鸢尾花数据集有三个真实类别,我们选择3个簇。
  4. 映射聚类标签:使用匈牙利算法(线性求和分配问题)将聚类标签映射到真实标签,以优化分类效果。
  5. 评估结果:通过混淆矩阵和分类报告评估聚类效果。
  6. 可视化:使用matplotlibseaborn绘制散点图,展示聚类结果。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import numpy as np
import pandas as pd
from sklearn import datasets
from scipy.cluster.hierarchy import dendrogram, linkage, fcluster
from sklearn.metrics import confusion_matrix, classification_report
from sklearn.preprocessing import LabelEncoder
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.optimize import linear_sum_assignment

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

# 应用层次聚类
Z = linkage(X, 'ward') # 使用Ward方法进行层次聚类

# 选择3个聚类
num_clusters = 3
clusters = fcluster(Z, num_clusters, criterion='maxclust') - 1

# 映射聚类标签到真实标签
row_ind, col_ind = linear_sum_assignment(confusion_matrix(y, clusters).max(axis=1) - confusion_matrix(y, clusters))
best_mapping = {col_ind[i]: i for i in range(num_clusters)}
mapped_clusters = [best_mapping[c] for c in clusters]

# 输出评估结果
cm = confusion_matrix(y, mapped_clusters)
cr = classification_report(y, mapped_clusters, target_names=iris.target_names)
print("Confusion Matrix:")
print(cm)
print("\nClassification Report:")
print(cr)

# 可视化分类结果
plt.figure(figsize=(10, 6))
sns.scatterplot(x=X[:, 0], y=X[:, 1], hue=mapped_clusters, palette='viridis', legend='full', s=100)
plt.title('Hierarchical Clustering of Iris Dataset')
plt.xlabel('Sepal Length')
plt.ylabel('Sepal Width')
plt.show()

层次聚类结果

注意,由于鸢尾花数据集有四个特征,而散点图只能展示两个特征,因此这里仅使用了花萼长度和宽度进行可视化。如果想使用更多特征进行聚类,可以考虑使用降维技术(如PCA)来可视化结果,或分别绘制每对特征的散点图。

层次聚类是一种强大的聚类方法,能够揭示数据中的层次结构。通过在鸢尾花数据集上的应用,我们展示了层次聚类的基本原理和步骤,并通过混淆矩阵、分类报告和散点图评估了聚类效果。层次聚类不仅适用于鸢尾花数据集,还可以广泛应用于其他领域的数据分析任务中。

逻辑回归

在机器学习的分类任务中,逻辑回归(Logistic Regression)是一种广泛应用于二分类问题的线性模型。尽管其名称中包含“回归”,但逻辑回归实际上是一种分类方法,它通过应用一个逻辑函数(通常是sigmoid函数)来预测二分类或多分类问题的概率。本文将介绍逻辑回归的基本原理,并通过在鸢尾花数据集上的应用展示其效果。

逻辑回归原理

逻辑回归的核心在于使用一个线性模型来预测输入特征与目标变量之间的关系,并通过sigmoid函数将线性模型的输出转换为0到1之间的概率值。sigmoid函数的公式如下:

sigmoid函数

其中,P(Y=1|X)表示给定输入特征X时,目标变量Y为1的概率;beta_0是截距项,beta_1, beta_2,····,beta_n是回归系数,对应于输入特征X_1, X_2,····, X_n。

逻辑回归通过最大化似然函数来估计回归系数,从而找到最佳拟合模型。对于二分类问题,逻辑回归的目标是将输入特征映射到两个类别中的一个。

对于多分类问题,逻辑回归通常使用一对多(One-vs-Rest, OvR)策略。在这种策略中,为每个类别训练一个二分类模型,每个模型将当前类别与其他所有类别区分开来。然后,通过比较每个模型的预测概率,选择具有最高概率的类别作为最终预测结果。

在鸢尾花数据集上的应用

下面,我们将通过Python代码展示如何在鸢尾花数据集上应用逻辑回归,并评估其效果。由于鸢尾花数据集是一个三分类问题,我们将首先将其转换为一个二分类问题,然后展示逻辑回归的应用。

步骤

  1. 加载数据集:使用sklearn.datasets加载鸢尾花数据集。
  2. 转换标签:将标签转换为二分类问题(例如,只区分类别0和类别1,忽略类别2)。
  3. 拆分数据集:将数据集拆分为训练集和测试集。
  4. 创建逻辑回归模型:为二分类问题创建逻辑回归模型。
  5. 训练模型:使用训练集训练模型。
  6. 进行预测:使用测试集进行预测。
  7. 评估结果:通过准确率、分类报告和混淆矩阵评估模型效果。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import numpy as np
import pandas as pd
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix

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

# 将标签转换为二分类问题(例如,只区分类别0和类别1)
binary_target = (y != 2).astype(int) # 将类别2转换为0,类别0和1转换为1

# 拆分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, binary_target, test_size=0.3, random_state=42)

# 创建逻辑回归模型
model = LogisticRegression(max_iter=200) # 增加迭代次数以确保收敛

# 训练模型
model.fit(X_train, y_train)

# 进行预测
y_pred = model.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.2f}')

# 打印分类报告和混淆矩阵
print('Classification Report:')
print(classification_report(y_test, y_pred))

print('Confusion Matrix:')
print(confusion_matrix(y_test, y_pred))

逻辑回归结果

  • 在处理多分类问题时,可以直接使用逻辑回归的默认设置(一对多策略),而无需手动转换标签。
  • 逻辑回归的性能受特征选择和模型参数的影响,因此在实际应用中可能需要进行特征工程和模型调优。

逻辑回归是一种简单而有效的分类方法,特别适用于二分类问题。通过在鸢尾花数据集上的应用,我们展示了逻辑回归的基本原理和步骤,并通过准确率、分类报告和混淆矩阵评估了模型效果。逻辑回归不仅适用于二分类问题,还可以通过一对多策略扩展到多分类问题。然而,在实际应用中,可能需要结合特征工程和模型调优来提高模型的性能。

线性判别分析(LDA)

在机器学习和统计学领域,线性判别分析(Linear Discriminant Analysis, LDA)是一种广泛应用的分类方法,特别适用于具有高斯分布特征的数据集。LDA通过寻找能够最大化类别间差异同时最小化类别内差异的线性组合特征,来实现对数据的分类。本文将介绍LDA的基本原理,并通过在鸢尾花数据集上的应用展示其效果。

线性判别分析(LDA)原理

LDA的核心思想是基于类内方差最小化和类间方差最大化来找到一个线性决策边界。具体来说,LDA试图找到一个投影方向,使得投影后的数据点能够按照类别尽可能地分开。这通常涉及到计算每个类别的均值向量和协方差矩阵,然后利用这些信息来找到最佳的投影方向。

LDA假设数据服从高斯分布,并且每个类别的协方差矩阵是相同的(这被称为LDA的“同协方差”假设)。在这些假设下,LDA能够找到一个线性变换,将数据从原始特征空间映射到一个新的低维空间,在这个空间中,类别之间的可分性最大化。

对于多分类问题,LDA会计算每个类别的后验概率,并选择具有最高后验概率的类别作为预测结果。

在鸢尾花数据集上的应用

下面,我们将通过Python代码展示如何在鸢尾花数据集上应用LDA,并评估其效果。鸢尾花数据集是一个经典的多分类数据集,包含150个样本,每个样本有4个特征,分别对应鸢尾花的萼片长度、萼片宽度、花瓣长度和花瓣宽度。

步骤

  1. 加载数据集:使用sklearn.datasets加载鸢尾花数据集。
  2. 拆分数据集:将数据集拆分为训练集和测试集。
  3. 创建LDA模型:使用sklearn.discriminant_analysis.LinearDiscriminantAnalysis创建LDA模型。
  4. 训练模型:使用训练集训练LDA模型。
  5. 进行预测:使用测试集进行预测,并计算准确率。
  6. 可视化分类结果:使用LDA变换后的前两个主成分对测试集进行分类结果的可视化。
  7. 评估结果:通过混淆矩阵和分类报告评估模型效果。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import numpy as np
import pandas as pd
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
import matplotlib.pyplot as plt
import seaborn as sns

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

# 拆分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 创建LDA模型
lda = LinearDiscriminantAnalysis()

# 训练模型
lda.fit(X_train, y_train)

# 进行预测
y_pred = lda.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.2f}')

# 可视化分类结果
lda_transformed_test = lda.transform(X_test)[:, :2] # 对测试集进行LDA变换,取前两个主成分

plt.figure(figsize=(10, 6))
sns.scatterplot(x=lda_transformed_test[:, 0], y=lda_transformed_test[:, 1], hue=y_test, palette='viridis', edgecolor='k', linewidth=0.5, legend='full')
plt.title('LDA Classification of Iris Dataset (Test Set)')
plt.xlabel('LDA Component 1')
plt.ylabel('LDA Component 2')
plt.legend(title='True Class')
plt.show()

# 计算混淆矩阵和分类报告
conf_matrix = confusion_matrix(y_test, y_pred)
print('Confusion Matrix:')
print(conf_matrix)

class_report = classification_report(y_test, y_pred, target_names=iris.target_names)
print('Classification Report:')
print(class_report)

线性判别分析结果
线性判别分析(LDA)是一种简单而有效的分类方法,特别适用于具有高斯分布特征的数据集。通过在鸢尾花数据集上的应用,我们展示了LDA的基本原理和步骤,并通过准确率、可视化分类结果、混淆矩阵和分类报告评估了模型效果。LDA不仅能够提供分类结果,还能够通过降维技术实现数据的可视化,这对于理解数据的内在结构和分类器的性能非常有帮助。然而,在实际应用中,LDA的性能可能受到数据分布和特征选择的影响,因此在进行模型选择时需要进行充分的评估和比较。

支持向量机(SVM)

在机器学习的广阔领域中,支持向量机(Support Vector Machine, SVM)以其强大的分类能力和坚实的理论基础,成为了众多分类任务中的首选算法之一。SVM通过寻找一个最优超平面,使得不同类别的样本在该超平面两侧尽可能分开,从而实现对数据的分类。本文将详细介绍SVM的基本原理,并通过在鸢尾花数据集上的应用,展示其分类效果。

支持向量机原理

SVM的核心思想是找到一个最优超平面,该超平面能够最大化两类样本之间的间隔(margin)。在二分类问题中,SVM试图找到一个线性决策边界,使得两类样本分别位于该边界的两侧,并且距离边界最近的样本(即支持向量)到边界的距离最大。对于非线性问题,SVM通过引入核函数(如高斯核、多项式核等),将输入数据映射到一个高维特征空间,在该空间中寻找最优线性超平面。

SVM的决策函数可以表示为:

$$ f(x) = \text{sign}(\mathbf{w}^T \mathbf{x} + b) $$

其中,$\mathbf{w}$ 是权重向量,$b$ 是偏置项,$\mathbf{x}$ 是输入样本。SVM的训练过程就是求解最优权重向量和偏置项的过程,使得分类间隔最大化。

在SVM中,正则化参数 $C$ 用于控制模型的复杂度和分类间隔之间的权衡。较小的 $C$ 值会导致更大的间隔和更多的分类错误(即欠拟合),而较大的 $C$ 值则会减小间隔并减少分类错误(但可能导致过拟合)。

步骤

  1. 加载数据集:使用sklearn.datasets加载鸢尾花数据集。
  2. 选择特征:为了可视化方便,我们选择前两个特征(花萼长度和花萼宽度)。
  3. 拆分数据集:将数据集拆分为训练集和测试集。
  4. 创建SVM模型:使用sklearn.svm.SVC创建SVM模型,并选择线性核。
  5. 训练模型:使用训练集训练SVM模型。
  6. 进行预测:使用测试集进行预测,并计算准确率。
  7. 评估结果:通过混淆矩阵和分类报告评估模型效果。
  8. 可视化分类结果:使用散点图展示测试集的分类结果,并为部分点添加注释以指示预测正确性。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import numpy as np
import pandas as pd
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
import matplotlib.pyplot as plt
import seaborn as sns

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

# 为了可视化,我们选择前两个特征(花萼长度和花萼宽度)
X_vis = X[:, :2]

# 拆分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_vis, y, test_size=0.3, random_state=42)

# 创建SVM模型,使用线性核
model = SVC(kernel='linear', C=1.0)

# 训练模型
model.fit(X_train, y_train)

# 进行预测
y_pred = model.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.2f}')

# 计算混淆矩阵和分类报告
conf_matrix = confusion_matrix(y_test, y_pred)
print('Confusion Matrix:')
print(conf_matrix)

class_report = classification_report(y_test, y_pred, target_names=iris.target_names)
print('Classification Report:')
print(class_report)

# 可视化分类结果
plt.figure(figsize=(10, 6))

# 使用seaborn的scatterplot进行可视化
palette = sns.color_palette("hsv", 3) # 生成一个包含3种颜色的调色板
scatter = sns.scatterplot(x=X_test[:, 0], y=X_test[:, 1], hue=y_test, palette=palette, legend='full', s=100, edgecolor='k', linewidth=0.5)

# 为部分点添加注释以指示预测正确性
np.random.seed(42)
indices_to_annotate = np.random.choice(range(len(y_test)), size=10, replace=False) # 选择10个随机点

for idx in indices_to_annotate:
true_label = y_test[idx]
pred_label = y_pred[idx]
if true_label == pred_label:
text = f'True: {true_label}\nPred: {pred_label} (Correct)'
color = 'green' # 使用绿色表示正确预测
else:
text = f'True: {true_label}\nPred: {pred_label} (Incorrect)'
color = 'red' # 使用红色表示错误预测

plt.text(X_test[idx, 0], X_test[idx, 1], text, fontsize=9, color=color, ha='right', va='bottom')

# 添加标题和标签
plt.title('SVM Classification of Iris Dataset (2 Features)')
plt.xlabel('Sepal Length')
plt.ylabel('Sepal Width')

# 显示图例
plt.legend(title='True Label')

# 显示图形
plt.show()

支持向量机结果
支持向量机(SVM)是一种强大的分类算法,特别适用于高维数据的分类问题。通过在鸢尾花数据集上的应用,我们展示了SVM的基本原理和步骤,并通过准确率、混淆矩阵、分类报告和可视化分类结果评估了模型效果。SVM不仅能够提供分类结果,还能够通过核函数技术处理非线性问题,这使得它在众多分类任务中表现出色。然而,在实际应用中,SVM的性能可能受到数据分布、特征选择和核函数选择等因素的影响,因此在进行模型选择时需要进行充分的评估和比较。

决策树

决策树是一种直观且强大的机器学习算法,广泛应用于分类和回归任务中。它通过递归地分割特征空间来构建树形结构,每个内部节点代表一个特征上的测试,每个分支代表测试结果,而每个叶节点则代表一个类别或输出值。本文将介绍决策树的基本原理,并通过在鸢尾花数据集上的应用展示其效果。看剩饭,康密是狼,康熙是狗。

决策树原理

决策树的核心思想是通过一系列的问题(即特征上的测试)来将数据集分割成不同的子集,直到每个子集都属于同一个类别或满足某个停止条件。构建决策树的过程通常包括以下几个步骤:

  1. 特征选择:选择最优特征进行分割。常用的选择标准包括信息增益(ID3算法)、信息增益比(C4.5算法)和基尼指数(CART算法)。

  2. 决策树生成:根据选择的最优特征,将数据集分割成子集,并递归地在每个子集上重复上述过程,直到满足停止条件(如子集为空、子集中所有样本属于同一类别、达到最大深度等)。

  3. 决策树剪枝:为了防止过拟合,可以对生成的决策树进行剪枝,即去掉一些不必要的节点,使模型更加简洁。

决策树的优点包括易于理解和解释、能够处理非线性关系、不需要特征缩放等。然而,它也可能受到过拟合、对噪声敏感和缺乏平滑性等问题的困扰。

步骤

  1. 加载数据集:使用sklearn.datasets加载鸢尾花数据集。
  2. 拆分数据集:将数据集拆分为训练集和测试集。
  3. 初始化决策树分类器:使用sklearn.tree.DecisionTreeClassifier创建决策树分类器。
  4. 训练模型:使用训练集训练决策树模型。
  5. 预测测试集:使用测试集进行预测,并计算准确率、分类报告和混淆矩阵。
  6. 可视化决策树:使用sklearn.tree.plot_tree可视化决策树的结构。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
import matplotlib.pyplot as plt

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

# 将数据集分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 初始化决策树分类器
clf = DecisionTreeClassifier(random_state=42)

# 训练模型
clf.fit(X_train, y_train)

# 预测测试集
y_pred = clf.predict(X_test)

# 评估模型
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.2f}')
print('Classification Report:')
print(classification_report(y_test, y_pred, target_names=iris.target_names))
print('Confusion Matrix:')
print(confusion_matrix(y_test, y_pred))

# 可视化决策树
plt.figure(figsize=(20,10))
plot_tree(clf, feature_names=iris.feature_names, class_names=iris.target_names, filled=True)
plt.show()

决策树结果
补充实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
from math import log
import operator

def calcShannonEnt(dataSet): # 计算数据的熵(entropy)
numEntries=len(dataSet) # 数据条数
labelCounts={}
for featVec in dataSet:
currentLabel=featVec[-1] # 每行数据的最后一个字(类别)
if currentLabel not in labelCounts.keys():
labelCounts[currentLabel]=0
labelCounts[currentLabel]+=1 # 统计有多少个类以及每个类的数量
shannonEnt=0
for key in labelCounts:
prob=float(labelCounts[key])/numEntries # 计算单个类的熵值
shannonEnt-=prob*log(prob,2) # 累加每个类的熵值
return shannonEnt

def createDataSet1(): # 创造示例数据
dataSet = [['长', '粗', '男'],
['短', '粗', '男'],
['短', '粗', '男'],
['长', '细', '女'],
['短', '细', '女'],
['短', '粗', '女'],
['长', '粗', '女'],
['长', '粗', '女']]
labels = ['头发','声音'] #两个特征
return dataSet,labels

def splitDataSet(dataSet,axis,value): # 按某个特征分类后的数据
retDataSet=[]
for featVec in dataSet:
if featVec[axis]==value:
reducedFeatVec =featVec[:axis]
reducedFeatVec.extend(featVec[axis+1:])
retDataSet.append(reducedFeatVec)
return retDataSet

def chooseBestFeatureToSplit(dataSet): # 选择最优的分类特征
numFeatures = len(dataSet[0])-1
baseEntropy = calcShannonEnt(dataSet) # 原始的熵
bestInfoGain = 0
bestFeature = -1
for i in range(numFeatures):
featList = [example[i] for example in dataSet]
uniqueVals = set(featList)
newEntropy = 0
for value in uniqueVals:
subDataSet = splitDataSet(dataSet,i,value)
prob =len(subDataSet)/float(len(dataSet))
newEntropy +=prob*calcShannonEnt(subDataSet) # 按特征分类后的熵
infoGain = baseEntropy - newEntropy # 原始熵与按特征分类后的熵的差值
if (infoGain>bestInfoGain): # 若按某特征划分后,熵值减少的最大,则次特征为最优分类特征
bestInfoGain=infoGain
bestFeature = i
return bestFeature

def majorityCnt(classList): #按分类后类别数量排序,比如:最后分类为2男1女,则判定为男;
classCount={}
for vote in classList:
if vote not in classCount.keys():
classCount[vote]=0
classCount[vote]+=1
sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
return sortedClassCount[0][0]

def createTree(dataSet,labels):
classList=[example[-1] for example in dataSet] # 类别:男或女
if classList.count(classList[0])==len(classList):
return classList[0]
if len(dataSet[0])==1:
return majorityCnt(classList)
bestFeat=chooseBestFeatureToSplit(dataSet) #选择最优特征
bestFeatLabel=labels[bestFeat]
myTree={bestFeatLabel:{}} #分类结果以字典形式保存
del(labels[bestFeat])
featValues=[example[bestFeat] for example in dataSet]
uniqueVals=set(featValues)
for value in uniqueVals:
subLabels=labels[:]
myTree[bestFeatLabel][value]=createTree(splitDataSet\
(dataSet,bestFeat,value),subLabels)
return myTree


if __name__=='__main__':
dataSet, labels=createDataSet1() # 创造示列数据
print(createTree(dataSet, labels)) # 输出决策树模型结果

运行结果:

1
{'声音': {'粗': {'头发': {'短': '男', '长': '女'}}, '细': '女'}}

决策树是一种直观且强大的机器学习算法,特别适用于分类任务。通过在鸢尾花数据集上的应用,我们展示了决策树的基本原理和步骤,并通过准确率、分类报告、混淆矩阵和可视化决策树评估了模型效果。决策树不仅能够提供分类结果,还能够通过可视化技术展示模型的决策过程,这对于理解数据的内在结构和分类器的性能非常有帮助。然而,在实际应用中,我们还需要注意决策树的过拟合问题,并尝试通过剪枝、限制树的最大深度等方法来提高模型的泛化能力。

随机森林

随机森林是一种集成学习方法,通过构建多个决策树并综合它们的预测结果来提高模型的准确性和鲁棒性。本文将详细介绍随机森林的基本原理,并通过在鸢尾花数据集上的应用来展示其效果。鸢尾花数据集是一个经典的多分类数据集,包含150个样本,每个样本有4个特征,分别对应鸢尾花的萼片长度、萼片宽度、花瓣长度和花瓣宽度。然而,为了可视化的目的,本文将仅使用前两个特征(萼片长度和萼片宽度)。

随机森林原理

随机森林的核心思想是利用多个决策树的预测结果进行投票或平均,以减少单一模型的过拟合风险并提高整体预测性能。具体来说,随机森林的构建过程包括以下几个关键步骤:

  1. 样本抽样:从原始数据集中随机抽取多个子样本集,通常使用有放回的抽样方法(即Bootstrap抽样),以确保每个子样本集都是独立的。

  2. 特征选择:在构建每棵决策树时,不是使用全部特征,而是从原始特征集中随机选择一部分特征作为候选特征。这种策略有助于增加模型的多样性,进一步减少过拟合。

  3. 构建决策树:对每个子样本集,使用候选特征构建决策树。决策树的构建过程与标准决策树算法相同,但通常会限制树的最大深度、最小样本数等参数,以防止单棵树过于复杂。

  4. 集成预测:对于分类任务,随机森林通过投票机制确定最终预测结果;对于回归任务,则通过平均各树的预测结果来得到最终输出。

随机森林的优点包括:能够处理高维数据、不易过拟合、对缺失数据不敏感、能够评估变量的重要性等。然而,它也可能受到计算量大、模型解释性较差等问题的困扰。

在鸢尾花数据集上的应用

下面,我们将通过Python代码展示如何在鸢尾花数据集上应用随机森林,并评估其效果。

步骤

  1. 加载数据集:使用sklearn.datasets加载鸢尾花数据集,并选择前两个特征进行可视化。
  2. 拆分数据集:将数据集拆分为训练集和测试集。
  3. 创建随机森林分类器:使用sklearn.ensemble.RandomForestClassifier创建随机森林分类器,并设置相关参数。
  4. 训练模型:使用训练集训练随机森林模型。
  5. 预测测试集:使用测试集进行预测,并计算准确率、混淆矩阵和分类报告。
  6. 可视化分类结果:使用matplotlibseaborn可视化分类结果和决策边界(尽管随机森林是复杂的非线性分类器,通常不绘制决策边界,但为了演示目的,我们可以使用网格搜索和预测来近似边界)。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import numpy as np
import pandas as pd
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
import matplotlib.pyplot as plt
import seaborn as sns

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

# 为了可视化,我们选择前两个特征(花萼长度和花萼宽度)
X_vis = X[:, :2]

# 拆分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_vis, y, test_size=0.3, random_state=42)

# 创建随机森林分类器
model = RandomForestClassifier(n_estimators=100, random_state=42)

# 训练模型
model.fit(X_train, y_train)

# 进行预测
y_pred = model.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.2f}')

# 计算混淆矩阵
conf_matrix = confusion_matrix(y_test, y_pred)
print('Confusion Matrix:')
print(conf_matrix)

# 计算分类报告
class_report = classification_report(y_test, y_pred, target_names=iris.target_names)
print('Classification Report:')
print(class_report)

# 可视化分类结果
plt.figure(figsize=(10, 6))

# 使用seaborn的scatterplot来可视化分类结果
sns.scatterplot(x=X_test[:, 0], y=X_test[:, 1], hue=y_test, palette='viridis', legend='full', alpha=0.7)

# 在测试集上绘制预测结果的边界(近似表示)
x_min, x_max = X_test[:, 0].min() - 1, X_test[:, 0].max() + 1
y_min, y_max = X_test[:, 1].min() - 1, X_test[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.01), np.arange(y_min, y_max, 0.01))
Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)

# 绘制决策边界(近似)
plt.contourf(xx, yy, Z, alpha=0.3, cmap='viridis')

# 添加标题和标签
plt.title('Random Forest Classification of Iris Dataset')
plt.xlabel('Sepal Length')
plt.ylabel('Sepal Width')

# 显示图例
plt.legend(title='Class')

# 显示图形
plt.show()

随机森林结果

随机森林是一种强大的集成学习方法,通过构建多个决策树并综合它们的预测结果来提高模型的准确性和鲁棒性。通过在鸢尾花数据集上的应用,我们展示了随机森林的基本原理和步骤,并通过准确率、混淆矩阵、分类报告和可视化分类结果评估了模型效果。随机森林不仅能够提供分类结果,还能够通过可视化技术展示模型的分类效果(尽管决策边界是近似表示的)。然而,在实际应用中,我们还需要注意随机森林的计算量问题,并尝试通过调整参数(如树的数量、最大深度等)来优化模型的性能。

K近邻

K近邻(K-Nearest Neighbors,简称KNN)是一种简单而直观的监督学习算法,广泛应用于分类和回归任务中。其核心思想是,给定一个待分类的样本,通过计算它与训练集中所有样本的距离,找出距离它最近的K个样本(即邻居),然后根据这些邻居的类别来预测待分类样本的类别(对于分类任务)或输出这些邻居的目标值的平均值(对于回归任务)。本文将介绍KNN的基本原理,并通过在鸢尾花数据集上的应用展示其效果。

KNN原理

KNN算法的核心步骤包括:

  1. 计算距离:选择一种距离度量方法(如欧氏距离、曼哈顿距离等),计算待分类样本与训练集中每个样本的距离。

  2. 选择邻居:根据计算出的距离,选择距离待分类样本最近的K个样本作为邻居。

  3. 预测类别:对于分类任务,根据邻居的类别进行投票,选择出现次数最多的类别作为待分类样本的预测类别;对于回归任务,则计算邻居目标值的平均值作为预测结果。

KNN算法的优点包括简单易懂、易于实现、无需训练阶段等。然而,它也可能受到计算量大、对不平衡数据集敏感、选择K值困难等问题的困扰。

在鸢尾花数据集上的应用

下面,我们将通过Python代码展示如何在鸢尾花数据集上应用KNN算法,并评估其效果。鸢尾花数据集是一个经典的多分类数据集,包含150个样本,每个样本有4个特征,分别对应鸢尾花的萼片长度、萼片宽度、花瓣长度和花瓣宽度。为了可视化方便,我们将仅使用前两个特征(萼片长度和萼片宽度)。

步骤

  1. 加载数据集:使用sklearn.datasets加载鸢尾花数据集。
  2. 选择特征:为了可视化,选择前两个特征(萼片长度和萼片宽度)。
  3. 拆分数据集:将数据集拆分为训练集和测试集。
  4. 创建KNN模型:使用sklearn.neighbors.KNeighborsClassifier创建KNN分类器,并选择K值(例如,K=3)。
  5. 训练模型:使用训练集训练KNN模型。
  6. 预测测试集:使用测试集进行预测,并计算准确率、混淆矩阵和分类报告。
  7. 可视化分类结果:使用matplotlibseaborn可视化分类结果,包括散点图和预测错误的点。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import numpy as np
import pandas as pd
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
import matplotlib.pyplot as plt
import seaborn as sns

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

# 为了可视化,我们选择前两个特征(花萼长度和花萼宽度)
X_vis = X[:, :2]

# 拆分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_vis, y, test_size=0.3, random_state=42)

# 创建KNN模型(选择k=3作为示例)
knn = KNeighborsClassifier(n_neighbors=3)

# 训练模型
knn.fit(X_train, y_train)

# 进行预测
y_pred = knn.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.2f}')

# 计算混淆矩阵和分类报告
conf_matrix = confusion_matrix(y_test, y_pred)
print('Confusion Matrix:')
print(conf_matrix)

class_report = classification_report(y_test, y_pred, target_names=iris.target_names)
print('Classification Report:')
print(class_report)

# 可视化分类结果
plt.figure(figsize=(10, 6))
sns.scatterplot(x=X_test[:, 0], y=X_test[:, 1], hue=y_test, palette='viridis', legend='full', alpha=0.7)

# 找出预测错误的点,并添加文本标签
incorrect_indices = np.where(y_pred != y_test)[0]
for idx in incorrect_indices[:5]: # 限制为前5个错误预测,以避免图形过于拥挤
plt.text(X_test[idx, 0], X_test[idx, 1], f'Pred: {y_pred[idx]}\nTrue: {y_test[idx]}',
color='red', fontsize=9, ha='right', va='bottom')

# 添加标题和标签
plt.title('KNN Classification of Iris Dataset')
plt.xlabel('Sepal Length')
plt.ylabel('Sepal Width')
plt.legend(title='True Class')
plt.show()

knn结果

KNN是一种简单而有效的监督学习算法,特别适用于分类任务。通过在鸢尾花数据集上的应用,我们展示了KNN的基本原理和步骤,并通过准确率、混淆矩阵、分类报告和可视化分类结果评估了模型效果。KNN不仅能够提供分类结果,还能够通过可视化技术展示模型的分类性能。然而,在实际应用中,我们还需要注意KNN的计算量大、对不平衡数据集敏感和选择K值困难等问题,并尝试通过优化距离度量方法、使用近似算法和进行交叉验证等方法来提高模型的性能和效率。

神经网络

神经网络,作为深度学习的基础,是一种模仿生物神经网络结构和功能的计算模型。它通过多层神经元之间的连接,能够学习并提取数据中的复杂特征,进而实现分类、等任务回归。本文将介绍神经网络的基本原理,并通过在鸢尾花数据集上的应用展示其效果。鸢尾花数据集是一个经典的多分类数据集,包含150个样本,每个样本有4个特征,分别对应鸢尾花的萼片长度、萼片宽度、花瓣长度和花瓣宽度。

神经网络原理

神经网络由输入层、隐藏层和输出层组成。每一层都包含多个神经元,神经元之间通过权重和偏置进行连接。在训练过程中,神经网络通过反向传播算法不断调整这些权重和偏置,以最小化损失函数,从而实现对输入数据的准确预测。

  1. 输入层:接收原始数据,并将其传递给下一层。

  2. 隐藏层:对输入数据进行非线性变换,提取数据中的特征。隐藏层的数量和每层的神经元数量可以根据任务复杂度进行调整。

  3. 输出层:根据提取的特征,输出预测结果。对于分类任务,输出层通常使用softmax激活函数,将输出转换为概率分布。

  4. 激活函数:增加神经网络的非线性,常用的激活函数包括ReLU、sigmoid和tanh等。

  5. 损失函数:衡量预测结果与真实结果之间的差异,常用的损失函数包括均方误差(MSE)、交叉熵损失等。

  6. 优化器:根据损失函数的梯度,更新神经网络的权重和偏置,常用的优化器包括SGD、Adam等。

在鸢尾花数据集上的应用

下面,我们将通过Python代码展示如何在鸢尾花数据集上应用神经网络,并评估其效果。

步骤

  1. 加载数据集:使用sklearn.datasets加载鸢尾花数据集。

  2. 数据预处理:将标签转换为one-hot编码,标准化特征值。

  3. 拆分数据集:将数据集拆分为训练集和测试集。

  4. 初始化神经网络模型:使用tensorflow.keras.models.Sequential创建神经网络模型,并添加输入层、隐藏层和输出层。

  5. 编译模型:指定优化器、损失函数和评估指标。

  6. 训练模型:使用训练集训练神经网络模型。

  7. 评估模型:使用测试集评估模型性能,并打印分类报告。

  8. 可视化分类结果:选择前两个特征进行可视化,展示真实标签和预测标签的分类结果。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.utils import to_categorical
import matplotlib.pyplot as plt
from sklearn.metrics import classification_report

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

# 将标签转换为one-hot编码
y = to_categorical(y)

# 标准化特征值
scaler = StandardScaler()
X = scaler.fit_transform(X)

# 将数据集分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 初始化神经网络模型
model = Sequential()
model.add(Dense(10, input_dim=4, activation='relu')) # 输入层和第一个隐藏层,4个输入特征,10个神经元
model.add(Dense(10, activation='relu')) # 第二个隐藏层,10个神经元
model.add(Dense(3, activation='softmax')) # 输出层,3个类别,使用softmax激活函数

# 编译模型
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# 训练模型
model.fit(X_train, y_train, epochs=100, batch_size=5, verbose=1)

# 评估模型
loss, accuracy = model.evaluate(X_test, y_test, verbose=0)
print(f'Test Accuracy: {accuracy:.2f}')

# 预测测试集
y_pred = model.predict(X_test)
# 将预测结果转换为类别标签(argmax取最大值索引)
y_pred_classes = np.argmax(y_pred, axis=1)
# 将真实标签也转换为类别标签(因为y_test已经是one-hot编码,所以需要转换回来)
y_true_classes = np.argmax(y_test, axis=1)

# 打印分类报告
print('Classification Report:')
print(classification_report(y_true_classes, y_pred_classes, target_names=iris.target_names))

# 可视化分类结果(选择前两个特征进行可视化)
# 提取前两个特征用于可视化
X_test_vis = X_test[:, :2]

# 获取真实标签和预测标签的类别索引
y_true_classes = np.argmax(y_test, axis=1)
y_pred_classes = np.argmax(y_pred, axis=1)

# 设置颜色映射
cmap = plt.cm.get_cmap('viridis', 3) # 使用viridis颜色映射,并为3个类别分配颜色
colors = cmap(np.arange(3))

# 创建一个散点图,用于可视化真实标签的分类结果
plt.figure(figsize=(10, 6))
for i, color in enumerate(colors):
idx = np.where(y_true_classes == i)[0]
plt.scatter(X_test_vis[idx, 0], X_test_vis[idx, 1], c=color, label=iris.target_names[i], edgecolor='k', s=50)
plt.title('True Labels Classification')
plt.xlabel(iris.feature_names[0])
plt.ylabel(iris.feature_names[1])
plt.legend()
plt.grid(True)
plt.show()

# 创建一个散点图,用于可视化预测标签的分类结果
plt.figure(figsize=(10, 6))
for i, color in enumerate(colors):
idx = np.where(y_pred_classes == i)[0]
plt.scatter(X_test_vis[idx, 0], X_test_vis[idx, 1], c=color, label=iris.target_names[i], edgecolor='w', linewidth=1.5, s=50, alpha=0.7)
plt.title('Predicted Labels Classification')
plt.xlabel(iris.feature_names[0])
plt.ylabel(iris.feature_names[1])
plt.legend()
plt.grid(True)
plt.show()

神经网络结果
注意:代码有一处内存泄漏,和两处可能是格式报错,均不影响正常运行

神经网络作为一种强大的机器学习算法,特别适用于处理复杂的数据和任务。通过在鸢尾花数据集上的应用,我们展示了神经网络的基本原理和步骤,并通过测试准确率、分类报告和可视化分类结果评估了模型效果。神经网络不仅能够提供分类结果,还能够通过可视化技术展示模型的分类效果,这对于理解数据的内在结构和分类器的性能非常有帮助。然而,在实际应用中,我们还需要注意神经网络的过拟合问题,并尝试通过添加正则化项、使用dropout等技术来提高模型的泛化能力。

朴素贝叶斯

朴素贝叶斯是一种基于贝叶斯定理和特征条件独立假设的分类算法。它通过计算给定特征条件下各类别的概率来进行分类,具有计算高效、易于实现和解释性强等特点。本文将介绍朴素贝叶斯的基本原理,并通过在鸢尾花数据集上的应用展示其效果。

朴素贝叶斯原理

朴素贝叶斯算法的核心思想是:对于给定的输入特征向量,通过计算每个类别在该特征向量下的条件概率,并选择具有最大条件概率的类别作为预测结果。为了简化计算,朴素贝叶斯假设各个特征之间是相互独立的,即一个特征的出现概率不依赖于其他特征的出现概率。

具体来说,假设我们有一个数据集,其中包含m个样本和n个特征,每个样本都有一个类别标签。朴素贝叶斯算法会计算每个类别在每个特征上的条件概率分布,然后根据这些概率分布和贝叶斯定理来计算给定特征向量下每个类别的后验概率。最后,选择具有最大后验概率的类别作为预测结果。

在实际应用中,朴素贝叶斯算法有多种变体,如高斯朴素贝叶斯(适用于特征为连续值的情况)、多项式朴素贝叶斯(适用于特征为离散值且服从多项式分布的情况)和伯努利朴素贝叶斯(适用于特征为二值化的情况)。

在鸢尾花数据集上的应用

下面,我们将通过Python代码展示如何在鸢尾花数据集上应用朴素贝叶斯算法,并评估其效果。鸢尾花数据集是一个经典的多分类数据集,包含150个样本,每个样本有4个特征,分别对应鸢尾花的萼片长度、萼片宽度、花瓣长度和花瓣宽度。

步骤

  1. 加载数据集:使用sklearn.datasets加载鸢尾花数据集。
  2. 拆分数据集:将数据集拆分为训练集和测试集。
  3. 创建朴素贝叶斯模型:使用sklearn.naive_bayes.GaussianNB创建高斯朴素贝叶斯模型(因为鸢尾花数据集的特征为连续值)。
  4. 训练模型:使用训练集训练朴素贝叶斯模型。
  5. 预测测试集:使用测试集进行预测,并计算准确率、混淆矩阵和分类报告。
  6. 可视化分类结果:使用matplotlibseaborn可视化分类后的数据点。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import numpy as np
import pandas as pd
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
import matplotlib.pyplot as plt
import seaborn as sns

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

# 为了可视化,我们选择前两个特征(花萼长度和花萼宽度)
X_vis = X[:, :2]

# 拆分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 创建朴素贝叶斯模型
model = GaussianNB()

# 训练模型
model.fit(X_train, y_train)

# 进行预测
y_pred = model.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.2f}')

# 计算混淆矩阵和分类报告
conf_matrix = confusion_matrix(y_test, y_pred)
print('Confusion Matrix:')
print(conf_matrix)

class_report = classification_report(y_test, y_pred, target_names=iris.target_names)
print('Classification Report:')
print(class_report)

# 可视化分类结果
plt.figure(figsize=(10, 6))
sns.scatterplot(x=X_test[:, 0], y=X_test[:, 1], hue=y_test, palette='viridis')

# 注意:style参数不适用于此处的预测结果可视化,因为它通常用于映射到少量的离散样式。
# 我们仅使用hue参数来区分不同的真实类别,并通过观察散点图的颜色来间接了解预测结果。

# 显示标题和标签
plt.title('Naive Bayes Classification of Iris Dataset')
plt.xlabel('Sepal Length')
plt.ylabel('Sepal Width')

# 显示图例(由于使用了hue参数,seaborn会自动添加图例)
plt.legend(title='Class', labels=iris.target_names)

# 显示图形
plt.show()

朴素贝叶斯结果

朴素贝叶斯算法是一种简单而有效的分类算法,特别适用于特征之间相对独立且特征数量较多的情况。通过在鸢尾花数据集上的应用,我们展示了朴素贝叶斯算法的基本原理和步骤,并通过准确率、混淆矩阵、分类报告和可视化分类结果评估了模型效果。虽然朴素贝叶斯算法在某些复杂场景下可能不如其他算法(如支持向量机、神经网络等)表现优异,但在许多实际应用中,它仍然是一种值得尝试和考虑的算法。

感知机

感知机(Perceptron)是一种线性分类模型,起源于神经网络领域,是二分类问题的基本单元。它通过计算输入特征的线性组合并应用一个激活函数(在此为符号函数)来预测输出类别。本文将介绍感知机的基本原理,并通过在鸢尾花数据集上的应用展示其效果。鸢尾花数据集是一个经典的多分类数据集,但在此例中,我们将其转换为二分类问题以适配感知机模型。

感知机原理

感知机模型的核心思想是通过一个线性决策边界将特征空间划分为两个区域,每个区域对应一个类别。具体来说,感知机接收一个输入向量 $X$,并计算其加权和加上偏置 $b$,即 $z = W^T \cdot X + b$。然后,应用符号函数(sign function)将 $z$ 映射到输出类别上,通常映射为 $-1$ 和 $1$(或 $0$ 和 $1$,取决于具体实现)。

感知机的训练过程是一个迭代过程,旨在通过调整权重 $W$ 和偏置 $b$ 来最小化分类错误。在每次迭代中,感知机会遍历训练集中的所有样本,计算每个样本的预测输出,并根据预测错误更新权重和偏置。这种更新通常基于梯度下降法或其变体。

在鸢尾花数据集上的应用

下面,我们将通过Python代码展示如何在鸢尾花数据集上应用感知机,并评估其效果。由于感知机是二分类模型,我们需要从鸢尾花数据集中选择两个类别进行训练。

步骤

  1. 加载数据集:使用sklearn.datasets加载鸢尾花数据集。
  2. 预处理数据集:选择类别0和类别1,排除类别2,以适配二分类问题。
  3. 拆分数据集:将数据集拆分为训练集和测试集。
  4. 特征缩放:使用StandardScaler对特征进行缩放,以提高模型性能。
  5. 实现感知机算法:创建一个简单的感知机类,包括初始化、训练(fit)和预测(predict)方法。
  6. 训练模型:使用训练集训练感知机模型。
  7. 预测测试集:使用测试集进行预测,并计算准确率、混淆矩阵和分类报告。
  8. 可视化分类结果:使用前两个特征(花萼长度和花萼宽度)绘制散点图,并显示决策边界。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import numpy as np
import pandas as pd
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import confusion_matrix, accuracy_score, classification_report
import matplotlib.pyplot as plt

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

# 为了二分类问题,我们选择类别0和类别1,将类别2排除在外
X = X[y != 2]
y = y[y != 2]

# 拆分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 特征缩放
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

# 感知机算法实现(简单版本,不带权重衰减)
class Perceptron:
def __init__(self, learning_rate=0.01, n_iters=1000):
self.learning_rate = learning_rate
self.n_iters = n_iters
self.weights = None
self.bias = None

def fit(self, X, y):
n_samples, n_features = X.shape
self.weights = np.zeros(n_features)
self.bias = 0

y_ = np.where(y <= 0, -1, 1) # 将标签转换为-1和1

for _ in range(self.n_iters):
for idx, x_i in enumerate(X):
linear_output = np.dot(x_i, self.weights) + self.bias
y_predicted = np.sign(linear_output)

# 更新权重和偏置
update = self.learning_rate * (y_[idx] - y_predicted)
self.weights += update * x_i
self.bias += update

def predict(self, X):
linear_output = np.dot(X, self.weights) + self.bias
y_predicted = np.sign(linear_output)
return np.where(y_predicted == 1, 1, 0) # 将预测结果转换回0和1

# 创建感知机模型实例
perceptron = Perceptron(learning_rate=0.01, n_iters=1000)

# 训练模型
perceptron.fit(X_train, y_train)

# 进行预测
y_pred = perceptron.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.2f}')

# 计算混淆矩阵
cm = confusion_matrix(y_test, y_pred)
print('Confusion Matrix:')
print(cm)

# 输出分类报告,包括精确率、召回率和F1分数
print('Classification Report:')
print(classification_report(y_test, y_pred, target_names=iris.target_names[:2])) # 只包含前两个类别

# 可视化分类结果
plt.figure(figsize=(10, 6))

# 使用不同的颜色表示不同的真实类别
colors = ['blue' if label == 0 else 'red' for label in y_test]

# 绘制散点图
plt.scatter(X_test[:, 0], X_test[:, 1], c=colors, edgecolor='k', linewidth=0.5)

# 绘制决策边界(线性分类器的直线)
# 决策边界的方程是 weights[0]*x1 + weights[1]*x2 + bias = 0
# 我们可以解出 x2 = -(weights[0]*x1 + bias) / weights[1]
x_values = np.linspace(X_test[:, 0].min() - 1, X_test[:, 0].max() + 1, 400)
y_values = -(perceptron.weights[0] * x_values + perceptron.bias) / perceptron.weights[1]

# 绘制决策边界线
plt.plot(x_values, y_values, 'k--', label='Decision Boundary')

# 添加标题和标签
plt.title('Perceptron Classification of Iris Dataset (Binary Target)')
plt.xlabel('Sepal Length')
plt.ylabel('Sepal Width')
plt.legend()

# 显示图形
plt.show()

感知机结果

感知机是一种简单而有效的线性分类模型,特别适用于二分类问题。通过在鸢尾花数据集上的应用,我们展示了感知机的基本原理和步骤,并通过准确率、混淆矩阵、分类报告和可视化分类结果评估了模型效果。尽管感知机在处理非线性问题时表现不佳,但它在理解线性分类器的基本原理和构建更复杂的神经网络模型时具有重要意义。在实际应用中,我们可以考虑使用支持向量机(SVM)等更高级的线性分类器或神经网络来处理复杂的分类任务。

最大熵

作为最后一个方法,我懒得弄了。故此方法只提供代码不附介绍。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
用相同的格式根据以下代码写一篇博客介绍最大熵原理:import numpy as np
import pandas as pd
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix, ConfusionMatrixDisplay
import matplotlib.pyplot as plt
import seaborn as sns

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

# 将数据集拆分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 创建最大熵(多项逻辑斯蒂回归)模型
model = LogisticRegression(multi_class='multinomial', solver='lbfgs', max_iter=200)

# 训练模型
model.fit(X_train, y_train)

# 进行预测
y_pred = model.predict(X_test)

# 评估模型性能
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.2f}')

# 输出分类报告
print(classification_report(y_test, y_pred, target_names=iris.target_names))

# 输出混淆矩阵
conf_matrix = confusion_matrix(y_test, y_pred)
print('Confusion Matrix:')
print(conf_matrix)

# 可视化分类结果(混淆矩阵)
disp = ConfusionMatrixDisplay(confusion_matrix=conf_matrix, display_labels=iris.target_names)
disp.plot(cmap=plt.cm.Blues) # 使用蓝色系热图展示混淆矩阵
plt.title('Confusion Matrix for Maximum Entropy Classification of Iris Dataset')
plt.show()

# 可视化分类结果的另一种方式(散点图结合真实标签与预测标签)
# 由于鸢尾花数据集有四个特征,我们选择前两个特征进行可视化
X_vis = X[:, :2]

# 为了在散点图上展示分类结果,我们根据预测标签为测试集样本着色
colors = ['red', 'green', 'blue'] # 对应鸢尾花的三个类别:setosa, versicolor, virginica
test_colors = [colors[pred] for pred in y_pred]
true_colors = [colors[label] for label in y_test]

# 绘制散点图,展示前两个特征(花萼长度与花萼宽度)
plt.figure(figsize=(10, 6))
for i in range(len(X_test)):
# 使用较小的透明度来区分重叠的点
plt.scatter(X_test[i, 0], X_test[i, 1], c=test_colors[i], alpha=0.6, edgecolor='k', linewidth=0.5, label=f'Pred: {iris.target_names[y_pred[i]]}' if i == 0 else '')
# 为了展示真实标签,我们在每个点旁边添加一个小文本注释(仅对部分点进行注释以避免过于拥挤)
if i % 10 == 0: # 例如,每10个点注释一个
plt.text(X_test[i, 0] + 0.1, X_test[i, 1] + 0.1, f'True: {iris.target_names[y_test[i]]}', fontsize=9, color='black', ha='left')

# 添加图例、标题和标签
plt.legend(loc='upper left', bbox_to_anchor=(1, 1), bbox_transform=plt.gcf().transFigure)
plt.title('Maximum Entropy Classification of Iris Dataset (Visualized with Sepal Length and Width)')
plt.xlabel('Sepal Length')
plt.ylabel('Sepal Width')

# 显示图形
plt.show()

最大熵结果

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2023-2025 John Doe
  • Visitors: | Views:

请我喝杯茶吧~

支付宝
微信