蓝桥杯人工智能赛道进阶重点及笔记(持续更新)

官网:https://www.lanqiao.cn/courses/29224/learning/?id=1723394&compatibility=false

一、集成学习和随机森林方法——特征的重要性

蓝桥杯直通国赛班(人工智能组)_蓝桥杯 - 蓝桥云课

计算现实问题中的特征重要性

让我们考虑一个数据集,这数据集的内容是 Booking.com 和 TripAdvisor.com 上所列旅馆的一些信息,数据集的特征是不同类别(包括服务质量、房间状况、性价比等)的平均评分,目标变量为旅馆在网站上的总评分。首先导入相关库。

# 导入随机森林回归器,这是一种集成学习方法
from sklearn.ensemble.forest import RandomForestRegressor


import numpy as np
import pandas as pd

''' 导入seaborn库,它是一个基于matplotlib的数据可视化库,
了一系列高级接口,用于制作吸引人且信息丰富的统计图形'''
import seaborn as sns

# 从matplotlib库中导入pyplot模块,它提供了类似于MATLAB的绘图框架,适合交互式绘图
from matplotlib import pyplot as plt

'''这行神奇的代码是IPython的魔法命令,
它告诉Jupyter Notebook直接在输出单元格中显示matplotlib图形
而不是创建一个新窗口。这样可以使输出更加整洁,便于在notebook中直接查看图形。'''
%matplotlib inline

集成学习(Ensemble  /ɒnˈsɒmb(ə)l/   Learning),也称为集成方法(Ensemble Method),是一种机器学习技术,它通过结合多个预测模型来提高单个模型的性能。集成学习的核心思想是,通过组合多个弱学习器(base learners),构建出一个强学习器(strong learner),以此来提高模型的准确性和鲁棒性。

集成学习通常分为两大类:

  1. 平行集成(Parallel Ensemble):这类方法中,多个弱学习器并行训练,每个学习器独立地进行预测,最终通过某种规则(如平均、投票等)来合并这些预测结果。常见的平行集成方法包括:

    • Bagging(例如随机森林 RandomForest):通过随机抽样和替换来构建多个不同的训练集,然后对每个训练集训练一个模型,最后通过投票(分类问题)或平均(回归问题)来合并预测结果。
    • Boosting(例如AdaBoost、XGBoost、LightGBM):通过迭代地训练一系列模型,每个模型都试图修正前一个模型的错误,最后通过加权投票(分类问题)或加权平均(回归问题)来合并预测结果。每个模型都是基于前一个模型的性能来调整数据的权重或概率分布。
  2. 序列集成(Sequential Ensemble):这类方法中,弱学习器是顺序训练的,每个学习器都依赖于前一个学习器的输出。Boosting就是一种序列集成方法。

集成学习的优点包括:

  • 提高性能:集成多个模型通常能比单个模型获得更好的性能。
  • 增强泛化能力:通过结合多个模型,集成学习方法可以减少过拟合的风险,提高模型在未知数据上的泛化能力。
  • 鲁棒性:集成学习方法对噪声和异常值具有较强的鲁棒性。

集成学习的缺点包括:

  • 计算成本高:训练多个模型需要更多的计算资源和时间。
  • 模型解释性差:集成模型通常比单个模型更复杂,因此更难以解释和理解。

在实际应用中,集成学习方法已经在许多机器学习竞赛和实际项目中取得了显著的成功,尤其是在需要高预测性能的场景下。

 Seaborn是一个基于matplotlib的Python数据可视化库,提供了一系列高级接口,用于制作吸引人且信息丰富的统计图形。Seaborn的设计目的是为数据分析和可视化提供更加美观和一致的界面,以及提供一组丰富的可视化模式,这些模式在matplotlib中实现起来要么比较复杂,要么根本不存在。

 导入数据集。

'''这段代码使用Python的pandas库从网络地址读取一个CSV文件,
并将其加载到一个DataFrame对象中。然后定义了一个字典,
将列名映射到更易读的描述性标签。'''


# 使用pandas的read_csv函数从指定的URL加载CSV文件
# 这个URL是一个在线资源,指向了一个名为"hostel_factors.csv"的文件
# 这个文件包含了关于旅舍的各种因素的数据
hostel_data = pd.read_csv(
    "https://labfile.oss.aliyuncs.com/courses/1283/hostel_factors.csv")
