kaggle比赛入门 - House Prices - Advanced Regression Techniques(第三部分)

本文承接上一篇。

1. 数据预处理流水线(pipelines)

from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
# define transformers for numerical and categorical columns
numerical_transformer = Pipeline(steps=[('imputer', SimpleImputer(strategy='mean')),('scaler', StandardScaler())
])categorical_transformer = Pipeline(steps=[('imputer', SimpleImputer(strategy='constant',fill_value='missing')),('onehot', OneHotEncoder(handle_unknown='ignore',sparse_output=False))
])

这段代码定义了两个数据预处理流水线(pipelines),分别针对数值型数据类别型数据进行特定的转换操作。以下是逐步解释:


1. 目标

对数值型和类别型特征进行预处理,以便后续建模使用。这是实现机器学习流水线的重要步骤。

  • 数值型特征:处理缺失值、归一化或标准化。
  • 类别型特征:处理缺失值、转换为数值格式(如独热编码)。

2. 数值型特征的预处理

numerical_transformer = Pipeline(steps=[('imputer', SimpleImputer(strategy='mean')),('scaler', StandardScaler())
])
  • Pipeline

    • 定义一个包含多个处理步骤的流水线,按照步骤顺序对数值型特征进行转换。
  • 步骤解析

    1. ('imputer', SimpleImputer(strategy='mean'))

      • SimpleImputer 用于填补缺失值。
      • 参数 strategy='mean' 表示使用数值特征的平均值填补缺失数据。
    2. ('scaler', StandardScaler())

      • StandardScaler 用于对数据进行标准化。
      • 将特征值转换为均值为 0、标准差为 1 的标准正态分布,便于模型处理不同尺度的特征。

3. 类别型特征的预处理

categorical_transformer = Pipeline(steps=[('imputer', SimpleImputer(strategy='constant', fill_value='missing')),('onehot', OneHotEncoder(handle_unknown='ignore', sparse_output=False))
])
  • 步骤解析
    1. ('imputer', SimpleImputer(strategy='constant', fill_value='missing'))

      • 使用 SimpleImputer 填补缺失值。
      • 参数 strategy='constant' 指定填充值为固定值。
      • 参数 fill_value='missing' 表示将缺失值替换为字符串 'missing',以明确标记缺失数据。
    2. ('onehot', OneHotEncoder(handle_unknown='ignore', sparse_output=False))

      • OneHotEncoder 将类别型特征转换为独热编码形式。
      • 参数 handle_unknown='ignore':忽略测试数据中未见过的类别,而不抛出错误。
      • 参数 sparse_output=False:返回密集矩阵(非稀疏格式)。

4. 总结功能

  • 数值型特征流水线

    • 填充缺失值(使用均值)。
    • 标准化(缩放到均值为 0,标准差为 1)。
  • 类别型特征流水线

    • 填充缺失值(使用固定值 'missing')。
    • 将类别型特征编码为数值独热编码格式。

应用场景

  1. 结合 ColumnTransformer,将这两个流水线分别应用到数据集中数值型和类别型的列。
  2. 用于机器学习模型的前置处理,确保数据一致性和模型训练效果。
  3. 减少重复代码,自动化数据预处理流程。

通过这种模块化的流水线设计,数据预处理变得更加清晰、灵活且易于扩展。

2. 从 DataFrame 中区分出类别型列和数值型列

# update categorical and numerical columns
categorical_columns = df.select_dtypes(include=['object', 'category']).columns
numerical_columns = df.select_dtypes(include=['int64', 'float64']).columns

这段代码的目的是从 DataFrame 中区分出类别型列和数值型列,以便对它们进行分别处理。以下是详细的解释:


代码拆解

1. 提取类别型列
categorical_columns = df.select_dtypes(include=['object', 'category']).columns
  • df.select_dtypes(include=...)

    • 这是 Pandas 提供的一个方法,用于选择具有特定数据类型的列。
    • 参数 include=['object', 'category'] 表示选择数据类型为 objectcategory 的列。
  • 解释数据类型

    • object:通常用于存储字符串数据(例如文本)。
    • category:表示类别型数据(例如有限的离散值集合,如 'low', 'medium', 'high')。
  • .columns

    • 获取选择出的列的名称,返回一个 Index 对象,包含所有满足条件的列名。
  • 结果

    • categorical_columns 是一个包含 DataFrame 中所有类别型列名称的列表。

2. 提取数值型列
numerical_columns = df.select_dtypes(include=['int64', 'float64']).columns
  • include=['int64', 'float64']

    • 选择数据类型为 int64float64 的列。
    • int64:表示整数型数据。
    • float64:表示浮点数型数据。
  • .columns

    • 获取选择出的列的名称。
  • 结果

    • numerical_columns 是一个包含 DataFrame 中所有数值型列名称的列表。

应用场景

  1. 区分列类型

    • 类别型列通常需要编码(如独热编码或标签编码)。
    • 数值型列可能需要归一化、标准化、或填充缺失值。
  2. 结合流水线预处理

    • 可以将 categorical_columnsnumerical_columns 作为输入,分别传递给之前定义的 categorical_transformernumerical_transformer 进行处理。
  3. 灵活的数据操作

    • 有助于自动化数据预处理,避免手动指定列名,提高代码的可复用性。

