模型的超参数优化

科技   2024-10-08 13:36   广东  

 今天是生信星球陪你的第1002天


   

公众号里的文章大多数需要编程基础,如果因为代码看不懂,而跟不上正文的节奏,可以来找我学习,相当于给自己一个新手保护期。我的课程都是循环开课,点进去咨询微信↓

生信分析直播课程(每月初开一期,春节休一个月)

生信新手保护学习小组(每月两期)

单细胞陪伴学习小组(每月两期)

前面已经提到过的超参数有:

  • 岭回归和lasso回归的α
  • KNN的n_neighbors

超参数是在拟合模型之前指定的参数。它们对模型的表现影响很大,所以我们希望选到好的参数。

1 选择正确的超参数的步骤

(1)尝试多个不同的超参数值

(2)用这些超参数分别拟合

(3)看它们拟合的模型的表现

(4)选择表现最佳的值

这个过程称之为超参数优化

  • 必须使用交叉验证,来避免对测试集的过拟合
  • 仍然可以拆分数据,并在训练集上执行交叉验证
  • 保留测试集用于最终评估

2 准备数据

import pandas as pd 
diabetes_df = pd.read_csv("diabetes_clean.csv"
print(diabetes_df.head())
cols_to_check = diabetes_df.iloc[:, [1,5]]
# 检查这些列中任意一列是否包含0
rows_to_drop = cols_to_check.eq(0).any(axis=1)
# 删除这些行
diabetes_df = diabetes_df[~rows_to_drop]
diabetes_df.shape
X = diabetes_df.drop("glucose", axis=1).values 
y = diabetes_df["glucose"].values  
print(X.shape, y.shape) 
## (752, 8) (752,)
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3,
random_state=42)

3 网格搜索交叉验证

就是把自己选择的参数值组合一下,看评分最高的参数组合是哪个。

import numpy as np
from sklearn.model_selection import GridSearchCV , KFold 
from sklearn.linear_model import Ridge
kf = KFold(n_splits=5, shuffle=True, random_state=42)
param_grid = {"alpha": np.arange(0.000110.001),
              "solver": ["sag""lsqr"]}
ridge = Ridge(max_iter=7000#增加迭代次数,让模型更好的收敛
ridge_cv = GridSearchCV(ridge, param_grid, cv=kf)
ridge_cv.fit(X_train, y_train)
print(ridge_cv.best_params_, ridge_cv.best_score_)
{'alpha': 0.0001, 'solver': 'lsqr'} 0.3049792393495717

param_grid里面是要选择的参数,包括了alpha

这个是回归模型,所以score计算的分数是R方

test_score = ridge_cv.score(X_test, y_test)
print(test_score)
0.35521220840875667

网格搜索交叉验证有明显的局限性:

3折交叉验证,1个超参数,每个超参数有10个值,就要执行30次拟合

10折交叉验证,3个超参数,每个超参数有10个值,就要执行900次拟合

课程里老师说是900次,但我的理解是101010*10是一万次拟合。。。

计算量太大,可以用随机搜索交叉验证代替。

4 随机搜索交叉验证

from sklearn.model_selection import RandomizedSearchCV
kf = KFold(n_splits=5, shuffle=True, random_state=42)
param_grid = {'alpha': np.arange(0.000110.001),
              "solver": ['sag''lsqr']}
ridge = Ridge(max_iter=7000#增加迭代次数,让模型更好的收敛
ridge_cv = RandomizedSearchCV(ridge, param_grid, cv=kf, n_iter=2)
ridge_cv.fit(X_train, y_train)
print(ridge_cv.best_params_, ridge_cv.best_score_)
{'solver': 'lsqr', 'alpha': 0.0001} 0.3049792393495717

在代码上,只是换一个函数,但他的计算量会少很多,而且可能计算出比网格搜索交叉验证更好的参数组合。

n_iter参数是计算多少个“参数组合”,默认值是10,老师设置个2可能只是为了演示,实战里2太少了。而且课程给的代码里是 np.arange(0.0001, 1, 10),这个代码是错的,只能产生一个0.0001啊。。。可能是代码太老了吧。


生信星球
一个零基础学生信的平台-- 原创结构化图文/教程,精选阶段性资料,带你少走弯路早入门,收获成就感,早成生信小能手~
 最新文章