# 定义一个字典,将原始的列名映射到更具描述性的标签
# 这些标签可能是中文,因为它们被u前缀标记为Unicode字符串
# 这样的映射可以帮助用户更好地理解每个列的含义
features = {"f1": u"Staff",
            "f2": u"Hostel booking",
            "f3": u"Check-in and check-out",
            "f4": u"Room condition",
            "f5": u"Shared kitchen condition",
            "f6": u"Shared space condition",
            "f7": u"Extra services",
            "f8": u"General conditions & conveniences",
            "f9": u"Value for money",
            "f10": u"Customer Co-creation"}

使用随机森林训练模型。

这段代码使用了Scikit-learn库中的随机森林回归器(RandomForestRegressor)来训练一个模型,并计算了特征的重要性。

# 创建一个随机森林回归器实例
# n_estimators=1000 表示森林中树的数目为1000
# max_features=10 表示每个决策树分裂时考虑的最大特征数为10
# random_state=0 设置随机状态,使得模型的可重复性更好
forest = RandomForestRegressor(n_estimators=1000, max_features=10, random_state=0)

# 使用hostel_data数据集训练随机森林模型
# drop(['hostel', 'rating'], axis=1) 表示在训练模型时不使用'hostel'和'rating'列
# 'rating'列是目标变量,即我们需要预测的值
forest.fit(hostel_data.drop(['hostel', 'rating'], axis=1), hostel_data['rating'])

# 获取模型中每个特征的重要性分数
# feature_importances_属性是一个数组,数组的长度等于特征的数量,数组的值表示对应特征的重要性
importances = forest.feature_importances_

# 计算特征重要性分数的排序索引
# argsort函数返回的是数组值从小到大的索引值
# [::-1]表示反转数组,使得索引值从大到小排序
indices = np.argsort(importances)[::-1]

标出随机森林模型中的特征重要性。

# 定义要绘制的特征数量
num_to_plot = 10

# 从排序后的特征索引中选取前num_to_plot个索引
# indices[:num_to_plot]切片操作选取了最重要的num_to_plot个特征的索引
# [ind+1 for ind in indices[:num_to_plot]]列表推导式用于创建一个新的列表
# 这个新列表包含了加1后的索引值,因为特征索引通常是从1开始的,而不是从0开始
feature_indices = [ind+1 for ind in indices[:num_to_plot]]

打印特征重要性排名(重要性从高到低排列)。

# 打印特征排名的标题
print("Feature ranking:")

# 遍历要绘制的特征数量
for f in range(num_to_plot):
    # 打印每个特征的排名、名称和重要性分数
    # %d 表示整数,%s 表示字符串,%f 表示浮点数
    # feature_indices[f] 是特征的真实索引,但由于我们之前对索引进行了加1操作,所以这里需要减去1来获取正确的索引
    print("%d. %s %f " % (f + 1,
                          features["f"+str(feature_indices[f])],
                          importances[indices[f]]))

# 设置图形的大小
plt.figure(figsize=(15, 5))

# 设置图形的标题
plt.title(u"Feature Importance")

# 绘制条形图
# bars = plt.bar() 用于创建条形图
# range(num_to_plot) 提供了条形图的x轴位置
# importances[indices[:num_to_plot]] 提供了每个条形的高度,即特征的重要性
# color=([str(i/float(num_to_plot+1)) for i in range(num_to_plot)]) 为每个条形指定了颜色
# align="center" 表示条形在x轴上的位置是对齐的
bars = plt.bar(range(num_to_plot),
               importances[indices[:num_to_plot]],
               color=([str(i/float(num_to_plot+1)) for i in range(num_to_plot)]),
               align="center")

# 设置x轴的刻度标签
# ticks = plt.xticks() 用于设置x轴的刻度
# range(num_to_plot) 提供了刻度的位置
# feature_indices 提供了刻度的&nbsp;<svg t="1708604394457" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2125" width="200" height="200"><path d="M512 64c247.424 0 448 200.576 448 448s-200.576 448-448 448S64 759.424 64 512 264.576 64 512 64z m0 256a192 192 0 1 0 0 384 192 192 0 0 0 0-384z" fill="#5b79e4" p-id="2126"></path></svg>

上图表明,消费者常常更关心服务人员素质(Staff)和性价比(Value for money),这两个因子对最终评分的影响最大。然而,这两项特征和其他特征的差别不是非常大,因此排除任何特征都会导致模型准确率的下降。

二、KMean聚类模型