numerical_columns
Index(['Id', 'MSSubClass', 'LotFrontage', 'LotArea', 'OverallQual','OverallCond', 'YearBuilt', 'YearRemodAdd', 'MasVnrArea', 'BsmtFinSF1','BsmtFinSF2', 'BsmtUnfSF', 'TotalBsmtSF', '1stFlrSF', '2ndFlrSF','LowQualFinSF', 'GrLivArea', 'BsmtFullBath', 'BsmtHalfBath', 'FullBath','HalfBath', 'BedroomAbvGr', 'KitchenAbvGr', 'TotRmsAbvGrd','Fireplaces', 'GarageYrBlt', 'GarageCars', 'GarageArea', 'WoodDeckSF','OpenPorchSF', 'EnclosedPorch', '3SsnPorch', 'ScreenPorch', 'PoolArea','MiscVal', 'MoSold', 'YrSold', 'SalePrice', 'PropertyAge'],dtype='object')
# remove target variable from numerical columns
numerical_columns = numerical_columns.drop('SalePrice')
numerical_columns
Index(['Id', 'MSSubClass', 'LotFrontage', 'LotArea', 'OverallQual','OverallCond', 'YearBuilt', 'YearRemodAdd', 'MasVnrArea', 'BsmtFinSF1','BsmtFinSF2', 'BsmtUnfSF', 'TotalBsmtSF', '1stFlrSF', '2ndFlrSF','LowQualFinSF', 'GrLivArea', 'BsmtFullBath', 'BsmtHalfBath', 'FullBath','HalfBath', 'BedroomAbvGr', 'KitchenAbvGr', 'TotRmsAbvGrd','Fireplaces', 'GarageYrBlt', 'GarageCars', 'GarageArea', 'WoodDeckSF','OpenPorchSF', 'EnclosedPorch', '3SsnPorch', 'ScreenPorch', 'PoolArea','MiscVal', 'MoSold', 'YrSold', 'PropertyAge'],dtype='object')

3. 整合一个预处理器和流水线,用于对数据进行统一、系统化的处理

# combine transformers using ColumnTransformer
preprocessor = ColumnTransformer(transformers=[('num', numerical_transformer, numerical_columns),('cat', categorical_transformer, categorical_columns)
], remainder = 'passthrough')# create a pipeline with the preprocessor
pipeline = Pipeline(steps=[('preprocessor', preprocessor)])

这段代码结合了前面定义的数值和类别型数据的处理逻辑,并将它们整合到一个预处理器和流水线中,用于对数据进行统一、系统化的处理。以下是详细的解释:


代码拆解

1. ColumnTransformer
preprocessor = ColumnTransformer(transformers=[('num', numerical_transformer, numerical_columns),('cat', categorical_transformer, categorical_columns)
], remainder='passthrough')
  • ColumnTransformer

    • 用于对不同列(根据列的数据类型或功能分类)应用不同的转换器。
  • 参数详解

    • transformers
      • 是一个列表,定义了每一类列的处理方式:
        • ('num', numerical_transformer, numerical_columns)
          • 将之前定义的 numerical_transformer 应用于 numerical_columns(数值型列)。
        • ('cat', categorical_transformer, categorical_columns)
          • 将之前定义的 categorical_transformer 应用于 categorical_columns(类别型列)。
    • remainder='passthrough'
      • 对于未在 transformers 中指定的列(如果存在),直接保留原始数据,不进行任何处理。
  • 结果

    • preprocessor 是一个组合的转换器,会对数值型列和类别型列分别应用其对应的预处理方法。

2. Pipeline
pipeline = Pipeline(steps=[('preprocessor', preprocessor)])
  • Pipeline

    • 是一种结构化的方法,用于将一系列数据预处理步骤组合在一起。
    • 它按照顺序应用各个步骤,将前一步的输出作为后一步的输入。
  • 参数详解

    • steps
      • 是一个列表,定义流水线的各步骤。
      • ('preprocessor', preprocessor)
        • 第一步是应用之前定义的 preprocessor,用于对数据进行预处理。
  • 结果

    • pipeline 是一个完整的预处理流水线,能够统一对输入数据执行数值型和类别型列的预处理操作。

工作流程

  1. 数值型列 numerical_columns 会经过以下处理:
    • 缺失值填充(使用 SimpleImputer(strategy='mean'))。
    • 数据标准化(使用 StandardScaler())。
  2. 类别型列 categorical_columns 会经过以下处理:
    • 缺失值填充(使用 SimpleImputer(strategy='constant', fill_value='missing'))。
    • 独热编码(使用 OneHotEncoder())。
  3. 其他未指定的列(如果存在)会被直接保留下来(因为 remainder='passthrough')。

使用场景

  • 这是用于机器学习模型构建中的数据预处理部分,可以方便地将 pipeline 与后续的模型结合(例如回归、分类模型)。
  • 提高代码的可复用性和可读性,适用于不同的数据集。

4. 对数据集进行预处理

# apply the pipeline to your dataset
X = df.drop('SalePrice', axis=1)
y = np.log(df['SalePrice']) # normalize dependent variable
X_preprocessed = pipeline.fit_transform(X)

这段代码应用了前面定义的预处理流水线 pipeline,对数据集进行预处理,以便用于后续的机器学习建模。以下是代码的逐步解析:


代码拆解

1. 定义特征和目标变量
X = df.drop('SalePrice', axis=1)
y = np.log(df['SalePrice']) # normalize dependent variable
  • X:

    • 使用 df.drop('SalePrice', axis=1) 从数据集中移除目标变量 SalePrice,只保留特征数据。
    • 目的
      • 为机器学习模型准备输入特征矩阵 X
  • y:

    • 使用 np.log(df['SalePrice']) 对目标变量 SalePrice 取自然对数。
    • 目的
      • 规范化(normalize)目标变量,使其更接近正态分布。
      • 机器学习模型(例如线性回归)对正态分布的目标变量更容易建模。

2. 应用预处理流水线
X_preprocessed = pipeline.fit_transform(X)
  • pipeline.fit_transform(X):

    • X 应用之前定义的 pipeline,执行以下步骤:
      1. 数值型列
        • 填充缺失值(使用均值填充)。
        • 数据标准化(调整为均值为 0、标准差为 1 的分布)。
      2. 类别型列
        • 填充缺失值(使用 'missing' 填充)。
        • 独热编码(将类别转换为数值型二进制列)。
      3. 其他列
        • 如果存在未指定的列,直接保留原始数据(因为 remainder='passthrough')。
    • 结果
      • 返回一个预处理后的特征矩阵 X_preprocessed,可以直接用于训练机器学习模型。
  • fit_transform 的作用

    • fit
      • 计算数据的统计信息(如均值、标准差、类别种类等),为后续的转换做好准备。
    • transform
      • 根据前面计算的信息,对数据进行转换(如标准化、编码等)。

结果分析

  • X_preprocessed 是预处理后的特征矩阵,包含数值型列的标准化值和类别型列的独热编码值。
  • y 是经过自然对数变换的目标变量,规范化后更适合建模。

