概述
分类算法是根据数据特征来预测数据的类别。
分类算法是一种监督学习(Supervised Learning)方法,它需要一个已知的类别标签的训练数据集,通过学习这个数据集来预测新的数据点的类别。例如,在电子邮件过滤系统中,分类算法可以学习如何区分垃圾邮件和非垃圾邮件。
分类算法通常用于预测离散的目标变量(例如,电子邮件是否为垃圾邮件),并产生一个概率模型,该模型可以预测目标变量取特定值的概率。
常见的分类算法包括以下几种:
1.决策树
决策树是一种简单易用的数据分类算法。决策树通过一系列的决策规则将数据划分到不同的类别中。
1.1 概述:
决策树,作为一种简单易用的数据分类算法,在机器学习领域具有广泛的应用。它通过一系列逻辑分支规则将原始数据划分到不同的目标类别,从而实现对数据的分类和预测。决策树的核心思想是将数据集根据特征值进行划分,直到满足一定的停止条件为止。在这个过程中,决策树不断地生长,直到成为一个完整的分类模型。
1.2 决策树的构建过程:
1.特征选择: 在构建决策树的过程中,选择合适的特征是关键。一般采用信息增益、增益率、基尼指数等方法来选择最优特征。
2.决策树生长: 根据选择的特征,将数据集划分成不同的子集,然后对每个子集递归地重复步骤1,直到满足停止条件。
3.停止条件: 通常有两条停止条件,一是所有样本属于同一类别,二是没有可选特征。当满足其中任意一条时,停止生长决策树。
4.剪枝: 为了防止过拟合现象,对决策树进行剪枝处理。剪枝方法有预剪枝和后剪枝两种,预剪枝是在构建过程中提前停止树的生长,后剪枝则是在生成完整的决策树后进行简化。
决策树的优点与局限性
1.优点(1)易于理解和解释 :决策树的结构简单,易于理解,便于分析特征之间的关系。
(2)适应性较强: 决策树可以处理不同类型的数据,如数值型、类别型等。
(3)抗噪声能力: 决策树在一定程度上能容忍数据中的噪声,提高分类准确性。
2.局限性(1)容易过拟合 :决策树在生长过程中容易过度拟合,需要进行剪枝处理。
(2)对特征选择敏感 :决策树的分类效果受特征选择影响较大,选择不当会导致分类效果不佳。
(3)无法处理连续特征: 决策树不适用于处理连续值特征,需结合其他算法进行处理。
3. 决策树示例的python代码:
python
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
# 1. 加载鸢尾花数据集
iris = load_iris()
X = iris.data # 特征数据,包含花的各种测量属性
y = iris.target # 目标数据,也就是鸢尾花的种类标签
# 2. 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 3. 创建决策树分类器对象
clf = DecisionTreeClassifier()
# 4. 使用训练集数据训练模型
clf.fit(X_train, y_train)
# 5. 使用测试集进行预测
y_pred = clf.predict(X_test)
# 6. 评估模型准确率
accuracy = (y_pred == y_test).sum() / len(y_test)
print("模型准确率:", accuracy)
# 7. 可视化决策树(需要安装graphviz库及相关依赖,同时在系统环境变量中配置好graphviz的可执行文件路径)
from sklearn.tree import plot_tree
plt.figure(figsize=(12, 8))
plot_tree(clf, filled=True, feature_names=iris.feature_names, class_names=iris.target_names)
plt.show()
# 创建决策树分类器对象,并设置一些参数进行优化
clf = DecisionTreeClassifier(max_depth=3, min_samples_split=5)
在上述代码中:
- 第一步通过
load_iris
函数加载了鸢尾花数据集,其中特征数据包含了四个维度,目标数据是对应鸢尾花的种类编号(0、1、2 分别对应不同种类)。 - 第二步利用
train_test_split
函数将数据集按照 7:3 的比例划分为训练集和测试集,同时设置了随机种子来保证每次划分结果可复现。 - 第三步创建了
DecisionTreeClassifier
决策树分类器实例。 - 第四步调用
fit
方法使用训练集对模型进行训练,让模型学习数据中的模式和规律。 - 第五步使用训练好的模型对测试集进行预测,得到预测结果。
- 第六步通过对比预测结果和真实的测试集标签来计算模型的准确率,以此衡量模型的表现情况。
- 第七步借助
plot_tree
函数对训练好的决策树进行可视化展示,能够直观看到决策树的节点、分支以及判断规则等内部结构,方便理解模型是如何进行分类决策的(前提是已经正确安装并配置好相关可视化依赖)。
2. 支持向量机
支持向量机是一种强大的分类算法,它可以有效地处理非线性分类问题。支持向量机通过找到数据的边界来实现分类。
2.1 概述:
支持向量机(Support Vector Machine,简称SVM)是一种卓越的分类算法,尤其在处理非线性分类问题上表现出了强大的能力。相较于传统的分类方法,支持向量机能够有效地找到数据的边界,实现高维空间中的分类。
支持向量机的核心思想是将数据映射到高维空间,从而在该空间中寻找一个最优的超平面,将不同类别的数据分开。这个超平面就是所谓的"支持向量",它们是分类边界上的关键点。支持向量机的目标是找到一个既能最大化分类边界距离,又能最小化两侧分类误差的支持向量。
2.2 特点:
在支持向量机的训练过程中,首先需要选取一组训练数据,并通过最小化目标函数来找到最优的超平面。这个目标函数通常包括两部分:分类误差和核函数。核函数用于将数据从原始空间映射到高维空间,并在此过程中实现分类。支持向量机中有多种核函数可供选择,如线性核、多项式核、径向基函数(RBF)核等。
支持向量机在众多领域得到了广泛的应用,如文本分类、图像识别、生物信息学等。它在处理高维数据和噪声数据时具有较高的分类准确率和稳定性。然而,支持向量机也存在一定的局限性,如过拟合问题和对核函数的选择敏感等。针对这些问题,研究者们提出了许多改进方法,如采用交叉验证、核函数的组合等。
2.3 支持向量机示例的python代码:
python
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from matplotlib.colors import ListedColormap
from sklearn.svm import SVC
# ? 加载样本数据及其分类标签
iris = datasets.load_iris()
X = iris.data[:, [2, 3]] # 按花瓣划分
# X = iris.data[:,[0,1]] #按花萼划分
y = iris.target
print('Class labels:', np.unique(y)) # 分类标签列表 [0 1 2]
# np.unique(arr): arr为一维数组/列表,结果返回一个列表,去除arr中重复的元素,并从小到大排序
# ? 划分70%训练集和30%测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1, stratify=y)
"""
train_test_split()函数: 用于将数据集划分为训练集train和测试集test
X: 待划分的样本特征集
y: 数据集X对应的标签
test_size: 0~1表示测试集样本占比、整数表示测试集样本数量
random_state: 随机数种子。在需要重复实验的时候保证得到一组一样的随机数据。每次填1(其他参数一样),每次得到的随机数组一样;每次填0/不填,每次都不一样
stratify=y: 划分数据集时保证每个类别在训练集和测试集中的比例与原数据集中的比例相同
"""
print('Labels counts in y:', np.bincount(y)) # 原数据集中各分类标签出现次数 [50 50 50]
print('Labels counts in y_train:', np.bincount(y_train)) # 训练集中各分类标签出现次数 [35 35 35]
print('Labels counts in y_test:', np.bincount(y_test)) # 测试集中各分类标签出现次数 [15 15 15] 35:15=7:3
# np.bincount(arr): 返回一个数组array,长度=max(arr[i])+1,array[i]=count(arr[i])。(长度=arr中最大元素值+1,每个元素值=它当前索引值在arr中出现的次数)
# ? 标准化训练集和测试集
sc = StandardScaler() # 定义一个标准缩放器
sc.fit(X_train) # 计算均值、标准差
X_train_std = sc.transform(X_train) # 使用计算出的均值和标准差进行标准化
X_test_std = sc.transform(X_test) # 使用计算出的均值和标准差进行标准化
"""
! StandardScaler()
均值:对每个特征求均值,即对每列求均值
去均值:每个特征的值减去对应特征的均值
标准差:去均值后平方和,然后除以总值的数量,最后开根号
标准分数:去均值、除以标准差
1、中心化:去均值,将整体数据平移,中心为(0,0)
2、缩放:标准分数,进行缩放
标准化:去均值、除以标准差。将数据的分布转为正态分布。每个特征的值 均值=0、方差=1
目的:
将特征表现为标准正态分布数据。
如果某个特征的方差比其他特征大几个数量级,那么它就会在学习算法中占据主导位置,导致学习器不能从其他特征中学习,从而降低精度。
加快梯度下降求解的速度。
"""
# ? 绘制决策边界图 函数
def plot_decision_regions(X, y, classifier, test_idx=None, resolution=0.02):
# ? 设置标记生成器和颜色图
markers = ('s', '^', 'o', 'x', 'v') # 标记生成器
colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan') # 定义颜色图
cmap = ListedColormap(colors[:len(np.unique(y))])
# ? 绘制决策曲面
x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1 # x轴范围 x1_min ~ x1_max
x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1 # y轴范围 x2_min ~ x2_max
xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution), # 生成网络点坐标矩阵
np.arange(x2_min, x2_max, resolution))
Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
Z = Z.reshape(xx1.shape) # 对不同分类进行标记
plt.contourf(xx1, xx2, Z, alpha=0.3, cmap=cmap) # 生成边界图
plt.xlim(xx1.min(), xx1.max())
plt.ylim(xx2.min(), xx2.max())
# ? 绘制 所有样本 散点图
for idx, cl in enumerate(np.unique(y)):
plt.scatter(x=X[y == cl, 0], # 散点的x坐标(分类标签==cl)
y=X[y == cl, 1], # 散点的y坐标(分类标签==cl)
alpha=0.8, # 散点的透明度
c=colors[idx], # 散点的颜色
marker=markers[idx], # 散点的样式
label=cl, # 散点的图例名称
edgecolor='black') # 散点的边缘颜色
# ? 绘制 测试样本 散点图
if test_idx: # 默认test_idx=None 如果未设置该参数,则不绘制测试样本
X_test, y_test = X[test_idx, :], y[test_idx]
plt.scatter(X_test[:, 0], # 散点的横坐标
X_test[:, 1], # 散点的纵坐标
c='y', # 散点的颜色【黄色】
edgecolor='black', # 散点的边缘颜色【黑色】
alpha=1.0, # 散点的透明度【1】
linewidth=1, # 散点的边缘线宽【1】
marker='*', # 散点的样式【圆圈】
s=150, # 散点的面积【150】
label='test set') # 散点的图例名称【test set】
"""
print(np.arange(x1_min, x1_max, resolution).shape) # 265
print(np.arange(x2_min, x2_max, resolution).shape) # 258
print(xx1.shape) # 258*265 # 258个相同的x值(x1范围),因为有258个不同y值,说明一个x值对应258个不同y【x坐标竖直复制258份】
print(xx2.shape) # 258*265 # 265个相同的y值(x2范围),因为有265个不同x值,说明一个y值对应265个不同x【y坐标水平复制265份】
print(xx1.ravel().shape) # 68370 =258*265
print(xx2.ravel().shape) # 68370 =258*265
print(np.array([xx1.ravel(), xx2.ravel()]).shape) # 2*68370
print(np.array([xx1.ravel(), xx2.ravel()]).T.shape) # 68370*2
Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
print(Z.shape) # 1*68370
Z = Z.reshape(xx1.shape)
print(Z.shape) # 258*265 # 预测出网格点的每个分类,reshape成258行预测结果,每行265个具体预测值
x=X[y == 0, 0] # 分类y=0的x坐标(第二个位置参数=1时为y坐标)
print(X.shape) # 150*2
print(x.shape) # 1*50
print(X[range(105, 150), :].shape) # 45*2
"""
# Training a svm model using the standardized training data
X_combined_std = np.vstack((X_train_std, X_test_std)) # 竖直堆叠
y_combined = np.hstack((y_train, y_test)) # 水平拼接
"""
np.vstack(tup): tup为一个元组,返回一个竖直堆叠后的数组
np.hstack(tup): tup为一个元组,返回一个水平拼接后的数组
"""
# ? 训练线性支持向量机
svm = SVC(kernel='linear', C=1.0, random_state=1) # 定义线性支持向量分类器 (linear为线性核函数)
svm.fit(X_train_std, y_train) # 根据给定的训练数据拟合训练SVM模型
plot_decision_regions(X_combined_std, y_combined, classifier=svm, test_idx=range(105, 150)) # 绘制决策边界
plt.xlabel('petal length [standardized]') # x轴标签
plt.ylabel('petal width [standardized]') # y轴标签
plt.legend(loc='upper left') # 图例位于左上方
plt.tight_layout() # 使子图填充整个图像区域
# plt.savefig('images/03_11.png', dpi=300)
plt.show()
# ? 使用测试集进行数据预测
y_pred = svm.predict(X_test_std) # 用训练好的分类器svm预测数据X_test_std的标签
print('Misclassified samples: %d' % (y_test != y_pred).sum()) # 输出错误分类的样本数
print('Accuracy: %.2f' % svm.score(X_test_std, y_test)) # 输出分类准确率
"""
! (arr1 != arr2).sum():
arr1、arr2为数组类型
(arr1 != arr2): 输出一个列表,元素为bool类型,两数组对应位置不相等为True
.sum(): 统计列表中True的个数
! svm.score(X_test_std, y_test)
返回给定测试集与对应标签的平均准确率
"""
"""
终端输出结果:
Class labels: [0 1 2]
Labels counts in y: [50 50 50]
Labels counts in y_train: [35 35 35]
Labels counts in y_test: [15 15 15]
Misclassified samples: 1
Accuracy: 0.98
"""
具体讲解:【ML】支持向量机SVM及Python实现(详细)_支持向量机代码-CSDN博客
总之,支持向量机作为一种强大的分类算法,在非线性分类问题上具有很高的价值。通过寻找数据的边界,支持向量机能够在高维空间中实现高效准确的分类。
3. 朴素贝叶斯
在机器学习和数据挖掘领域,分类算法是一种重要的技术。它可以帮助我们根据已知的特征对未知数据进行归类。在众多的分类算法中,朴素贝叶斯算法(Naive Bayes)脱颖而出,以其简单、有效的特性受到了广泛关注和应用。
3.1 贝叶斯定理
朴素贝叶斯算法基于贝叶斯定理,该定理是概率论中的一个重要原理。它描述了在给定某些条件下,事件发生的概率。贝叶斯定理的表达式为:
P(A|B) = P(B|A) * P(A) / P(B)
其中,P(A|B)表示在已知事件 B发生的情况下,事件 A发生的概率;P(B|A)表示在已知事件 A发生的情况下,事件 B发生的概率;P(A) 和 P(B)分别表示事件 A 和事件 B 的概率。
3.2 主要特点
朴素贝叶斯算法的主要特点在于,它假设各个特征之间相互独立。
这意味着,在计算某个特征的概率时,其他特征的概率不会受到影响。
这种假设简化了计算过程,使得算法具有较小的计算量。
在实际应用中,朴素贝叶斯算法广泛应用于文本分类、垃圾邮件过滤、情感分析等领域。以文本分类为例,我们可以根据已知的训练数据,计算出每个单词在各个类别中的概率。然后,根据贝叶斯定理,计算出未知文本属于某个类别的概率。最终,我们可以根据概率大小,将未知文本分配到相应的类别中。
尽管朴素贝叶斯算法在某些领域表现出色,但它也存在一定的局限性。由于它假设特征之间相互独立,因此在处理具有复杂关系的数据时,算法的性能可能会受到影响。然而,在许多情况下,朴素贝叶斯算法仍然是一种值得尝试的分类方法。
3.3 朴素贝叶斯算法python代码示例:
python
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB
from matplotlib.colors import ListedColormap
# 加载鸢尾花数据集
iris = load_iris()
X = iris.data[:, :2] # 只取前两个特征用于二维可视化展示,方便绘图
y = iris.target
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 创建高斯朴素贝叶斯分类器对象
gnb = GaussianNB()
# 使用训练集训练模型
gnb.fit(X_train, y_train)
# 生成用于绘制决策边界的网格数据
h = 0.02 # 网格步长
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
np.arange(y_min, y_max, h))
test_points = np.c_[xx.ravel(), yy.ravel()]
# 使用训练好的分类器进行预测
predicted_labels = gnb.predict(test_points)
# 重塑预测结果以便可视化展示
predicted_labels = predicted_labels.reshape(xx.shape)
# 自定义颜色映射,用于区分不同类别
cmap_light = ListedColormap(['#FFAAAA', '#AAFFAA', '#AAAAFF'])
cmap_bold = ListedColormap(['#FF0000', '#00FF00', '#0000FF'])
# 绘制决策边界和数据点
plt.figure(figsize=(8, 6))
plt.pcolormesh(xx, yy, predicted_labels, cmap=cmap_light)
plt.scatter(X_test[:, 0], X_test[:, 1], c=y_test, cmap=cmap_bold, edgecolor='k', s=20)
# 设置坐标轴标签和标题
plt.xlabel(iris.feature_names[0])
plt.ylabel(iris.feature_names[1])
plt.title('Gaussian Naive Bayes Classification on Iris Dataset')
# 添加图例
handles = [
plt.scatter([], [], c='r', label=iris.target_names[0]),
plt.scatter([], [], c='g', label=iris.target_names[1]),
plt.scatter([], [], c='b', label=iris.target_names[2])
]
plt.legend(handles=handles)
# 显示图形
plt.show()
整个代码实现了使用高斯朴素贝叶斯算法对鸢尾花数据集进行分类,并将分类结果以及数据分布情况以可视化的形式展示出来。朴素贝叶斯算法是一种简单而有效的分类方法。它基于贝叶斯定理,假设各个特征相互独立,从而在计算过程中具有较小的复杂度。虽然在处理复杂数据时存在局限性,但在许多应用场景中,它仍然具有良好的表现。