特征工程与交叉验证在机器学习中的应用

数据入口:学生考试表现影响因素数据集 - Heywhale.com

本数据集提供了关于影响学生考试成绩的多种因素的全面概述。数据集包含了有关学习习惯、出勤率、家长参与、资源获取等方面的信息。

数据说明

字段名 说明
Hours_Studied 每周学习的小时数
Attendance 出勤率(上课出席的百分比)
Parental_Involvement 家长参与程度(低,中,高)
Access_to_Resources 教育资源的可用性(低,中,高)
Extracurricular_Activities 课外活动参与情况(是,否)
Sleep_Hours 每晚平均睡眠时间(小时)
Previous_Scores 之前考试的分数
Motivation_Level 学生的动机水平(低,中,高)
Internet_Access 互联网接入情况(是,否)
Tutoring_Sessions 每月参加辅导课的次数
Family_Income 家庭收入水平(低,中,高)
Teacher_Quality 教师质量(低,中,高)
School_Type 学校类型(公立,私立)
Peer_Influence 同伴对学业表现的影响(积极,中立,消极)
Physical_Activity 每周平均体育活动时间(小时)
Learning_Disabilities 学习障碍(是,否)
Parental_Education_Level 父母的最高学历(高中,本科,研究生)
Distance_from_Home 家到学校的距离(近,适中,远)
Gender 学生性别(男,女)
Exam_Score 期末考试成绩

在本文中将分析不同学习习惯、家长参与度、资源获取等对学生考试成绩的影响以及构建机器学习模型预测学生的考试成绩。

一:影响因素分析

python 复制代码
import pandas as pd

file_path = 'StudentPerformanceFactors.csv'
df = pd.read_csv(file_path)

df.info()

了解到该数据含有较少的空缺值,可以进行删除:

python 复制代码
df = df[(df!= 0).all(axis=1)]

我们的目标是分析这些因素对Exam_Score(考试成绩)的影响。为了进行这个分析,我们可以采用以下步骤:

  1. 描述性统计分析:首先,我们可以查看这些变量的描述性统计信息,以了解其分布和基本特征。
  2. 相关性分析:接着,我们可以计算这些变量与考试成绩之间的相关性,以找出哪些因素与考试成绩最相关。
  3. 可视化分析:为了更直观地展示结果,我们可以创建一些图表来可视化这些关系。

让我们首先进行描述性统计分析。

python 复制代码
descriptive_stats = df[['Hours_Studied', 'Attendance', 'Parental_Involvement', 'Access_to_Resources',
                        'Extracurricular_Activities', 'Sleep_Hours', 'Previous_Scores', 'Motivation_Level',
                        'Internet_Access', 'Tutoring_Sessions', 'Family_Income', 'Teacher_Quality',
                        'School_Type', 'Peer_Influence', 'Physical_Activity', 'Learning_Disabilities',
                        'Parental_Education_Level', 'Distance_from_Home', 'Gender', 'Exam_Score']].describe()

descriptive_stats

以下是对相关字段的描述性统计分析结果:

  • Hours_Studied(学习时间)

    • 平均值:约20小时
    • 标准差:约6小时
    • 最小值:1小时
    • 最大值:44小时
  • Attendance(出勤率)

    • 平均值:约80%
    • 标准差:约12%
    • 最小值:60%
    • 最大值:100%
  • Sleep_Hours(睡眠时间)

    • 平均值:约7小时
    • 标准差:约1.5小时
    • 最小值:4小时
    • 最大值:10小时
  • Previous_Scores(历史成绩)

    • 平均值:约75分
    • 标准差:约14分
    • 最小值:50分
    • 最大值:100分
  • Tutoring_Sessions(辅导课程数量)

    • 平均值:约1.5次
    • 标准差:约1.2次
    • 最小值:0次
    • 最大值:8次
  • Physical_Activity(体育活动)

    • 平均值:约3次
    • 标准差:约1次
    • 最小值:0次
    • 最大值:6次
  • Exam_Score(考试成绩)

    • 平均值:约67分
    • 标准差:约4分
    • 最小值:55分
    • 最大值:101分