5. 对三种模型进行超参数搜索

from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor
from xgboost import XGBRegressor
from sklearn.model_selection import GridSearchCV, KFold, cross_val_score
# split the data into training and testing sets
from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X_preprocessed, y, test_size=0.2, random_state=42)
# define the models
models = {'LinearRegression': LinearRegression(),'RandomForest': RandomForestRegressor(random_state=42),'XGBoost': XGBRegressor(random_state=42)
}
# define the hyperparameter grids for each model 
param_grids = {'LinearRegression': {},'RandomForest': {'n_estimators': [100, 200, 500],'max_depth': [None, 10, 30],'min_samples_split': [2, 5, 10],},'XGBoost':{'n_estimators': [100, 200, 500],'learning_rate': [0.01, 0.1, 0.3],'max_depth': [3, 6, 10],}
}

这段代码定义了用于模型超参数调优的参数网格字典 param_grids,为多个模型提供其可选的超参数组合。以下是逐步解析:


代码解析

1. 变量 param_grids
  • param_grids 是一个字典,包含多个模型的名称作为键,以及它们对应的超参数网格(也是字典)作为值。
  • 作用
    • 用于超参数搜索(如网格搜索或随机搜索)以优化模型性能。

2. 超参数网格定义
1) LinearRegression
'LinearRegression': {}
  • 解释
    • 对于线性回归模型,没有定义需要调优的超参数,因此参数网格为空字典 {}
    • 线性回归模型通常没有过多可调参数(如正则化项等需使用其他变体如岭回归)。

2) RandomForest
'RandomForest': {'n_estimators': [100, 200, 500],'max_depth': [None, 10, 30],'min_samples_split': [2, 5, 10],
}
  • 解释
    • 这是随机森林模型的超参数网格:
      1. n_estimators
        • 随机森林中树的数量。
        • 候选值为 [100, 200, 500],较多的树可能提升模型稳定性但增加计算时间。
      2. max_depth
        • 树的最大深度。
        • 候选值为 [None, 10, 30]None 表示树的深度不限。
      3. min_samples_split
        • 内部节点再分裂所需的最小样本数。
        • 候选值为 [2, 5, 10],值越大越能限制过拟合。

3) XGBoost
'XGBoost': {'n_estimators': [100, 200, 500],'learning_rate': [0.01, 0.1, 0.3],'max_depth': [3, 6, 10],
}
  • 解释
    • 这是 XGBoost 模型的超参数网格:
      1. n_estimators
        • XGBoost 中树的数量。
        • 候选值为 [100, 200, 500]
      2. learning_rate
        • 学习率,控制每次迭代的步长。
        • 候选值为 [0.01, 0.1, 0.3],较低的值可以提高模型稳定性,但需要更多迭代次数。
      3. max_depth
        • 每棵树的最大深度。
        • 候选值为 [3, 6, 10],较大的深度允许捕捉更复杂的关系,但可能导致过拟合。

结果

  • 这段代码为三种模型(LinearRegression, RandomForest, XGBoost)分别定义了超参数搜索空间。
  • 后续可以结合这些参数网格执行调优,寻找性能最优的超参数组合。

6. 通过网格搜索找到每个模型的最佳超参数组合

# 3-fold cross-validation
cv = KFold(n_splits=3, shuffle=True, random_state=42)# train and tune the models
grids = {}
for model_name, model in models.items():print(f'Training and tuning {model_name}...')grids[model_name] = GridSearchCV(estimator=model,param_grid=param_grids[model_name],cv=cv,scoring='neg_mean_squared_error',n_jobs=-1,verbose=2)grids[model_name].fit(X_train, y_train)best_params = grids[model_name].best_params_best_score = np.sqrt(-1 * grids[model_name].best_score_)print(f'Best parameters for {model_name}: {best_params}')print(f'Best RMSE for {model_name}: {best_score}\n')

这段代码使用 3 折交叉验证 对多个机器学习模型进行训练和调参,目标是通过网格搜索(GridSearchCV)找到每个模型的最佳超参数组合,同时评估其预测性能(以 RMSE 为度量)。以下是逐步解释:


代码解析

1. 创建 3 折交叉验证对象
cv = KFold(n_splits=3, shuffle=True, random_state=42)
  • KFold:
    • 实现 K 折交叉验证,这里 n_splits=3 表示将数据分成 3 份,每次用 1 份作为验证集,剩余 2 份作为训练集,重复 3 次。
  • 参数解释
    • n_splits=3:3 折交叉验证。
    • shuffle=True:在划分数据之前随机打乱,以减少偏倚。
    • random_state=42:设置随机种子,以保证结果的可复现性。

2. 初始化一个空字典存储网格搜索对象
grids = {}
  • 作用
    • 用来存储每个模型对应的 GridSearchCV 对象及其搜索结果。

3. 迭代训练和调参
for model_name, model in models.items():...
  • models.items():
    • models 是一个字典,其中的键是模型名称(如 'LinearRegression''RandomForest'),值是对应的模型对象(如 LinearRegression(), RandomForestRegressor() 等)。
  • 作用
    • 遍历模型字典,对每个模型分别执行以下步骤。

4. 打印当前模型名称
print(f'Training and tuning {model_name}...')
  • 作用
    • 输出当前正在训练和调参的模型名称,方便跟踪进度。

5. 初始化 GridSearchCV 对象
grids[model_name] = GridSearchCV(estimator=model,param_grid=param_grids[model_name],cv=cv,scoring='neg_mean_squared_error',n_jobs=-1,verbose=2
)
  • GridSearchCV:
    • 网格搜索对象,用于对指定的超参数网格进行搜索。
  • 参数解释
    1. estimator=model:模型实例,例如 LinearRegression()RandomForestRegressor()
    2. param_grid=param_grids[model_name]
      • 超参数网格。
      • 来源于之前定义的 param_grids 字典,对应于当前模型。
    3. cv=cv:指定交叉验证的划分方式,即 3 折交叉验证。
    4. scoring='neg_mean_squared_error'
      • 使用负均方误差作为评估指标(越大越好,负号是因为 scikit-learn 默认要求评分指标越大越好)。
    5. n_jobs=-1:启用多线程,利用所有 CPU 核心以加速搜索。
    6. verbose=2:显示搜索进度,数字越大,输出的详细程度越高。

