从零开始学机器学习——初探分类器

首先给大家介绍一个很好用的学习地址:https://cloudstudio.net/columns

在上一节中,我们已经完成了对所有经过均衡和清洗的菜品数据的准备工作。接下来,我们将考虑使用多种算法,也就是不同的分类器,来构建模型。我们将利用这个数据集和各种分类器,基于一组特定的配料,预测这些菜品属于哪个国家的美食。

在这一过程中,你将深入学习如何评估和权衡不同分类算法的优缺点,以及如何选择最适合当前任务的模型。

选择你的分类器

Scikit-learn 将分类任务归类为监督学习的一部分,其中包含了多种可用于分类的算法和方法。初看之下,这些选择似乎让人眼花缭乱。以下是一些可用于分类的主要算法:

  1. 线性模型(Linear Models):这些模型基于线性假设,通过对特征进行线性组合来进行分类。
  2. 支持向量机(Support Vector Machines):此算法通过找到最佳分隔超平面来最大化类别间的间隔,从而实现分类。
  3. 随机梯度下降(Stochastic Gradient Descent):一种高效的优化方法,可以用于训练各种模型,特别是在处理大规模数据集时。
  4. 最近邻(Nearest Neighbors):基于实例的学习方法,通过计算样本之间的距离来进行分类,简单而有效。
  5. 高斯过程(Gaussian Processes):一种灵活的非参数贝叶斯方法,能够捕捉数据的潜在分布并进行分类。
  6. 决策树(Decision Trees):通过构建树状结构来做出决策,根据特征的不同值逐步划分数据。
  7. 集成方法(投票分类器)(Ensemble methods — voting classifier):结合多个分类器的预测结果,以提高整体分类性能。
  8. 多类别多输出算法(Multiclass and multioutput algorithms):处理多类别分类和多标签分类问题,能够同时输出多个类别的预测结果。

如何选择分类器?

与其进行无目的的猜测,不如下载这份详尽的机器学习速查表——微软原版本的小抄表。该速查表对各种算法进行了系统的比较和总结,能够有效地指导我们在选择适合的分类算法时做出明智的决策。根据这份速查表,我们可以针对本章节中涉及的多种分类任务,考虑以下几种算法选择:

以下是我自己翻译后的中文版本,希望可以帮助大家,如图所示:

image

分析模型选择

首先,我们的预测值是固定的,并且涉及多类分类的问题,因此我们可以聚焦于多类分类模型的选择。接下来,我们将逐个分析适合的算法。

神经网络(Neural Network)虽然强大,但在这个特定任务中显得过于复杂。我们的数据量较小且相对清晰。

我们可以考虑决策树和逻辑回归这两种算法。决策树是一种直观且易于解释的模型,适用于处理多类分类问题。它能够自动选择重要特征并进行数据分割,直观地展示决策过程。然而,逻辑回归也是一个非常实用的选择,尤其是在处理多类型数据时,它能够有效地建立类间的线性关系。

尽管增强决策树在某些场景中非常有效,但它更适合用于非参数化的任务,尤其是在需要进行排序或集成多种模型时。而对于我们当前的任务,增强决策树并不能提供直接的帮助。

综合考虑这些因素,我们决定选择逻辑回归作为我们的模型构建方法。

因为我们对 Scikit-learn 库已经相对熟悉,今天,我们将主要分析 LogisticRegression 这一方法的参数设置,因为不同的参数配置会直接影响底层算法的运作机制。通过对这些参数的深入理解,我们能够更好地优化模型,以实现更高的分类准确率。

LogisticRegression详解

当我们使用 Scikit-learn 进行逻辑回归运算时,两个至关重要的参数是 multi_classsolver,它们对于模型的性能和适用性有着直接的影响,因此需要特别关注和详细说明。

参数 描述 可选值 备注
multi_class 指定分类方式。 - ovr(一对多)
- multinomial(多项式)
- ovr 是默认选项,适用于二分类和多分类
- multinomial 适用于多分类且通常需要softmax输出。
solver 优化算法选择,用于求解逻辑回归模型的权重。 - liblinear
- newton-cg
- lbfgs
- sag
- saga
- liblinear 仅适用于 ovr
- newton-cglbfgssagsaga 可以与 multinomial 配合使用。

详细说明

  1. multi_class 参数
    • ovr(一对多):将多类问题转换为多个二分类问题。对于每个类别,训练一个分类器来区分该类别与其他所有类别。
    • multinomial(多项式):适用于多类别分类问题,使用softmax函数进行概率估计,通常在类别数量较多时效果较好。
  2. solver 参数
    • liblinear:适用于小数据集和二分类问题,支持 ovr
    • newton-cg:适用于多类别问题,支持 multinomial
    • lbfgs:适用于多类别问题,支持 multinomial,通常在大数据集上效果较好。
    • sag:适用于大数据集,支持 multinomial,加速收敛。
    • saga:适用于大数据集,支持 multinomial,同时支持L1和L2正则化。

匹配关系

  • liblinear 只与 ovr 兼容。
  • newton-cglbfgssagsaga 都可以与 multinomialovr 兼容。

关于多项式逻辑回归,我们已经有了一定的了解,接下来让我们详细解释一下 "ovr"(一对多)是什么意思,以及它在多类分类中的作用。

ovr详解

