sklearn 分类算法

分类算法

整理自黑马机器学习教程

sklearn 转换器与预估器

转换器

在特征工程处理的步骤中有用到转换器,一般使用流程为:

  1. 实例化一个转换器
  2. 调用fit_transform()
    实际上fit_transform()可分为两个步骤进行,这里以标准化为例: x , = x − E ( x ) σ \displaystyle x^, = \frac{x-E(x)}{\sigma} x,=σxE(x)
    1. fit:计算每一列的方差、均值
    2. transfer:根据fit得到的值,对该列的值进行转换

估计器

sklearn中,是一类实现了算法的api。

  • 用于分类的估计器:
    • sklearn.neighbors K-近邻
    • sklearn.naive_bayes 贝叶斯
    • sklearn.linear_model.LogisticRegression 逻辑回归
    • sklearn.tree 决策树和随机森林
  • 用于回归的估计器:
    • sklearn.linear_model.LinearRegression 线性回归
    • sklearn.linear_model.Ridge 岭回归
  • 用于无监督学习的估计器:
    • sklearn.cluster.KMeans 聚类

使用流程

  1. 实例化一个estimator类
  2. estimator.fit(x_train, y_train)->根据训练集的特征值和目标值,生成模型
  3. 模型评估
    1. 直接评估真实值和预测值
    2. 计算准确率:estimator.score(x_train, y_train)

KNN算法

K近邻算法:如果一个样本在特征空间中K个最相似(即特征空间中最邻近)的样本中的大多数属于一个类别,那么该样本也属于这个类别。

如何计算特征距离

介绍几种距离计算公式:

  1. 欧式距离: ( a 1 − b 1 ) 2 + ( a 2 − b 2 ) 2 + ( a 2 − b 2 ) 2 \sqrt{(a_1-b_1)^2+(a_2-b_2)^2+(a_2-b_2)^2} (a1b1)2+(a2b2)2+(a2b2)2
  2. 曼哈顿距离: ∣ a 1 − b 1 ∣ + ∣ a 2 − b 2 ∣ + ∣ a 3 − b 3 ∣ |a_1-b_1| + |a_2-b_2| + |a_3-b_3| a1b1+a2b2+a3b3;
  3. 明可夫斯基距离: ( ∑ i = 1 n ∣ x i − y i ∣ p ) 1 p (\sum_{i=1}^n |x_i-y_i|^p)^{\frac{1}{p}} (i=1nxiyip)p1

可以发现欧式距离和曼哈顿距离都是明可夫斯基距离的特殊情况

如何处理数据

K近邻对K的取值较为敏感:

  • 如果K值过小,则容易受异常点影响
  • 如果K值过大,则容易受样本不均衡的影响

同时不同量纲的数据会让大量纲的数据影响更多。
综上:我们需要将数据提前标准化

api 以鸢尾花为例

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
# 获取数据
iris = load_iris()

# 划分数据集
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=23)

# 标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
# 训练集和测试集做相同处理(很重要!)
x_test = transfer.transform(x_test)

# KNN算法预估器  建立模型
estimator = KNeighborsClassifier(n_neighbors=3)
estimator.fit(x_train, y_train)

# 模型评估
# 1 直接对比真实值和预估值
y_predict = estimator.predict(x_test)
print(y_predict == y_test)

# 计算准确率
score = estimator.score(x_test, y_test)
print(score)

结果会受到数据集划分的影响(随机数种子为23时,准确率为1)

小结

  • 优点
    • 简单,易于理解,容易实现,无需训练
  • 缺点
    • 懒惰算法,对测试样本分类时计算量大,内存开销大
    • 结果受K值影响
  • 使用场景
    • 小数据场景

模型选择与调优

KNN算法中我们需要确定一个K值,模型选择与调优可以帮助我们寻找合适的K值

交叉验证

可以让模型更加准确
以4折交叉验证为例:将训练集分为四组,其中一组作为验证集,经过四次训练,每次都更换不同的验证集,取平均值作为最终结果
在这里插入图片描述

超参数搜索-网格搜索(Grid Search)