接下来,我们可以进行相关性分析,以查看这些变量与考试成绩之间的相关性。

python 复制代码
correlation_matrix = df[['Hours_Studied', 'Attendance', 'Sleep_Hours', 'Previous_Scores', 
                         'Tutoring_Sessions', 'Physical_Activity', 'Exam_Score']].corr()

correlation_matrix['Exam_Score']

以下是与考试成绩(Exam_Score)的相关性分析结果:

  • Hours_Studied(学习时间):0.445 - 表明学习时间与考试成绩有中等程度的正相关。
  • Attendance(出勤率):0.581 - 表明出勤率与考试成绩有较强的正相关。
  • Sleep_Hours(睡眠时间):-0.017 - 表明睡眠时间与考试成绩几乎不相关。
  • Previous_Scores(历史成绩):0.175 - 表明历史成绩与考试成绩有较弱的正相关。
  • Tutoring_Sessions(辅导课程数量):0.157 - 表明辅导课程数量与考试成绩有较弱的正相关。
  • Physical_Activity(体育活动):0.028 - 表明体育活动与考试成绩几乎不相关。

为了更直观地展示这些关系,我们可以创建一些图表来可视化这些关系。我们可以从最相关的变量开始,比如学习时间、出勤率和历史成绩。让我们为这些变量创建散点图。

python 复制代码
import matplotlib.pyplot as plt
import seaborn as sns

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

plt.figure(figsize=(15, 10))

plt.subplot(2, 2, 1)
sns.scatterplot(x='Hours_Studied', y='Exam_Score', data=df)
plt.title('学习时间 vs 考试成绩')

plt.subplot(2, 2, 2)
sns.scatterplot(x='Attendance', y='Exam_Score', data=df)
plt.title('出勤率 vs 考试成绩')

plt.subplot(2, 2, 3)
sns.scatterplot(x='Previous_Scores', y='Exam_Score', data=df)
plt.title('历史成绩 vs 考试成绩')

plt.tight_layout()

plt.show()

从上面的散点图中,我们可以观察到以下关系:

  1. 学习时间 vs 考试成绩:可以看到,随着学习时间的增加,考试成绩也呈现出一定的上升趋势。这证实了之前的正相关分析。

  2. 出勤率 vs 考试成绩:出勤率与考试成绩之间也呈现出正相关关系。随着出勤率的提高,考试成绩也有所提高。

  3. 历史成绩 vs 考试成绩:历史成绩与考试成绩之间也有一定的正相关关系,尽管没有前两个因素那么明显。

二:学业表现预测

为了构建一个适合的机器学习模型来预测学生的考试成绩,我们可以遵循以下步骤:

1: 数据预处理

  • 缺失值处理:检查数据集中是否存在缺失值,并决定是填充缺失值、删除缺失值还是保留它们**。**
  • 分类变量编码:将分类变量(如性别、学校类型等)转换为数值型,可以使用独热编码(One-Hot Encoding)或标签编码(Label Encoding)。
  • 特征选择:根据之前的描述性统计和相关性分析,选择对考试成绩影响最大的特征。
  • 数据标准化/归一化:将所有特征缩放到相同的范围,以避免某些特征对模型的影响过大。

2: 模型选择

  • 选择合适的机器学习算法。对于回归问题,常见的算法包括线性回归、决策树、随机森林、梯度提升机(如XGBoost)等。
  • 可以使用交叉验证来评估模型的性能。

3: 模型训练与评估

  • 将数据集分为训练集和测试集。
  • 使用训练集训练模型,并使用测试集评估模型的性能。
  • 使用适当的评估指标,如均方误差(MSE)、决定系数(R²)等。

4: 模型调优

  • 根据模型在测试集上的表现,调整模型的参数,以提高模型的预测能力。
  • 可以使用网格搜索(Grid Search)或随机搜索(Random Search)来寻找最优参数。

5: 模型部署

  • 一旦模型性能满意,可以将模型部署到实际应用中,用于预测新学生的考试成绩。

