请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

使用逻辑回归时怎么利用网格搜索来查找degree,c等超参数

回答1 浏览3142 2018-06-03 17:18:02

老师,课上您说到如果在实际应用中逻辑回归的超参数是利用网格搜索来找的,我自己试了一下,下面是代码,您帮我看看哪里不对

#您课上举得例子
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(666)
X = np.random.normal(0, 1, size=(200, 2))
y = np.array((X[:,0]**2+X[:,1])<1.5, dtype='int')
for _ in range(20):
    y[np.random.randint(200)] = 1
#数据集分成训练数据集和测试数据集
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=666)
#使用逻辑回归
from sklearn.linear_model import LogisticRegression
log_reg = LogisticRegression()
log_reg.fit(X_train, y_train)
log_reg.score(X_test, y_test)
##########这里已经能够看到SCORE是多少##############
#这里是重点,我想使用网格搜索来查找多项式回归和逻辑回归的超参数
C_PARM = [0.1,0.2,0.3,0.4,0.5]
param_grid = [
    {
        'degree': [i for i in range(1, 11)], 
        'C': [i for i in C_PARM]
    }
]
from sklearn.model_selection import GridSearchCV
grid_search = GridSearchCV(log_reg, param_grid)
grid_search.fit(X_train,y_train)  
#这一步进行fit的时候已经报错,我觉得是因为逻辑回归没有degree这个超参数
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler

def PolynomialLogisticRegression(degree,C):
    return Pipeline([
        ('poly', PolynomialFeatures(degree=degree)),
        ('std_scaler', StandardScaler()),
        ('log_reg', LogisticRegression(C=C))
    ])
####老师,我最想表达的是怎么用网格搜索来搜索degree和C这两个超参数,让其跟后面的pipeline一起使用





添加回答

已采纳回答

非常好的问题。如何将自定义的Pipline对象应用于sklearn内置的网格搜索确实是课程没有讲的一个sklearn使用上的语法细节:)


首先,你在31行的注释分析的是正确的。由于此时,你在构建grid_search的时候,传入的算法是log_reg。而log_reg是LogisticRegression的对象,但是创建LogisticRegression是并不需要参数degree,所以,这里会报错。


正确的做法是,我们要对你创建的PolynomialLogisticRegression这个函数返回的对象进行网格搜索。这个函数的逻辑是返回了一个Pipeline的对象,这个Pipeline的对象中创建PolynomialFeatures时使用了degree这个参数。


为了方便起见,在这里,我为这个PolynomialLogisticRegression添加上了默认值。

def PolynomialLogisticRegression(degree = 1, C = 0.1):
    return Pipeline([
        ('poly', PolynomialFeatures(degree=degree)),
        ('std_scaler', StandardScaler()),
        ('log_reg', LogisticRegression(C=C))
    ])
    
poly_log_reg = PolynomialLogisticRegression()


我们需要针对poly_log_reg这个对象进行网格搜索:)


但是,在这里,poly_log_reg中包含三部分,每部分都有自己的参数。按照你写的param_grid,参数名称直接写degree和C,GridSearchCV是无法认得这些参数名隶属于哪一部分的。所以,在这种情况下,我们在设置param_grid的时候,参数名要显示地表明这个参数属于哪个部分。表示的方法是:

{$Pipeline中的对象名称}__{$参数名}

即,在Pipeline中的对象名称,加上双下换线(__),再加上参数名称。


所以,我们在网格搜索中,要搜索的两个参数名称应该是:

poly__degree
log_reg__C

其中的poly和log_reg,是你在实例化这个Pipeline对象的时候,给每一部分起的那个名称。


综上,此时我们的param_grid,要这样声明:

C_PARM = [0.1,0.2,0.3,0.4,0.5]
param_grid = [
    {
        'poly__degree': [i for i in range(1, 11)], 
        'log_reg__C': [i for i in C_PARM]
    }
]


现在,就可以按照以前一样的方法使用GridSearchCV啦:)

grid_search = GridSearchCV(poly_log_reg, param_grid)
grid_search.fit(X_train,y_train)


整理一遍,我们的整个代码就是这样的:

def PolynomialLogisticRegression(degree = 1,C = 0.1):
    return Pipeline([
        ('poly', PolynomialFeatures(degree=degree)),
        ('std_scaler', StandardScaler()),
        ('log_reg', LogisticRegression(C=C))
    ])

# 待进行网格搜索的算法    
poly_log_reg = PolynomialLogisticRegression()

# 准备待搜索的参数列表
C_PARM = [0.1,0.2,0.3,0.4,0.5]
param_grid = [
    {
        'poly__degree': [i for i in range(1, 11)], 
        'log_reg__C': [i for i in C_PARM]
    }
]

# 实例化GridSearchCV进行网格搜索
grid_search = GridSearchCV(poly_log_reg, param_grid)
grid_search.fit(X_train,y_train)


看起来写了很多,但是自己整理一遍,会发现其实这个语法非常简单:)


加油!

2018-06-04 06:54:23

购买课程后即可查看全部 1 条问答,立即购买

Python3入门机器学习 经典算法与应用 轻松入行人工智能

难度进阶
时长25小时
人数4564
好评度100%

Python3+sklearn,同时兼顾原理,算法底层实现和框架使用。零基础机器学习从此起步

讲师

liuyubobobo 全栈工程师

创业者,全栈工程师,持续学习者。对技术开发,产品设计、前后端,ios,html5,智能算法等领域均有接触;拥有多款独立App作品;对一切可编程的东西有浓厚兴趣,对游戏编程格外感兴趣。相信编程改变一切。

意见反馈 帮助中心 APP下载
官方微信