KMeans 聚类算法是一种无监督学习算法,用于将数据集分为若干个类别(称为“簇”)。它的目标是将相似的数据点归为一类,同时保证不同类别的数据点尽可能不同。KMeans 算法是一种迭代算法,其主要步骤如下:

  1. 初始化:随机选择 K 个数据点作为初始聚类中心。

  2. 分配:对于数据集中的每一个数据点,计算其与各个聚类中心的距离,并将其分配到最近的聚类中心所代表的簇中。

  3. 更新:重新计算每个簇的聚类中心。新的聚类中心是该簇中所有数据点的均值。

  4. 迭代:重复步骤 2 和 3,直到满足停止条件。停止条件可以是聚类中心的变化小于某个阈值、达到预设的迭代次数等。

KMeans 算法的优点是简单、易于实现,且计算效率较高。但它也有一些局限性,例如:

  • 初始中心的选择:KMeans 对初始中心的选择比较敏感,不同的初始中心可能会导致不同的聚类结果。

  • 簇的数量 K:KMeans 需要事先指定簇的数量 K,但在实际应用中 K 的值往往是不确定的。

  • 假设数据分布:KMeans 假设簇的形状为球形,这在某些情况下可能不符合数据的实际分布。

尽管有这些局限性,KMeans 仍然是最流行的聚类算法之一,广泛应用于数据挖掘、机器学习、图像处理等领域。

模型补充:    

K-Means 和 K-近邻(K-Nearest Neighbors,简称 K-NN)是两种不同的算法,它们分别用于聚类和分类任务。

  1. K-Means 聚类算法

    • 如前所述,K-Means 是一种聚类算法,用于将无标签的数据集分为 K 个簇。
    • 它通过迭代更新聚类中心的位置,使得每个数据点都属于离它最近的聚类中心所在的簇。
    • K-Means 是无监督学习算法,因为它不需要预先知道数据的标签。
  2. K-近邻(K-NN)分类算法

    • K-NN 是一种监督学习算法,用于分类任务。
    • 它的基本思想是,对于一个未知类别的数据点,通过查看它周围 K 个最近的数据点(邻居)的类别,来确定这个数据点的类别。
    • K-NN 算法在训练阶段只是简单地存储训练数据集,实际的“学习”过程发生在测试阶段,当需要对一个新的数据点进行分类时。

总结来说,K-Means 用于数据的聚类,而 K-NN 用于数据的分类。两者都依赖于“邻近性”的概念,但它们在算法目的、使用场景和操作步骤上都有显著的不同。

 第四期-4题答案提示:cluster/ˈklʌstə(z)/丛、簇     state /steɪt/状态、形态    
classifier/ˈklæsɪfaɪə(r)/ 分类器   accuracy/ˈækjərəsi/  准确性,精确性

这段代码定义了一个名为 classification_with_clustering 的函数,该函数的目的是结合聚类和分类任务来提高分类准确率。具体来说,它使用 KMeans 聚类算法来识别数据中的自然分组,并将这些分组信息作为额外的特征输入到随机森林分类器中。

以下是该函数的详细解释:

  1. 函数参数:

    • rf_classifier: 一个随机森林分类器实例。
    • X_train: 训练数据集的特征部分。
    • X_test: 测试数据集的特征部分。
    • y_train: 训练数据集的标签部分。
    • y_test: 测试数据集的标签部分。
  2. KMeans聚类模型:

    • KMeans(n_clusters=12, random_state=20): 初始化一个 KMeans 聚类模型,设置聚类中心数量为12。random_state 参数确保每次运行代码时都能得到相同的结果,这对于调试和结果复现非常重要。
  3. 对训练集和测试集进行聚类:

    • k_mean.fit_predict(X_train): 对训练集进行聚类,并将聚类结果(每个样本所属的簇)作为新特征加入到训练集中。
    • k_mean.predict(X_test): 对测试集进行聚类,并将聚类结果作为新特征加入到测试集中。
  4. 训练随机森林分类器:

    • rf_classifier.fit(X_train, y_train): 使用加入了聚类特征的新训练集来训练随机森林分类器。
  5. 在测试集上进行预测:

    • rf_classifier.predict(X_test): 使用训练好的分类器在测试集上进行预测。
  6. 计算分类准确率:

    • accuracy_score(y_test, pred): 使用 accuracy_score 函数从 sklearn.metrics 中计算预测准确率。
  7. 返回分类准确率:

    • 函数最后返回计算出的分类准确率。

总的来说,这个函数首先使用 KMeans 聚类算法来识别数据中的自然分组,并将这些分组信息作为额外的特征输入到随机森林分类器中,从而帮助分类器更好地学习和预测数据的类别。

  • 14
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值