1:数据预处理

随机森林(Random Forest)和梯度提升树(Gradient Boosting Tree)在一定程度上可以从数值变量的标准化中受益,但通常不是严格必需的。

python 复制代码
X = df.drop('Exam_Score', axis=1)
y = df['Exam_Score']

categorical_cols = X.select_dtypes(include=['object', 'category']).columns

X_encoded = pd.get_dummies(X, columns=categorical_cols, drop_first=True)

scaler = StandardScaler()

X_numeric = X_encoded.select_dtypes(include=['int', 'float'])

X_scaled = scaler.fit_transform(X_numeric)

X_scaled_df = pd.DataFrame(X_scaled, columns=X_numeric.columns)

X_scaled_df

由于数据集包含分类特征,我们需要对这些特征进行编码,使其能够被机器学习模型所使用。通常,我们可以使用独热编码(One-Hot Encoding)或标签编码(Label Encoding)来处理分类特征。在这个例子中,我们将使用独热编码来处理所有的分类特征。且对数值特征进行标准化。

在对数值特征进行标准化以及对分类特征进行了独热编码之后,生成了一个新的特征矩阵 X_encoded。现在我们可以继续进行特征工程和模型选择。

由于数据集的特征较多,我们可能需要进行特征选择来提高模型的性能。一种常见的方法是使用基于树模型的特征重要性来选择最重要的特征。在这里,我们可以使用随机森林作为基模型来进行特征选择。让我们使用随机森林模型来确定特征的重要性,并选择最重要的特征。

python 复制代码
from sklearn.ensemble import RandomForestRegressor
from sklearn.feature_selection import SelectFromModel

rf = RandomForestRegressor(n_estimators=100, random_state=42)

rf.fit(X_encoded, y)

selector = SelectFromModel(rf, threshold='median')

X_selected = selector.transform(X_encoded)

selected_features = X_encoded.columns[selector.get_support()]

selected_features.tolist()

我们已经使用随机森林模型选择了以下最重要的特征:

  • Hours_Studied
  • Attendance
  • Sleep_Hours
  • Previous_Scores
  • Tutoring_Sessions
  • Physical_Activity
  • Parental_Involvement_Low
  • Parental_Involvement_Medium
  • Access_to_Resources_Low
  • Family_Income_Low
  • Peer_Influence_Positive
  • Parental_Education_Level_High School
  • Parental_Education_Level_Postgraduate

现在我们可以使用这些特征来训练我们的集成学习模型。在这里,我们将使用随机森林和梯度提升树(Gradient Boosting Tree)两种集成学习方法,并比较它们的性能。

2:随机森林与梯度提升树

首先,我们将数据集分为训练集和测试集,然后分别在训练集上训练两个模型,并在测试集上评估它们的性能。

python 复制代码
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.ensemble import GradientBoostingRegressor
import numpy as np

X_train, X_test, y_train, y_test = train_test_split(X_selected, y, test_size=0.2, random_state=42)

rf = RandomForestRegressor(n_estimators=100, random_state=42)
gbt = GradientBoostingRegressor(n_estimators=100, random_state=42)

rf.fit(X_train, y_train)
gbt.fit(X_train, y_train)

rf_pred = rf.predict(X_test)
gbt_pred = gbt.predict(X_test)

rf_mse = mean_squared_error(y_test, rf_pred)
gbt_mse = mean_squared_error(y_test, gbt_pred)

rf_mse, gbt_mse

我们已经训练了随机森林和梯度提升树模型,并在测试集上评估了它们的性能。以下是两个模型的均方误差(MSE):

  • 随机森林(Random Forest)的MSE: 6.51
  • 梯度提升树(Gradient Boosting Tree)的MSE: 5.11

从结果来看,梯度提升树模型的性能略优于随机森林模型。这意味着梯度提升树模型可能更好地捕捉了数据中的模式和关系。

3:交叉验证

python 复制代码
from sklearn.model_selection import cross_val_score

