如何在(GridSearchCV)拟合模型后打印估计系数?(SGDRegressor)

14 投票
3 回答
27457 浏览
提问于 2025-04-18 10:50

我刚接触scikit-learn,它的表现让我很满意。不过,现在让我烦恼的是,我不知道怎么打印出(或者更好的是,写入一个小文本文件)它估算的所有系数和选择的所有特征。请问该怎么做呢?

对于SGDClassifier也是这样,我觉得所有可以进行拟合的基本对象,不管有没有交叉验证,都是一样的。下面是完整的代码。

import scipy as sp
import numpy as np
import pandas as pd
import multiprocessing as mp
from sklearn import grid_search
from sklearn import cross_validation
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import SGDClassifier


def main():
    print("Started.")
    # n = 10**6
    # notreatadapter = iopro.text_adapter('S:/data/controls/notreat.csv', parser='csv')
    # X = notreatadapter[1:][0:n]
    # y = notreatadapter[0][0:n]
    notreatdata = pd.read_stata('S:/data/controls/notreat.dta')
    notreatdata = notreatdata.iloc[:10000,:]
    X = notreatdata.iloc[:,1:]
    y = notreatdata.iloc[:,0]
    n = y.shape[0]

    print("Data lodaded.")
    X_train, X_test, y_train, y_test = cross_validation.train_test_split(X, y, test_size=0.4, random_state=0)

    print("Data split.")
    scaler = StandardScaler()
    scaler.fit(X_train)  # Don't cheat - fit only on training data
    X_train = scaler.transform(X_train)
    X_test = scaler.transform(X_test)  # apply same transformation to test data

    print("Data scaled.")
    # build a model
    model = SGDClassifier(penalty='elasticnet',n_iter = np.ceil(10**6 / n),shuffle=True)
    #model.fit(X,y)

    print("CV starts.")
    # run grid search
    param_grid = [{'alpha' : 10.0**-np.arange(1,7),'l1_ratio':[.05, .15, .5, .7, .9, .95, .99, 1]}]
    gs = grid_search.GridSearchCV(model,param_grid,n_jobs=8,verbose=1)
    gs.fit(X_train, y_train)

    print("Scores for alphas:")
    print(gs.grid_scores_)
    print("Best estimator:")
    print(gs.best_estimator_)
    print("Best score:")
    print(gs.best_score_)
    print("Best parameters:")
    print(gs.best_params_)


if __name__=='__main__':
    mp.freeze_support()
    main()

3 个回答

1

我觉得你可能是在寻找“最佳”模型的估计参数,而不是通过网格搜索得到的超参数。你可以把网格搜索中找到的最佳超参数(在你的情况下是'alpha'和'l1_ratio')放回模型(在你的情况下是'SGDClassifier')中,再进行一次训练。然后你就可以从训练好的模型对象中找到参数。

代码可能是这样的:

model2 = SGDClassifier(penalty='elasticnet',n_iter = np.ceil(10**6 / n),shuffle=True, alpha = gs.best_params_['alpha'], l1_ratio=gs.best_params_['l1_ratio'])
print(model2.coef_)
3
  • 从一个估计器(就是用来做预测的模型)中,你可以通过 coef_ 属性来获取系数。
  • 从一个管道(就是把多个步骤串联起来的流程)中,你可以通过 named_steps 属性来获取模型,然后再用 coef_ 来获取系数。
  • 从网格搜索(就是找出最佳模型的过程)中,你可以通过 best_estimator_ 来获取最佳模型,然后再用 named_steps 来获取管道,最后再用 coef_ 来获取系数。

示例:

from sklearn.svm import LinearSVC
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.model_selection import GridSearchCV

pipe = Pipeline([
    ("scale", StandardScaler()),
    ("model", LinearSVC())
])

# from pipe:
pipe.fit(X, y);
coefs = pipe.named_steps.model.coef_

# from gridsearch:
gs_svc_model = GridSearchCV(estimator=pipe,
                    param_grid={
                      'model__C': [.01, .1, 10, 100, 1000],
                    },
                    cv=5,
                    n_jobs = -1)
gs_svc_model.fit(X, y);
coefs = gs_svc_model.best_estimator_.named_steps.model.coef_
21

用最好的超参数训练出来的 SGDClassifier 实例被保存在 gs.best_estimator_ 里。coef_intercept_ 是这个最佳模型的参数。

撰写回答