6. 执行网格搜索
grids[model_name].fit(X_train, y_train)
  • 作用
    • 使用 GridSearchCV 对当前模型进行训练、验证和超参数调优。
    • 数据:
      • X_train:训练特征数据。
      • y_train:训练目标数据(对数化后的 SalePrice)。

7. 提取最佳超参数和最佳评分
best_params = grids[model_name].best_params_
best_score = np.sqrt(-1 * grids[model_name].best_score_)
  • best_params
    • GridSearchCV 获取当前模型的最佳超参数组合。
  • best_score
    • 获取最佳负均方误差(best_score_ 是负值),转换为均方误差的平方根(RMSE)。

8. 打印结果
print(f'Best parameters for {model_name}: {best_params}')
print(f'Best RMSE for {model_name}: {best_score}\n')
  • 作用
    • 输出当前模型的最佳超参数组合和对应的 RMSE,以便于结果分析和比较。

总结

  1. 核心功能

    • 使用 3 折交叉验证对多个模型分别执行超参数调优。
    • 使用 RMSE 评估模型性能,输出每个模型的最佳参数和最优 RMSE。
  2. 运行逻辑

    • 定义交叉验证规则。
    • 遍历所有模型,依次进行网格搜索。
    • 保存最佳结果供后续比较。
Training and tuning LinearRegression...Fitting 3 folds for each of 1 candidates, totalling 3 fitsBest parameters for LinearRegression: {}Best RMSE for LinearRegression: 5394655149.930396Training and tuning RandomForest...Fitting 3 folds for each of 27 candidates, totalling 81 fitsBest parameters for RandomForest: {'max_depth': None, 'min_samples_split': 2, 'n_estimators': 500}Best RMSE for RandomForest: 0.15332719681534118Training and tuning XGBoost...Fitting 3 folds for each of 27 candidates, totalling 81 fitsBest parameters for XGBoost: {'learning_rate': 0.1, 'max_depth': 3, 'n_estimators': 500}Best RMSE for XGBoost: 0.13797005834667236

7. 使用多层感知器回归器对数据进行回归建模

from sklearn.neural_network import MLPRegressorX_train_scaled = X_train.copy()
X_test_scaled = X_test.copy()# create a MLPRegressor instance
mlp = MLPRegressor(random_state = 42,max_iter=10000,n_iter_no_change=3,learning_rate_init=0.001,verbose=True)# define the parameter grid for tuning
param_grid = {'hidden_layer_sizes': [(10,), (10, 10), (10, 10, 10), (25)],'activation': ['relu', 'tanh'],'solver': ['adam'],'alpha': [0.0001, 0.001, 0.01],'learning_rate': ['constant', 'invscaling', 'adaptive'],
}# create the GridSearchCV object
grid_search_mlp = GridSearchCV(mlp, param_grid,scoring='neg_mean_squared_error',cv=3, n_jobs=-1, verbose=1)# fit the model on the training data
grid_search_mlp.fit(X_train_scaled, y_train)# print the best parameters found during the search
print("Best parameters found: ", grid_search_mlp.best_params_)# evaluate the model
best_score = np.sqrt(-1 * grid_search_mlp.best_score_)
print("Best score: ", best_score)
Best parameters found:  {'activation': 'relu', 'alpha': 0.001, 'hidden_layer_sizes': (10, 10), 'learning_rate': 'constant', 'solver': 'adam'}Best score:  0.22778267781613568

这段代码使用 MLPRegressor(多层感知器回归器) 对数据进行回归建模,并通过 GridSearchCV 进行超参数调优。以下是逐步的详细解释:


1. 导入和准备数据

from sklearn.neural_network import MLPRegressorX_train_scaled = X_train.copy()
X_test_scaled = X_test.copy()
  • MLPRegressor
    • 用于回归任务的神经网络模型,适合非线性和复杂关系建模。
  • X_train_scaledX_test_scaled
    • 创建训练和测试数据的副本。这段代码假设输入数据已经被缩放(比如标准化或归一化),因为神经网络对数据的尺度非常敏感

2. 创建 MLPRegressor 实例

mlp = MLPRegressor(random_state=42,max_iter=10000,n_iter_no_change=3,learning_rate_init=0.001,verbose=True)
  • MLPRegressor 参数说明
    • random_state=42:设置随机种子,保证结果可复现。
    • max_iter=10000:最大迭代次数,防止训练时间过长。
    • n_iter_no_change=3:如果验证集损失在连续 3 次迭代中没有改善,则提前停止训练。
    • learning_rate_init=0.001:初始学习率,用于权重更新。
    • verbose=True:输出训练过程的日志信息,方便观察模型收敛情况。

3. 定义参数网格

param_grid = {'hidden_layer_sizes': [(10,), (10, 10), (10, 10, 10), (25)],'activation': ['relu', 'tanh'],'solver': ['adam'],'alpha': [0.0001, 0.001, 0.01],'learning_rate': ['constant', 'invscaling', 'adaptive'],
}
  • param_grid 是一个超参数网格,供网格搜索调参使用。
    • hidden_layer_sizes
      • 定义隐藏层的结构和神经元个数。
      • 示例 (10,) 表示 1 层,10 个神经元;(10, 10) 表示 2 层,每层 10 个神经元。
    • activation
      • 激活函数,用于神经元的输出。
      • relu:修正线性单元(推荐使用,常见于深度学习)。
      • tanh:双曲正切函数,输出范围为 [-1, 1]。
    • solver
      • 用于优化权重的算法。
      • adam:一种高效的随机梯度下降优化算法,默认选择。
    • alpha
      • 正则化参数(L2 惩罚项),防止过拟合。
      • 值越大,正则化强度越大。
    • learning_rate
      • 学习率调节策略:
        • constant:固定学习率。
        • invscaling:随着训练次数增加,学习率逐步减小。
        • adaptive:当训练停止改善时自动降低学习率。

4. 创建 GridSearchCV 对象