rf_scores = cross_val_score(rf, X_selected, y, scoring='neg_mean_squared_error', cv=5)
gbt_scores = cross_val_score(gbt, X_selected, y, scoring='neg_mean_squared_error', cv=5)

rf_mse_cv = -rf_scores.mean()
gbt_mse_cv = -gbt_scores.mean()

rf_mse_cv, gbt_mse_cv

分别求出随机森林与梯度提升树的交叉验证cv值分别约为6.41和5.52。

这段代码使用了Python的scikit-learn库来进行机器学习模型的交叉验证评分:

from sklearn.model_selection import cross_val_score

这里导入了cross_val_score函数,它用于执行交叉验证并计算模型的性能指标。

随机森林模型的交叉验证:

rf_scores = cross_val_score(rf, X_selected, y, scoring='neg_mean_squared_error', cv=5)
  • rf 是一个随机森林回归模型,它已经被实例化并准备好用于评分。
  • X_selected 是特征矩阵,包含了用于训练模型的数据。
  • y 是目标变量,即我们试图预测的值。
  • scoring='neg_mean_squared_error' 表示评分标准是负的均方误差(MSE)。在scikit-learn中,某些评分标准会被最大化,因此实际的MSE值被取反,以便使用最大化策略。
  • cv=5 表示交叉验证的折数,这里使用了5折交叉验证。

梯度提升树模型的交叉验证:

gbt_scores = cross_val_score(gbt, X_selected, y, scoring='neg_mean_squared_error', cv=5)
  • gbt 是一个梯度提升树(Gradient Boosting Tree)回归模型,它也已经被实例化。
  • 其他参数与随机森林模型的交叉验证相同。

计算交叉验证的平均MSE

rf_mse_cv = -rf_scores.mean()
gbt_mse_cv = -gbt_scores.mean()
  • 由于cross_val_score返回的是负的MSE值,所以在计算平均值时,需要再次取反以得到正的MSE值。
  • rf_scores.mean()gbt_scores.mean() 分别计算了随机森林和梯度提升树模型在5折交叉验证中的平均MSE。
rf_mse_cv, gbt_mse_cv

最后,这段代码将输出随机森林和梯度提升树模型在交叉验证中的平均MSE值。这两个值可以用来比较两个模型的性能。

总结来说,这段代码的主要目的是通过5折交叉验证来评估随机森林和梯度提升树模型的性能,并比较它们在给定数据集上的均方误差。这种方法可以帮助我们了解模型在未知数据上的泛化能力。

在交叉验证中,cv值(交叉验证折数)的大小可以说明以下几个方面:

一、对模型评估的准确性和稳定性

较大的 cv 值(如 10 或更多)

优势 :能更细致地评估模型在不同数据子集上的性能,使得模型评估结果更加准确和可靠。因为有更多不同的数据划分组合,模型会接触到更多不同的数据情况,从而更好地反映其在总体数据上的泛化能力。对于数据量较大的情况,较大的 cv 值可以充分利用数据,减少评估结果的方差,提供更稳定的性能估计。

劣势 :计算成本较高。随着 cv 值的增加,需要进行更多次的模型训练和评估,这会显著增加计算时间和资源消耗。

较小的 cv 值(如 3 或 5)

优势:计算速度快,适用于数据量较小或者计算资源有限的情况。在一些快速迭代的场景中,可以更快地得到模型性能的初步评估,以便进行参数调整和模型改进。

劣势:评估结果可能不够准确和稳定。由于数据划分的组合较少,模型可能没有充分接触到不同的数据情况,导致评估结果的方差较大,不能很好地反映模型的真实泛化能力。

二、对数据的利用程度

较大的 cv :能够更充分地利用数据进行评估,因为每次划分时不同的数据子集被用作训练和验证,使得模型在不同的数据组合上进行学习和评估,从而更好地挖掘数据中的信息。然而,对于非常大的 cv 值,可能会导致每个折叠中的数据量过少,尤其是在数据总量有限的情况下,这可能会使模型在某些折叠上的训练不充分,影响评估的准确性。