通常情况下,很多参数需要手动指定(例如KNN中的K值),这种参数被称为超参数
我们可以将这些超参数的取值记录在网格里,然后对网格数据进行遍历,寻找最优

api

from sklearn.model_selection import GridSearchCV
# KNN算法预估器  建立模型
estimator = KNeighborsClassifier(n_neighbors=3)
# 添加网格搜索交叉验证
param_dict = {
    
    "n_neighbors":[1, 3, 5, 7, 9, 11]}
estimator = GridSearchCV(estimator, param_grid=param_dict, cv=10)
# 查看最佳参数等
print("最佳参数:\n", estimator.best_params_)
print("最佳结果:\n", estimator.best_score_)
print("最佳估计器:\n", estimator.best_estimator_)
print("交叉验证结果:\n", estimator.cv_results_)

为什么最佳结果比准确率?

因为这两者分别是对训练集和测试机的评估

朴素贝叶斯算法

前提假设:特征与特征之间是相互独立的

P ( A ∣ B ) = P ( B ∣ A ) P ( A ) P ( B ) P(A|B) = \frac {P(B|A)P(A)}{P(B)} P(AB)=P(B)P(BA)P(A)

使用场景: 文本分类

api

from sklearn.naive_bayes import MultinomialNB
# 贝叶斯
estimator = MultinomialNB()
estimator.fit(x_train, y_train)

小结

  • 优点:
    • 分类效率稳定
    • 对确实数据不敏感,常用于文本分类
    • 分类准确度高,速度快
  • 缺点:
    • 样本属性独立性假设,如果特征相关性较强则效果不理想

决策树

分类原理类似程序中的if-else,关键为找到最高效的决策顺序。

如何找到最高效的决策顺序

主要涉及两点:

  1. 在众多输入特征中选择最适合分枝的特征
  2. 如何从分组特性中寻找一个阈值作为最佳分割点

为此有定义信息熵:用于度量随机变量的不确定性
随机变量的熵:
$ H(X) = - \sum_{i=1}^n p(X_i)log_2 p(X_i)$
针对数量为d的样本集D,有k个种类,每个种类队以ing的样本数量为 C k C_k Ck,则样本集的熵为:
$ H(D) = - \sum_{i=1}^k \frac{C_i}{d}log_2\frac{C_i}{d}$

依据信息熵,我们可以通过三种决策树算法进行分类,将在另外文章中分享。

api

from sklearn.tree import DecisionTreeClassifier, export_graphviz

# 决策树
estimator = DecisionTreeClassifier(criterion="entropy")
estimator.fit(x_train, y_train)
# 计算准确率
score = estimator.score(x_test, y_test)
print(score)
# 决策树可视化
export_graphviz(estimator, out_file="tree.dot", feature_names=iris.feature_names)

小结

  • 优点
    • 简单理解和解释,树可视化
  • 缺点
    • 不能创建数据更为复杂的树(过拟合)
  • 改进
    • 剪枝
    • 随机森林

随机森林

随机森林是一个包含多个决策树的分类器,输出结果由所有类别的众数决定。

原理过程

随机体现在两个方面:

  1. 训练集随机:bootstrap抽样(随机有放回)
  2. 特征随机:从M个特征中随机抽取m个特征(M >> m可以达到降维的目的)

api

因为有几个超参数,所以我们可以添加网格搜索来寻找最佳结果

from sklearn.ensemble import RandomForestClassifier

estimator = RandomForestClassifier()
# 网格搜索
param_dict = {
    
    "n_estimators": [120, 200, 300, 500, 800, 1200],"max_depth": [5, 8, 15, 25, 30]}
estimator = GridSearchCV(estimator, param_grid=param_dict, cv=3)

小结

  • 当前所有算法中,具有极好的准确率
  • 能够有效地运行在大数据集上,能够处理高纬度特征的输入样本,不需要降维(因为随机抽取样本即特征)
  • 能够评估各个特征在分类问题上的重要性(也是因为对特征进行随机采样)

猜你喜欢

转载自blog.csdn.net/qq_43550173/article/details/116614775