grid_search_mlp = GridSearchCV(mlp,param_grid,scoring='neg_mean_squared_error',cv=3,n_jobs=-1,verbose=1
)
  • GridSearchCV 参数说明
    • estimator=mlp:待调参的模型,即 MLPRegressor。
    • param_grid=param_grid:定义的超参数网格。
    • scoring='neg_mean_squared_error'
      • 使用负均方误差(MSE)作为评估指标,最终会取负值。
      • MSE 越小,模型性能越好。
    • cv=3:3 折交叉验证。
    • n_jobs=-1:使用所有可用 CPU 核心并行运行,提升搜索效率。
    • verbose=1:输出网格搜索进度信息。

5. 训练并调参

grid_search_mlp.fit(X_train_scaled, y_train)
  • 作用
    • 在训练集上运行 3 折交叉验证,搜索最佳的超参数组合。

6. 输出最佳超参数和最佳得分

print("Best parameters found: ", grid_search_mlp.best_params_)
best_score = np.sqrt(-1 * grid_search_mlp.best_score_)
print("Best score: ", best_score)
  • best_params_
    • 返回最佳超参数组合,例如:
      Best parameters found: {'activation': 'relu', 'alpha': 0.001, ...}
      
  • best_score_
    • 返回最佳的负均方误差,转换为 RMSE(均方根误差)
    • RMSE 是回归问题中衡量预测误差的常用指标,值越小越好

总结

  1. 目的
    • 使用多层感知器(MLPRegressor)进行回归建模。
    • 通过 GridSearchCV 调参,找到最优的隐藏层结构、激活函数、学习率策略等参数。
  2. 结果输出
    • 最优参数组合(best_params_)。
    • 最佳模型在交叉验证中的 RMSE 值(best_score)。
  3. 实际应用
    • 用于非线性回归问题,特别是当数据有复杂关系时,神经网络是一种强大的建模工具。

8. 使用主成分分析 Principal Component Analysis 来对数据进行降维

from sklearn.decomposition import PCApca = PCA()
X_pca_pre = pca.fit_transform(X_preprocessed)# Calculate the cumulative explained variance
cumulative_explained_variance = np.cumsum(pca.explained_variance_ratio_)
cumulative_explained_variance

这段代码使用主成分分析 (PCA, Principal Component Analysis) 来对数据进行降维,同时计算每个主成分所解释的累计方差比例。以下是逐步的详细解释:


1. 导入 PCA 模块

from sklearn.decomposition import PCA
  • PCA
    • 一种无监督学习方法,用于数据降维和特征提取。
    • 它通过线性变换将原始特征映射到一组新的特征(称为主成分)。
    • 这些主成分按解释原始数据方差的能力排序,前几个主成分通常保留了大部分信息。

2. 创建 PCA 对象

pca = PCA()
  • PCA()
    • 默认情况下,PCA 会计算出所有可能的主成分。
    • 可通过 n_components 参数指定希望保留的主成分个数。例如,PCA(n_components=2) 表示仅保留前 2 个主成分。

3. 对数据进行 PCA 转换

X_pca_pre = pca.fit_transform(X_preprocessed)
  • fit_transform
    • 这一步计算出数据的主成分方向(fit),并将原始数据投影到这些主成分上(transform)。
    • 输入
      • X_preprocessed 是预处理后的数据。
      • 数据通常需要归一化或标准化,因为 PCA 对特征的尺度敏感。
    • 输出
      • X_pca_pre 是转换后的数据,每列表示一个主成分的值。

4. 计算累计解释方差

cumulative_explained_variance = np.cumsum(pca.explained_variance_ratio_)
  • explained_variance_ratio_
    • 表示每个主成分解释的方差占总方差的比例。
    • 例如,[0.5, 0.3, 0.1, 0.1] 表示:
      • 第 1 个主成分解释了 50% 的方差。
      • 第 2 个主成分解释了 30% 的方差。
      • 第 3 和第 4 个主成分各解释了 10% 的方差。
  • np.cumsum
    • 计算累计方差比例。
    • 例如,累计值为 [0.5, 0.8, 0.9, 1.0],表示:
      • 前 1 个主成分解释了 50% 的总方差。
      • 前 2 个主成分解释了 80% 的总方差。
      • 前 3 个主成分解释了 90% 的总方差。

5. 输出累计解释方差

cumulative_explained_variance
  • 输出为一个数组,表示每个主成分的累计解释方差比例。
  • 示例输出:
    array([0.5, 0.75, 0.9, 1.0])
    
    • 前 1 个主成分解释了 50% 的方差。
    • 前 2 个主成分累计解释了 75% 的方差。
    • 前 3 个主成分累计解释了 90% 的方差。
    • 所有主成分累计解释了 100% 的方差。

总结

这段代码的主要作用是:

  1. 使用 PCA 分解数据,提取主成分。
  2. 计算主成分的累计解释方差,帮助判断需要保留的主成分个数。
  3. 为后续的数据降维和模型构建奠定基础。