较小的 cv:每个折叠中的数据量相对较多,模型在每个折叠上的训练相对更充分。但是,数据的利用程度相对较低,可能没有充分探索数据的多样性,导致评估结果可能不够全面。

三、适用场景

较大的 cv :适用于数据量较大、模型复杂度较高或者对评估准确性要求较高的情况。例如,在进行复杂的机器学习模型训练时,为了获得更可靠的性能评估,可以选择较大的 cv 值。当数据具有较高的多样性和复杂性时,较大的 cv 值可以更好地捕捉模型在不同数据情况下的表现。

较小的 cv :适用于数据量较小、计算资源有限或者需要快速得到模型评估结果的情况。例如,在进行初步的模型探索或快速迭代的实验中,较小的 cv 值可以节省计算时间,同时提供一个相对快速的性能评估。

4:集成学习

在机器学习中,集成学习是一种强大的技术,它通过结合多个模型来提高预测性能。对于随机森林和梯度提升树这两种模型,我们可以采用几种不同的集成策略:

模型融合(Model Blending)

  • 这是一种简单的集成方法,它涉及训练多个模型并将它们的预测结果以加权平均或投票的方式进行合并。
  • 例如,我们可以给随机森林和梯度提升树分配不同的权重,然后根据这些权重对它们的预测结果进行加权平均。

堆叠(Stacking)

  • 堆叠是一种分层模型集成技术,它首先使用多个不同的模型进行预测,然后使用另一个模型(通常是一个逻辑回归模型)来学习如何最好地结合这些预测。
  • 在堆叠中,每个模型的输出被用作第二层模型的输入。

混合(Ensemble by Weighting)

  • 这是一种为每个模型分配权重的方法,权重可以通过优化算法来确定,以最小化整个集成模型的预测误差。

超级学习器(Super Learner)

  • 超级学习器是一种特定的堆叠方法,它使用所有基本模型的预测以及真实标签来训练一个元模型,这个元模型用于生成最终的预测。
  • 超级学习器通常使用交叉验证来训练基本模型,并使用另一种交叉验证来训练元模型。

接下来,我们将选择**堆叠(Stacking)**作为集成策略。堆叠是一种分层模型集成技术,它首先使用多个不同的模型进行预测,然后使用另一个模型来学习如何最好地结合这些预测。

python 复制代码
from sklearn.ensemble import StackingRegressor
from sklearn.linear_model import LinearRegression

stacking_regressor = StackingRegressor(estimators=[
    ('rf', rf),
    ('gbt', gbt)
], final_estimator=LinearRegression())

stacking_regressor.fit(X_train, y_train)

stacking_pred = stacking_regressor.predict(X_test)

stacking_mse = mean_squared_error(y_test, stacking_pred)

stacking_mse

得出均方误差(MSE)约为6.39。可以看出不一定集成学习比某单个模型的效果更好,但一般情况下集成学习比单个模型的预测效果较好。

想要探索多元化的数据分析视角,可以关注之前发布的内容。

相关推荐
古希腊掌管学习的神1 小时前
[机器学习]XGBoost(3)——确定树的结构
人工智能·机器学习
梧桐树04293 小时前
python常用内建模块:collections
python
Dream_Snowar3 小时前
速通Python 第三节
开发语言·python
海棠AI实验室3 小时前
AI的进阶之路:从机器学习到深度学习的演变(一)
人工智能·深度学习·机器学习
IT古董4 小时前
【机器学习】机器学习的基本分类-强化学习-策略梯度(Policy Gradient,PG)
人工智能·机器学习·分类
蓝天星空4 小时前
Python调用open ai接口
人工智能·python
睡觉狂魔er4 小时前
自动驾驶控制与规划——Project 3: LQR车辆横向控制
人工智能·机器学习·自动驾驶
jasmine s5 小时前
Pandas
开发语言·python
郭wes代码5 小时前
Cmd命令大全(万字详细版)
python·算法·小程序
scan7245 小时前
LILAC采样算法
人工智能·算法·机器学习