FastText调参:GridSearch+CV


本博客中使用到的完整代码请移步至: 我的github https://github.com/qingyujean/eda-for-text-classification,求赞求星求鼓励~~~

1. FastText之train_supervised参数说明

input_file         训练文件路径(必须)
model              skipgram或者CBOW default skipgram
lr                 学习率 default 0.1
dim                词向量维度 default 100
ws                 上下文窗口大小 default 5
epoch              epochs 数量 default 5
min_count          最低词频 default 1
minCountLabel      minimal number of label occurences default 0
minn               最小词长度 default 0
maxn               最大词长度 default 0
neg                负采样数目 default 5
wordNgrams         n-gram 设置 default 1
loss               损失函数 {ns,hs,softmax} default softmax
bucket             number of buckets [2000000]
thread             线程数 multiprocessing.cpu_count() - 1
lrUpdateRate       学习率更新速率 default 100
                   change the rate of updates for the learning rate
t                  sampling threshold [0.0001]
label              label prefix [’_label_’]
verbose            default  2
pretrainedVectors  指定使用已有的词向量 .vec 文件 default ""
                   pretrained word vectors (.vec file) for supervised learning

2. 参数选择实现:网格搜索+交叉验证

2.1 my_gridsearch_cv主方法

# 网格搜索+交叉验证
# 输入分别是训练数据帧,要搜索的参数,最佳score评价指标,交叉验证要做几折
def my_gridsearch_cv(df, param_grid, metrics, kfold=10):
    n_classes = len(np.unique(df[1]))
    print('n_classes', n_classes)

    kf = KFold(n_splits=kfold)  # k折交叉验证

    params_combination = get_gridsearch_params(param_grid) # 获取参数的各种排列组合

    best_score = 0.0
    best_params = dict()
    for params in params_combination:
        avg_score = get_KFold_scores(df, params, kf, metrics, n_classes)
        if avg_score > best_score:
            best_score = avg_score
            best_params = copy.deepcopy(params)

    return best_score, best_params

这里面主要使用到2个方法,一个是get_gridsearch_params,用于获取参数的各种排列组合,一个是get_KFold_scores,用于获取每组参数在交叉验证集上的score。

2.2 get_gridsearch_params

  • 将各个参数的取值进行排列组合
# 将各个参数的取值进行排列组合,例如tuned_parameters的示例中,会产生2*4*4*2=64种组合
def get_gridsearch_params(param_grid):
    params_combination = [dict()]  # 用于存放所有可能的参数组合
    for k, v_list in param_grid.items():
        tmp = [{k: v} for v in v_list]
        n = len(params_combination)
        # params_combination = params_combination*len(tmp)  # 浅拷贝,有问题
        copy_params = [copy.deepcopy(params_combination) for _ in range(len(tmp))] 
        params_combination = sum(copy_params, [])
        _ = [params_combination[i*n+k].update(tmp[i]) for k in range(n) for i in range(len(tmp))]
    return params_combination

例如当tuned_parameters为如下情况是:

tuned_parameters = {
    'lr': [0.1],
    'epoch': [15, 20, 25],
    'dim': [50, 100, 150],
    'wordNgrams': [2],
}

将各个参数的取值进行排列组合,例如在tuned_parameters的示例中,会产生1x3x3x1=9种组合,使用如下代码验证一下:

print(get_gridsearch_params(tuned_parameters))

返回:

[
	{'lr': 0.1, 'epoch': 15, 'dim': 50, 'wordNgrams': 2}, 
	{'lr': 0.1, 'epoch': 20, 'dim': 50, 'wordNgrams': 2}, 
	{'lr': 0.1, 'epoch': 25, 'dim': 50, 'wordNgrams': 2}, 
	{'lr': 0.1, 'epoch': 15, 'dim': 100, 'wordNgrams': 2}, 
	{'lr': 0.1, 'epoch': 20, 'dim': 100, 'wordNgrams': 2}, 
	{'lr': 0.1, 'epoch': 25, 'dim': 100, 'wordNgrams': 2}, 
	{'lr': 0.1, 'epoch': 15, 'dim': 150, 'wordNgrams': 2}, 
	{'lr': 0.1, 'epoch': 20, 'dim': 150, 'wordNgrams': 2}, 
	{'lr': 0.1, 'epoch': 25, 'dim': 150, 'wordNgrams': 2}
]

2.3 get_KFold_scores

  • 使用k折交叉验证,得到最后的score,保存最佳score以及其对应的那组参数
# 使用k折交叉验证,得到最后的score,保存最佳score以及其对应的那组参数
# 输入分别是训练数据帧,要搜索的参数,用于交叉验证的KFold对象,最佳score评价指标,几分类
def get_KFold_scores(df, params, kf, metric, n_classes):
    metric_score = 0.0

    for train_idx, val_idx in kf.split(df):
        df_train = df.iloc[train_idx]
        df_val = df.iloc[val_idx]

        tmpdir = tempfile.mkdtemp() #因为fasttext的训练时读入一个训练数据所在的目录或文件,所以这里用交叉验证集开一个临时目录/文件
        tmp_train_file = tmpdir + '/train.txt'
        df_train.to_csv(tmp_train_file, sep='\t', index=False, header=None, encoding='UTF-8')  # 不要表头

        fast_model = fasttext.train_supervised(tmp_train_file, label_prefix='__label__', thread=3, **params) #训练,传入参数
        
        #用训练好的模型做评估预测
        predicted = fast_model.predict(df_val[0].tolist())  # ([label...], [probs...])
        y_val_pred = [int(label[0][-1:]) for label in predicted[0]]  # label[0]  __label__0
        y_val = [int(cls[-1:]) for cls in df_val[1]]

        score = get_metrics(y_val, y_val_pred, n_classes)[metric]
        metric_score += score #累计在不同的训练集上的score,用于计算在整个交叉验证集上平均分
        shutil.rmtree(tmpdir, ignore_errors=True) #删除临时训练数据文件

    print('平均分:', metric_score / kf.n_splits)
    return metric_score / kf.n_splits

2.4 使用示例

import fasttext
from sklearn.model_selection import KFold, StratifiedKFold
import numpy as np
import pandas as pd
import copy
import tempfile
import shutil

from fast import get_metrics

DATA_PATH = '../data/'

# 要调试的参数
tuned_parameters = {
    'lr': [0.1, 0.05],
    'epoch': [15, 20, 25, 30],
    'dim': [50, 100, 150, 200],
    'wordNgrams': [2, 3],
}

# 这里引入上述3个方法

if __name__ == '__main__':
    filepath = DATA_PATH + 'fast/augmented/js_pd_tagged_train.txt'
    df = pd.read_csv(filepath, encoding='UTF-8', sep='\t', header=None, index_col=False, usecols=[0, 1])
    print(df.head())
    print(df.shape)  # (1480, 2)
    best_score, best_params = my_gridsearch_cv(df, tuned_parameters, 'accuracy', kfold=5)
    print('best_score', best_score)
    print('best_params', best_params)

3. 完整代码

完整代码请移步至: 我的github https://github.com/qingyujean/eda-for-text-classification,求赞求星求鼓励~~~

最后:如果本文中出现任何错误,请您一定要帮忙指正,感激~

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值