array([0.17243282, 0.24388356, 0.30683835, 0.34948682, 0.38080478,0.40728548, 0.43229814, 0.4553012 , 0.47784164, 0.49974638,0.52099392, 0.54160949, 0.56158708, 0.58125935, 0.60053254,0.61902405, 0.63641873, 0.65333506, 0.66977935, 0.68565874,0.70081592, 0.71479989, 0.72797553, 0.74013759, 0.75202852,0.76347094, 0.77276728, 0.78133766, 0.78941649, 0.7971427 ,0.80366548, 0.80983832, 0.8158552 , 0.82171262, 0.82712973,0.83247664, 0.8377077 , 0.84289461, 0.8479119 , 0.85243286,0.85687566, 0.86114926, 0.86530002, 0.86933408, 0.87314688,0.87683267, 0.88034602, 0.88383026, 0.88714117, 0.89039485,0.89353886, 0.896602  , 0.89953279, 0.90237039, 0.90520265,0.90797676, 0.91053189, 0.91306058, 0.91547626, 0.91779434,0.92005817, 0.92227619, 0.92438524, 0.92642266, 0.9283981 ,0.9303439 , 0.93223214, 0.93402124, 0.93575219, 0.93747069,0.93914422, 0.94078272, 0.94234897, 0.94387349, 0.94538287,0.94682297, 0.94823643, 0.94959758, 0.95093592, 0.95224158,0.95350946, 0.95472786, 0.95589638, 0.95704969, 0.95817143,0.95926274, 0.9603086 , 0.96132907, 0.96233372, 0.96330337,0.96425211, 0.96518196, 0.96608827, 0.96696542, 0.96781578,0.96861418, 0.96940699, 0.97018496, 0.97094682, 0.97167701,0.97240163, 0.97309352, 0.97378175, 0.97444138, 0.97508567,0.97571937, 0.97634927, 0.97696691, 0.97756939, 0.97815862,0.97873212, 0.97929725, 0.97984866, 0.98039201, 0.98092683,0.98145566, 0.98196764, 0.9824595 , 0.98293804, 0.98341039,0.98387423, 0.98433478, 0.98478139, 0.98521562, 0.98564182,0.98605927, 0.98646022, 0.98685517, 0.98723933, 0.98761082,0.98797424, 0.9883316 , 0.98868368, 0.98902194, 0.98935108,0.98967198, 0.98998727, 0.99029192, 0.99058997, 0.99087116,0.99115127, 0.99141999, 0.99168104, 0.99193879, 0.99218769,0.99242641, 0.9926581 , 0.99287949, 0.99309632, 0.99331018,0.99351827, 0.99372393, 0.99392369, 0.99411309, 0.99430108,0.99448488, 0.99466067, 0.99482919, 0.99499738, 0.99516156,0.99531813, 0.99547122, 0.99562218, 0.99576942, 0.99591437,0.99605398, 0.9961902 , 0.99632357, 0.99645277, 0.99657876,0.99670183, 0.99682237, 0.9969369 , 0.99704846, 0.9971582 ,0.99726432, 0.99736721, 0.99746831, 0.99756467, 0.99765843,0.99775056, 0.99784042, 0.99792818, 0.99801267, 0.99809567,0.99817047, 0.99824177, 0.99831226, 0.99837856, 0.99844265,0.99850534, 0.99856619, 0.99862442, 0.99868095, 0.99873669,0.99879126, 0.99884481, 0.99889584, 0.99894505, 0.99899145,0.99903706, 0.99908194, 0.99912437, 0.99916554, 0.99920626,0.9992444 , 0.99928079, 0.99931607, 0.9993509 , 0.9993834 ,0.99941427, 0.99944282, 0.99947029, 0.99949603, 0.9995212 ,0.99954584, 0.99957006, 0.9995939 , 0.9996169 , 0.99963857,0.9996596 , 0.99967979, 0.99969977, 0.9997183 , 0.9997365 ,0.99975451, 0.99977103, 0.99978734, 0.99980207, 0.99981655,0.9998307 , 0.9998434 , 0.99985601, 0.99986807, 0.99987946,0.99989058, 0.9999016 , 0.99991223, 0.9999227 , 0.99993297,0.99994215, 0.99995048, 0.99995846, 0.99996558, 0.99997209,0.99997818, 0.99998391, 0.99998814, 0.99999217, 0.999996  ,0.9999989 , 0.99999962, 1.        , 1.        , 1.        ,1.        , 1.        , 1.        , 1.        , 1.        ,1.        , 1.        , 1.        , 1.        , 1.        ,1.        , 1.        , 1.        , 1.        , 1.        ,1.        , 1.        , 1.        , 1.        , 1.        ,1.        , 1.        , 1.        , 1.        , 1.        ,1.        , 1.        , 1.        , 1.        , 1.        ,1.        , 1.        , 1.        , 1.        , 1.        ,1.        , 1.        , 1.        , 1.        , 1.        ,1.        , 1.        , 1.        , 1.        , 1.        ,1.        , 1.        , 1.        , 1.        , 1.        ])

9. 通过累计解释方差阈值 (95%) 来选择主成分的数量

# choose the number of components based on the explained variance threshold
n_components = np.argmax(cumulative_explained_variance >= 0.95) + 1pca = PCA(n_components=n_components)
pipeline_pca = Pipeline(steps=[('preprocessor', preprocessor),('pca', pca)
])X_pca = pipeline_pca.fit_transform(X)

这段代码的主要功能是通过累计解释方差阈值 (95%) 来选择主成分的数量,然后将 PCA 集成到一个管道中,以便在预处理后直接进行降维。以下是逐步解释:


1. 根据解释方差选择主成分数量

n_components = np.argmax(cumulative_explained_variance >= 0.95) + 1
  • 目的

    • 自动确定需要保留的主成分数量,使得累计解释方差达到或超过 95%。
  • 步骤

    1. cumulative_explained_variance >= 0.95
      • 比较每个累计解释方差值是否达到或超过 0.95(即 95%)。
      • 结果是一个布尔数组,例如 [False, False, True, True, ...]
    2. np.argmax()
      • 返回第一个 True 的索引,表示第一个达到或超过 95% 的主成分位置。
    3. +1
      • 调整索引为数量,因为主成分的数量从 1 开始,而索引从 0 开始。
  • 结果

    • 变量 n_components 存储保留的主成分数量。例如:
      cumulative_explained_variance = [0.4, 0.7, 0.95, 1.0]
      n_components = np.argmax([False, False, True, True]) + 1  # n_components = 3
      

2. 创建 PCA 实例

pca = PCA(n_components=n_components)
  • 参数
    • n_components=n_components:设置保留的主成分数量,使累计解释方差接近 95%。

3. 创建包含 PCA 的管道

pipeline_pca = Pipeline(steps=[('preprocessor', preprocessor),('pca', pca)
])
  • Pipeline
    • 通过管道将多个数据处理步骤整合在一起,方便后续操作。
    • 步骤
      1. ('preprocessor', preprocessor)
        • 对原始数据进行预处理(如数值标准化、分类变量编码等)。
        • preprocessor 是之前定义的列转换器 (ColumnTransformer)。
      2. ('pca', pca)
        • 应用 PCA 降维,减少特征数量。
  • 优点
    • 使用管道可以保证在数据预处理后立即进行 PCA,简化代码逻辑,减少重复工作。

