赞
踩
假设我现在有个简单的需求:
我有一批历史数据数据,每条数据有6个指标字段,这些数据作为训练数据输入,训练完成后,我可以根据一条数据的3个字段,生成另外3个字段的模拟数据
前前后后通过和gpt4的多次问答,最后完成这个简单的demo,demo使用的模型是随机森林(Random Forest)。
它回答的几近完美,但是很多在知识匮乏的情况下,它回答的很多内容其实对初学者来说太过深奥了(随便一个问题问到底都可能扯出一堆知识点),所以本文就只以初学者(有一定编程基础)的角度,简化了部分它回答的内容,无关的,跑题的,不需要了解太多的,我全部过滤掉了。
1、首先,确保你已经安装了scikit-learn
和pandas
库。如果没有安装,可以使用以下命令来安装:
pip install scikit-learn pandas
2、准备训练的数据,我自己准备了100多万数据
import pandas as pd from joblib import dump, load from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import mean_squared_error from sklearn.model_selection import train_test_split, GridSearchCV # 主函数 # 输入三个指标:watch_count,like_count,gift_user_count # 输出三个指标:watch_user_count,comment_count,comment_user_count def main(): model = get_model(True) # 使用模型生成数据 input_data = pd.DataFrame({ # 输入三个指标 'watch_count': [2152], 'like_count': [18230], 'gift_user_count': [14], }) simulated_data = simulate_data(model, input_data) print("Simulated Data:", simulated_data) # 创建数据集 def create_dataset(): # 自备数据,这里是通过spark输出的部分数据作为训练数据 df = pd.read_csv( '/Users/fangyirui/Documents/input/p1p2Data.csv/part-00000-adc31a3e-8ae2-4394-b10d-3e6055674306-c000.csv') return df # 根据训练好的模型进行数据模拟 def simulate_data(model, input_data): predicted = model.predict(input_data) return predicted # 获取训练模型,传入参数标识是否需要重新训练模型,ture为是,false为导入训练好的模型 def get_model(reset): if reset: # 创建数据集 df = create_dataset() # 选择条件特征和目标特征 # 输入的指标 condition_features = ['watch_count', 'like_count', 'gift_user_count'] # 输出的指标 target_features = ['watch_user_count', 'comment_count', 'comment_user_count'] # 分割数据集 X = df[condition_features] y = df[target_features] x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 优化模型参数,执行一次即可,我执行了两次,输出了两次最优的参数,直接填到下面的模型训练方法中 # {'max_depth': 10, 'min_samples_leaf': 1, 'min_samples_split': 2, 'n_estimators': 100} # {'max_depth': 10, 'min_samples_leaf': 1, 'min_samples_split': 3, 'n_estimators': 100} # model_optimize(x_train, y_train) # 创建模型 # 参数解释:verbose 0无日志输出,1输出tasks每个并行度的完成时间,2在1的基础上增加task的进度,3及以上跟2没有区别了 model = RandomForestRegressor(n_estimators=100, random_state=42, verbose=2, min_samples_leaf=1, min_samples_split=2, max_depth=10) # 应用数据训练模型 model.fit(x_train, y_train) # 保存模型到文件 dump(model, '/Users/fangyirui/Documents/input/trained_model_new.joblib') # 在测试集上评估模型 y_pred = model.predict(x_test) mse = mean_squared_error(y_test, y_pred) print(f"Mean Squared Error: {mse}") return model else: model = load('/Users/fangyirui/Documents/input/trained_model_new.joblib') return model # 模型超参数优化 def model_optimize(x_train, y_train): # 指定你要只用的模型 model = RandomForestRegressor(random_state=42) # 设置想要优化组合,比如n_estimators你设置了100和200,最后输出的结果为100,说明100比200要优,就可以再试试100和150这样 param_grid = { 'n_estimators': [100, 150], 'max_depth': [10, 15], 'min_samples_split': [2, 3], 'min_samples_leaf': [1, 2] } # 创建 GridSearchCV 对象 grid_search = GridSearchCV(estimator=model, param_grid=param_grid, cv=5, scoring='neg_mean_squared_error', verbose=2) # 执行网格搜索 grid_search.fit(x_train, y_train) # 查看结果 print(grid_search.best_params_) if __name__ == "__main__": main()
train_test_split
是 scikit-learn 库中的一个函数,用于将数据集划分为训练集和测试集。这在机器学习中是一个常见的步骤,因为你需要在一组数据上训练模型,并在另一组未见过的数据上评估模型的性能。
这行代码的意思是:
X
:包含特征数据的变量。在大多数情况下,这是一个二维数组或 DataFrame,其中每一行是一个样本,每一列是一个特征。y
:包含目标数据的变量。这通常是一个一维数组或 Series,长度与 X
的行数相同。test_size=0.2
:表示测试集应该包含原始数据集的 20%。相应地,剩下的 80% 将用作训练集。random_state=42
:是一个随机数种子,用于确保每次划分都是相同的。这样做的目的是为了可重复性,即每次运行代码时都会得到相同的训练集和测试集。函数的返回值是四个部分:X_train
, X_test
, y_train
, y_test
。
X_train
:用于训练模型的特征数据集部分。X_test
:用于测试模型的特征数据集部分。y_train
:与 X_train
对应的目标数据,用于训练模型。y_test
:与 X_test
对应的目标数据,用于评估模型。这行代码将整个数据集分成两组,一组用于建立(训练)模型,另一组用于测试模型的性能(测试)。这是确保模型泛化能力的标准做法。
“Mean Squared Error: 8723122.741238702” 表示模型在测试集上的表现的均方误差(Mean Squared Error,简称 MSE)是 8723122.741238702。均方误差是回归任务中常用的性能评估指标之一,它计算了模型预测值与实际值之间差异的平方的平均值。
具体来说,MSE 的计算公式如下:
[ \text{MSE} = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2 ]
其中:
MSE 的值越小,表示模型的预测值与实际值越接近,模型的性能越好。一个较大的 MSE 值(如例子中的 8723122.741238702)通常表示模型预测的误差较大,可能需要进一步调整模型参数、改进模型结构,或者重新审视数据的预处理和特征工程步骤。
在实际应用中,MSE 的绝对值可能难以直观理解,因为它依赖于数据的规模和范围。因此,除了查看 MSE 的值,也常常会查看均方根误差(Root Mean Squared Error, RMSE)或者与目标变量范围相关的标准化指标,如 R-squared(决定系数)来评估模型性能。
调整随机森林模型的超参数是一个重要的过程,可以显著影响模型的性能。以下是随机森林中一些关键超参数以及它们如何影响模型表现:
调整超参数通常需要使用交叉验证,并且基于评估指标(如均方误差、精确度、F1 分数等)进行迭代试验以找到最佳组合。下面介绍两种常见方法:
网格搜索是一种通过遍历给定参数网格中所有可能组合来寻找最优超参数设置方法。
pythonfrom sklearn.model_selection import GridSearchCV # 设置想要优化组合 param_grid = { 'n_estimators': [100, 200], 'max_depth': [None, 10, 20], 'min_samples_split': [2, 5], 'min_samples_leaf': [1, 2] } # 创建随机森林对象 rf = RandomForestRegressor(random_state=42) # 创建 GridSearchCV 对象 grid_search = GridSearchCV(estimator=rf, param_grid=param_grid, cv=5, scoring='neg_mean_squared_error', verbose=2) # 执行网格搜索 grid_search.fit(X_train, y_train) # 查看结果 print(grid_search.best_params_)
与网格搜索遍历所有可能组合不同,随机搜索从指定范围内随机选取超参数组合进行尝试。
pythonfrom sklearn.model_selection import RandomizedSearchCV # 设置想要优化范围 param_distributions = { 'n_estimators': range(100, 500), 'max_depth': [None] + list(range(5, 25)), # 其他可调整参数... } # 创建 RandomizedSearchCV 对象 random_search = RandomizedSearchCV(estimator=rf, param_distributions=param_distributions, n_iter=10, cv=5, scoring='neg_mean_squared_error', verbose=2) random_search.fit(X_train, y_train) print(random_search.best_params_)
请注意,在实际应用中你需要选择适当范围和步长,并且可能需要运行多次以获得较好结果。此外,在执行这些操作之前,请确保你已经对数据进行了充分预处理,并选择了正确评估指标反映你希望解决问题类型(例如分类或回归)。
不一定。在这个上下文中,rf = RandomForestRegressor(random_state=42)
创建了一个新的随机森林回归器实例,用于网格搜索过程中寻找最佳超参数组合。这里的 rf
是未经训练的模型。
如果你已经有一个训练好的模型,并且只是想要调整它的超参数来看是否可以进一步提高性能,那么你可以使用该模型作为起点进行网格搜索。但通常情况下,在进行网格搜索时,我们从未训练过的模型开始,因为我们希望每个超参数组合都在同等条件下被评估。
在使用 GridSearchCV
或 RandomizedSearchCV
进行超参数优化时,默认情况下会对每种超参数组合创建新的模型实例,并用交叉验证数据集进行独立训练和评估。所以即使你之前有一个已经训练好了的随机森林模型,在执行网格搜索时也不会直接使用它。
总结来说:
GridSearchCV
或 RandomizedSearchCV
作为基础来开始搜索。但请记住,在这种情况下,传递给这些函数类对象将仅仅利用其初始设置而非其学习到任何数据后得到状态(因为交叉验证需要从头开始重新学习)。Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。