"ovr" 本意为一对其余(One-vs-Rest,OvR)策略,它涉及将多类数据集拆分为多个二元分类问题。具体而言,这种方法通过将每个类别视为一个独立的二元分类任务,使得我们可以利用现有的二元分类算法来解决更复杂的多类分类问题。对于每个二元分类问题,我们都将训练一个二元分类器,并使用这些分类器中最可靠的模型进行最终预测。

例如,考虑一个多类分类问题,其中有三个类别:“red”、“blue”和“green”。在这种情况下,我们可以将这个多类分类问题拆分为以下三个二元分类数据集:

  1. 二元分类问题 1:判断样本是否为“red”,与其他两个类别(“blue”和“green”)进行区分。
  2. 二元分类问题 2:判断样本是否为“blue”,与其他两个类别(“red”和“green”)进行区分。
  3. 二元分类问题 3:判断样本是否为“green”,与其他两个类别(“red”和“blue”)进行区分。

这种拆分方式使得每个分类器只需关注一个特定类别,从而简化了模型训练的过程。由于逻辑回归本身是为二元分类设计的,因此它不能直接应用于多类分类任务。然而,通过使用 OvR 策略,我们可以采用一种启发式的方法,将多类分类问题分解为多个二元分类数据集,并为每个数据集训练一个独立的二元分类模型。

解析数据

经过以上分析,我们的模型选择方案可以是 "ovr"(一对其余,One-vs-Rest)或 "multinomial"(多项式)。由于逻辑回归最初是设计用于二分类任务的,因此这两个方案参数的选择都能够有效地使逻辑回归在多类分类任务中发挥出色的性能。

在我们的模型中,我们决定将 multi_class 参数设置为 "ovr",并选择 solver 设置为 "liblinear" 进行模型训练。选择 "liblinear" 作为求解器的原因在于它在处理小型数据集时表现出色,特别是在二元分类的场景中,能够提供快速的收敛速度和较高的准确率。

分割数据

接下来我们将数据清洗下并进行测试、训练集分割。

import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import accuracy_score,precision_score,confusion_matrix,classification_report, precision_recall_curve
from sklearn.svm import SVC
import numpy as np

cuisines_df = pd.read_csv("../../data/cleaned_cuisines.csv")

cuisines_label_df = cuisines_df['cuisine']

X_train, X_test, y_train, y_test = train_test_split(cuisines_feature_df, cuisines_label_df, test_size=0.3)

这段代码的整体结构和逻辑我们已经有了相当清晰的印象,因此在此不再详细解释其具体实现。

构建模型

创建一个逻辑回归模型

lr = LogisticRegression(multi_class='ovr',solver='liblinear')
model = lr.fit(X_train, np.ravel(y_train))

accuracy = model.score(X_test, y_test)

Accuracy is 0.8015012510425354

运算完成后,我们观察到模型的准确率高达 80%!

接下来,我们将对本轮预测结果进行详细的检查,以评估准确率的具体来源。

  test= X_test.iloc[50].values.reshape(-1, 1).T
proba = model.predict_proba(test)
classes = model.classes_
resultdf = pd.DataFrame(data=proba, columns=classes)

topPrediction = resultdf.T.sort_values(by=[0], ascending = [False])
topPrediction.head()

运行后的输出如下——可以看到,根据模型的预测结果,这道菜被识别为日本菜的可能性最大。

japanese 0.935524
indian 0.040175
korean 0.016106
thai 0.005825
chinese 0.002370

与你在之前的回归章节中所进行的分析类似,我们同样可以通过生成分类报告来获取关于模型的更多详细信息。

y_pred = model.predict(X_test)
print(classification_report(y_test,y_pred))

详细报告如下:

              precision    recall  f1-score   support

     chinese       0.73      0.71      0.72       238
      indian       0.92      0.87      0.89       243
    japanese       0.79      0.79      0.79       237
      korean       0.84      0.81      0.82       236
        thai       0.75      0.84      0.79       245

    accuracy                           0.80      1199
   macro avg       0.80      0.80      0.80      1199
weighted avg       0.80      0.80      0.80      1199

至此,本模型的构建过程已圆满完成!

总结

尽管我们今天对数据的解析仍然采用了之前熟悉的方法,但我们在此基础上新增了两个重要的知识点。首先,我们深入探讨了分类器的选择,分析了不同分类器在特定任务中的适用性与表现。这不仅帮助我们更好地理解各类算法的优势与局限性,也为未来的模型选择提供了理论支持。

其次,我们详细解析了逻辑回归中的参数设置,特别是对“ovr”(一对多)策略进行了深入学习。通过对这一策略的理解,我们能够更清楚地掌握如何在多类分类问题中有效地应用逻辑回归,提高模型的准确性与泛化能力。

接下来我们将继续深入学习各种分类器的特性与应用以提升整体的分类性能。


我是努力的小雨,一名 Java 服务端码农,潜心研究着 AI 技术的奥秘。我热爱技术交流与分享,对开源社区充满热情。同时也是一位腾讯云创作之星、阿里云专家博主、华为云云享专家、掘金优秀作者。

💡 我将不吝分享我在技术道路上的个人探索与经验,希望能为你的学习与成长带来一些启发与帮助。

🌟 欢迎关注努力的小雨!🌟

posted @ 2024-10-15 09:55  努力的小雨  阅读(319)  评论(0编辑  收藏  举报