4. 使用管道处理数据

X_pca = pipeline_pca.fit_transform(X)
  • fit_transform(X)
    • 执行整个管道的所有步骤:
      1. preprocessor.fit_transform(X)
        • 对数据进行预处理(如缺失值填充、数值标准化、分类变量编码等)。
      2. pca.fit_transform(preprocessed_data)
        • 在预处理后的数据上执行 PCA,将其投影到保留的主成分空间。
  • 结果
    • X_pca 是降维后的数据,维度由原始特征数量减少到 n_components

总结

这段代码的主要作用是:

  1. 动态确定需要保留的主成分数量,使得累计解释方差达到 95%。
  2. 构建一个包含预处理和 PCA 的管道,实现一站式数据处理和降维。
  3. 使用该管道对原始数据进行转换,输出降维后的特征矩阵 X_pca

10. 再次通过网格搜索找到每个模型的最佳超参数组合

X_train_pca, X_test_pca, y_train_pca, y_test_pca = train_test_split(X_pca, y, test_size=0.2, random_state=42)# define the models
models = {'LinearRegression': LinearRegression(),'RandomForest': RandomForestRegressor(random_state=42),'XGBoost': XGBRegressor(random_state=42)
}# define the hyperparameter grids for each model 
param_grids = {'LinearRegression': {},'RandomForest': {'n_estimators': [100, 200, 500],'max_depth': [None, 10, 30],'min_samples_split': [2, 5, 10],},'XGBoost':{'n_estimators': [100, 200, 500],'learning_rate': [0.01, 0.1, 0.3],'max_depth': [3, 6, 10],}
}# 3-fold cross-validation
cv = KFold(n_splits=3, shuffle=True, random_state=42)
# train and tune the models
grids_pca = {}
for model_name, model in models.items():print(f'Training and tuning {model_name}...')grids_pca[model_name] = GridSearchCV(estimator=model,param_grid=param_grids[model_name],cv=cv,scoring='neg_mean_squared_error',n_jobs=-1,verbose=2)grids_pca[model_name].fit(X_train_pca, y_train_pca)best_params = grids_pca[model_name].best_params_best_score = np.sqrt(-1 * grids_pca[model_name].best_score_)print(f'Best parameters for {model_name}: {best_params}')print(f'Best RMSE for {model_name}: {best_score}\n')
Training and tuning LinearRegression...Fitting 3 folds for each of 1 candidates, totalling 3 fitsBest parameters for LinearRegression: {}Best RMSE for LinearRegression: 0.16377046612265703Training and tuning RandomForest...Fitting 3 folds for each of 27 candidates, totalling 81 fitsBest parameters for RandomForest: {'max_depth': None, 'min_samples_split': 2, 'n_estimators': 500}Best RMSE for RandomForest: 0.15205832992542345Training and tuning XGBoost...Fitting 3 folds for each of 27 candidates, totalling 81 fitsBest parameters for XGBoost: {'learning_rate': 0.1, 'max_depth': 3, 'n_estimators': 500}Best RMSE for XGBoost: 0.13770460992099054

11. 再次使用多层感知器回归器对数据进行回归建模

X_train_scaled_pca = X_train_pca.copy()
X_test_scaled_pca = X_test_pca.copy()# create a MLPRegressor instance
mlp = MLPRegressor(random_state = 42,max_iter=10000,n_iter_no_change=3,learning_rate_init=0.001,verbose=True)# define the parameter grid for tuning
param_grid = {'hidden_layer_sizes': [(10,), (10, 10), (10, 10, 10), (25)],'activation': ['relu', 'tanh'],'solver': ['adam'],'alpha': [0.0001, 0.001, 0.01, .1, 1],'learning_rate': ['constant', 'invscaling', 'adaptive'],
}# create the GridSearchCV object
grid_search_mlp_pca = GridSearchCV(mlp, param_grid,scoring='neg_mean_squared_error',cv=3, n_jobs=-1, verbose=1)# fit the model on the training data
grid_search_mlp_pca.fit(X_train_scaled_pca, y_train)# print the best parameters found during the search
print("Best parameters found: ", grid_search_mlp_pca.best_params_)# evaluate the model
best_score = np.sqrt(-1 * grid_search_mlp_pca.best_score_)
print("Best score: ", best_score)
Best parameters found:  {'activation': 'tanh', 'alpha': 1, 'hidden_layer_sizes': (10, 10), 'learning_rate': 'constant', 'solver': 'adam'}Best score:  0.20141574193541442

12. 使用分离出的test数据进行测试(分别使用无pca降维和有pca降维数据训练的模型)

from sklearn.metrics import mean_squared_error
grids.keys()
dict_keys(['LinearRegression', 'RandomForest', 'XGBoost'])
for i in grids.keys():print(i + ': ' + str(np.sqrt(mean_squared_error(grids[i].predict(X_test), y_test))))
LinearRegression: 1240663156.677283RandomForest: 0.1468371013683763XGBoost: 0.13519734581188902
grids_pca.keys()
dict_keys(['LinearRegression', 'RandomForest', 'XGBoost'])
for i in grids_pca.keys():print(i + ': ' + str(np.sqrt(mean_squared_error(grids_pca[i].predict(X_test_pca), y_test))))
LinearRegression: 0.1426615311522792RandomForest: 0.15286112373105223XGBoost: 0.14149572462432053
print(str(np.sqrt(mean_squared_error(grid_search_mlp.predict(X_test_scaled), y_test))))
0.1668391027224058
print(str(np.sqrt(mean_squared_error(grid_search_mlp_pca.predict(X_test_scaled_pca), y_test))))
0.1638504108133665

下一篇继续

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/8477.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Python实现机器遗忘算法】复现2020年顶会CVPR算法Selective Forgetting

【Python实现机器遗忘算法】复现2020年顶会CVPR算法Selective Forgetting 1 算法原理 Golatkar, A., Achille, A., & Soatto, S. (2020). Eternal sunshine of the spotless net: Selective forgetting in deep networks. In Proceedings of the IEEE/CVF Conference on Co…

Linux(NTP配置)

后面也会持续更新,学到新东西会在其中补充。 建议按顺序食用,欢迎批评或者交流! 缺什么东西欢迎评论!我都会及时修改的! NTP环境搭建 服务端客户端192.168.111.10192.168.111.11Linux MySQL5.7 3.10.0-1160.el7.x86_…

神经网络|(四)概率论基础知识-古典概型

【1】引言 前序学习了线性回归的基础知识,了解到最小二乘法可以做线性回归分析,但为何最小二乘法如此准确,这需要从概率论的角度给出依据。 因此从本文起,需要花一段时间来回顾概率论的基础知识。 【2】古典概型 古典概型是我…

21款炫酷烟花合集

系列专栏 《Python趣味编程》《C/C趣味编程》《HTML趣味编程》《Java趣味编程》 写在前面 Python、C/C、HTML、Java等4种语言实现18款炫酷烟花的代码。 Python Python烟花① 完整代码:Python动漫烟花(完整代码) ​ Python烟花② 完整…

新项目上传gitlab

Git global setup git config --global user.name “FUFANGYU” git config --global user.email “fyfucnic.cn” Create a new repository git clone gitgit.dev.arp.cn:casDs/sawrd.git cd sawrd touch README.md git add README.md git commit -m “add README” git push…

Brightness Controller-源码记录

Brightness Controller 亮度控制 一、概述二、ddcutil 与 xrandr1. ddcutil2. xrandr 三、部分代码解析1. icons2. ui3. utilinit.py 一、概述 项目:https://github.com/SunStorm2018/Brightness.git 原理:Brightness Controlle 是我在 Ubuntu 发现上调…

机器学习-K近邻算法

文章目录 一. 数据集介绍Iris plants dataset 二. 代码三. k值的选择 一. 数据集介绍 鸢尾花数据集 鸢尾花Iris Dataset数据集是机器学习领域经典数据集,鸢尾花数据集包含了150条鸢尾花信息,每50条取自三个鸢尾花中之一:Versicolour、Setosa…

Day27-【13003】短文,线性表两种基本实现方式空间效率、时间效率比较?兼顾优点的静态链表是什么?如何融入空闲单元链表来解决问题?

文章目录 本次内容总览第四节,两种基本实现方式概览两种基本实现方式的比较元素个数n大于多少时,使用顺序表存储的空间效率才会更高?时间效率比较?*、访问操作,也就是读运算,读操作1、插入,2、删…

JavaSE第十一天——集合框架Collection

一、List接口 List接口是一个有序的集合,允许元素有重复,它继承了Collection接口,提供了许多额外的功能,比如基于索引的插入、删除和访问元素等。 常见的List接口的实现类有ArrayList、LinkedList和Vector。 List接口的实现类 …

数据结构与算法学习笔记----求组合数

数据结构与算法学习笔记----求组合数 author: 明月清了个风 first publish time: 2025.1.27 ps⭐️一组求组合数的模版题,因为数据范围的不同要用不同的方法进行求解,涉及了很多之前的东西快速幂,逆元,质数,高精度等…

kaggle社区LLM Classification Finetuning

之前有个一样的比赛,没去参加,现在弄了一个无限期的比赛出来 训练代码链接:fine_tune | Kaggle 推理代码链接:https://www.kaggle.com/code/linheshen/inference-llama-3-8b?scriptVersionId219332972 包链接:pack…

【Python实现机器遗忘算法】复现2021年顶会 AAAI算法Amnesiac Unlearning

【Python实现机器遗忘算法】复现2021年顶会 AAAI算法Amnesiac Unlearning 1 算法原理 论文:Graves, L., Nagisetty, V., & Ganesh, V. (2021). Amnesiac machine learning. In Proceedings of the AAAI Conference on Artificial Intelligence, volume 35, 115…

51单片机开发:点阵屏显示数字

实验目标:在8x8的点阵屏上显示数字0。 点阵屏的原理图如下图所示,点阵屏的列接在P0端口,行接在74HC595扩展的DP端口上。 扩展口的使用详见:51单片机开发:IO扩展(串转并)实验-CSDN博客 要让点阵屏显示数字&#xff0…

买卖股票的最佳时机 II

hello 大家好!今天开写一个新章节,每一天一道算法题。让我们一起来学习算法思维吧! 问题分析 本题要求计算在可以多次买卖股票(但任何时候最多只能持有一股股票,也可以在同一天买卖)的情况下能获得的最大…

2024年度总结——理想的风,吹进现实

2024年悄然过去,留下了太多美好的回忆,不得不感慨一声时间过得真快啊!旧年风雪尽,新岁星河明。写下这篇博客,记录我独一无二的2024年。这一年,理想的风终于吹进现实! 如果用一句话总结这一年&am…

LosslessScaling-学习版[steam价值30元的游戏无损放大/补帧工具]

LosslessScaling 链接:https://pan.xunlei.com/s/VOHc-yZBgwBOoqtdZAv114ZTA1?pwdxiih# 解压后运行"A-绿化-解压后运行我.cmd"

CVE-2020-0796永恒之蓝2.0(漏洞复现)

目录 前言 产生原因 影响范围 漏洞复现 复现环境 复现步骤 防御措施 总结 前言 在网络安全的战场上,漏洞一直是攻防双方关注的焦点。CVE-2020-0796,这个被称为 “永恒之蓝 2.0” 的漏洞,一度引起了广泛的关注与担忧。它究竟是怎样的…

计算机网络 (61)移动IP

前言 移动IP(Mobile IP)是由Internet工程任务小组(Internet Engineering Task Force,IETF)提出的一个协议,旨在解决移动设备在不同网络间切换时的通信问题,确保移动设备可以在离开原有网络或子网…

node 爬虫开发内存处理 zp_stoken 作为案例分析

声明: 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 前言 主要说3种我们补环境过后如果用…

基于Python的哔哩哔哩综合热门数据分析系统的设计与实现

【Django】基于大数据的哔哩哔哩综合热门数据分析系统的设计与实现(完整系统源码开发笔记详细部署教程)✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 该系统涵盖登录、热门数据展示、数据分析及数据管理等功能。通过大数据处理与…