Sklearn-metric评估
sklearn.metrics.make_scorer
从性能指标或损失函数中创建一个记分标准。
这个函数封装了用于GridSearchCV和cross_val_score的评分函数,它接受一个评分函数,如accuracy_score、mean_squared_error、adjusted_rand_index或average_precision,并返回一个可调用的值,该值对学习器的输出进行评分。
它的使用形式如下:
sklearn.metrics.make_scorer(score_func, greater_is_better=True, needs_proba=False, needs_threshold=False, **kwargs)
其参数如下:
needs_threshold:
score_func是否具有连续的决策确定性。这只适用于使用具有decision_function或predict_proba方法的分类器的二元分类。如果为真,对于二进制y_true, score函数应该接受一维的y_pred(即,正类或决策函数的概率)。例如**,平均精度或roc曲线下的面积不能使用离散预测来计算**:
该函数返回的是一个可调用的记分对象:
model = LGBMRegressor(max_depth=5,num_leaves=10,objective="regression")
score_ = cross_val_score(model,X = X_train,y=Y_train,verbose=0,scoring=make_scorer(mean_squared_error))
print(score_)
分类评估准则
accuracy_score
sklearn.metrics.accuracy_score(y_true, y_pred, *, normalize=True, sample_weight=None)
- 分类准确性分数
- 在多分类中,该函数计算子集准确性:一个样本中预测的标签集必须与y中对应的标签集完全匹配。
参数
- y_true:1维 array,label indicator array(标签指示数组),sparse matrix(稀疏矩阵)
- y_pred:与上一样
- y_true就是y_test,y_pred就是你的模型根据x_test预测出的结果
normalize:bool,默认为True - True时返回准确率,False为准确的个数
- sample_weight:array-like of shape(n_samples),默认为None
设置某些权重
note - 在二分类和多分类中,这个方法相当于jaccard_score方法
>>> from sklearn.metrics import accuracy_score
>>> y_pred = [0, 2, 1, 3]
>>> y_true = [0, 1, 2, 3]
>>> accuracy_score(y_true, y_pred)
0.5
>>> accuracy_score(y_true, y_pred, normalize=False)
2
AUC
- sklearn.metrics.auc(x, y)
使用梯形法则计算AUC
>>> import numpy as np
>>> from sklearn import metrics
>>> y = np.array([1, 1, 2, 2])
>>> pred = np.array([0.1, 0.4, 0.35, 0.8])
>>> fpr, tpr, thresholds = metrics.roc_curve(y, pred, pos_label=2)
>>> metrics.auc(fpr, tpr)
0.75
classification_report
sklearn.metrics.classification_report(y_true, y_pred, *, labels=None, target_names=None, sample_weight=None, digits=2, output_dict=False, zero_division=‘warn’)
构建文本报告,显示主要的分类数量。
参数
y_true,y_pred:这两个参数不再赘述
labels:array,shape = [n_labels]
sample_weight:array,其shape为n_samples,default = None
不为None时,表示设置sample的权重
digits:int
只有out_dict为False时才有效,设置输出值的小数点位数
out_dict:bool,default=False
若是True,将输出转为字典类型
zero_division:‘warn’,0 or 1,默认为’warn’
设置值的返回。
回归评估准则:Regression metrics
mean_absolute_error
- sklearn.metrics.mean_absolute_error(y_true, y_pred, *, sample_weight=None, multioutput=‘uniform_average’)
>>> y_true = [[0.5, 1], [-1, 1], [7, -6]]
>>> y_pred = [[0, 2], [-1, 2], [8, -5]]
>>> mean_absolute_error(y_true, y_pred)
0.75
#等价于以下
>>>y_true,y_pred = np.array(y_true),np.array(y_pred)
>>>np.sum(np.absolute(y_true-y_pred))/len(y_true)
pipeline.Pipeline
Python的sklearn.pipeline.Pipeline()函数可以把多个“处理数据的节点”按顺序打包在一起,数据在前一个节点处理之后的结果,转到下一个节点处理。除了最后一个节点外,其他节点都必须实现’fit()'和’transform()'方法**, 最后一个节点需要实现fit()方法即可。当训练样本数据送进Pipeline进行处理时, 它会逐个调用节点的fit()和transform()方法**,然后点用最后一个节点的fit()方法来拟合数据。
Pipeline可用于将多个估计器链接为一个。这很有用,因为在处理数据时通常会有固定的步骤顺序,例如特征选择,归一化和分类。Pipeline在这里有多种用途:
方便和封装:只需调用一次fit并在数据上进行一次predict即可拟合整个估计器序列。
联合参数选择:可以一次对Pipeline中所有估计器的参数进行网格搜索(grid search )。
安全性:通过确保使用相同的样本来训练转换器和预测器,Pipeline有助于避免在交叉验证中将测试数据的统计信息泄漏到经过训练的模型中。
Pipeline的使用
Pipeline是使用 (key,value) 对的列表构建的,其中key是包含要提供此步骤名称的字符串,而value是一个估计器对象:
from sklearn.pipeline import Pipeline
from sklearn.svm import SVC
from sklearn.decomposition import PCA
estimators = [(‘reduce_dim’, PCA()), (‘clf’, SVC())]
pipe = Pipeline(estimators)
pipe
`
输出结果`
GridSearchCV
GridSearchCV,它存在的意义就是自动调参,只要把参数输进去,就能给出最优化的结果和参数。但是这个方法适合于小数据集,一旦数据的量级上去了,很难得出结果。这个时候就是需要动脑筋了。数据量比较大的时候可以使用一个快速调优的方法——坐标下降。它其实是一种贪心算法:拿当前对模型影响最大的参数调优,直到最优化;再拿下一个影响最大的参数调优,如此下去**,直到所有的参数调整完毕**。这个方法的缺点就是可能会调到局部最优而不是全局最优,但是省时间省力,巨大的优势面前,还是试一试吧,后续可以再拿bagging再优化。
通常算法不够好,需要调试参数时必不可少。比如SVM的惩罚因子C,核函数kernel,gamma参数等,对于不同的数据使用不同的参数,结果效果可能差1-5个点,sklearn为我们提供专门调试参数的函数grid_search。
参数解释
GridSearchCV(estimator, param_grid, scoring=None, fit_params=None, n_jobs=1, iid=True, refit=True, cv=None, verbose=0, pre_dispatch=‘2*n_jobs’, error_score=‘raise’, return_train_score=True)
-
estimator:所使用的分类器,或者pipeline
-
param_grid:值为字典或者列表,即需要最优化的参数的取值
-
scoring:准确度评价标准,默认None,这时需要使用score函数;或者如scoring=‘roc_auc’,根据所选模型不同,评价准则不同。字符串(函数名),或是可调用对象,需要其函数签名形如:scorer(estimator, X, y);如果是None,则使用estimator的误差估计函数。scoring 参数可以设置为什么可以参考这篇博文:https://blog.csdn.net/qq_41076797/article/details/102755893
-
n_jobs:并行数,int:个数,-1:跟CPU核数一致, 1:默认值。
-
pre_dispatch:指定总共分发的并行任务数。当n_jobs大于1时,数据将在每个运行点进行复制,这可能导致OOM,而设置pre_dispatch参数,则可以预先划分总共的job数量,使数据最多被复制pre_dispatch次
-
iid:默认True,为True时,默认为各个样本fold概率分布一致,误差估计为所有样本之和,而非各个fold的平均。
-
cv:交叉验证参数,默认None,使用三折交叉验证。指定fold数量,默认为3,也可以是yield训练/测试数据的生成器。
-
refit:默认为True,程序将会以交叉验证训练集得到的最佳参数,重新对所有可用的训练集与开发集进行,作为最终用于性能评估的最佳模型参数。即在搜索参数结束后,用最佳参数结果再次fit一遍全部数据集。
-
verbose:日志冗长度,int:冗长度,0:不输出训练过程,1:偶尔输出,>1:对每个子模型都输出。
-
Attributes:
-
best_estimator_:效果最好的分类器
-
best_score_:成员提供优化过程期间观察到的最好的评分
-
best_params_:描述了已取得最佳结果的参数的组合
-
best_index_:对应于最佳候选参数设置的索引(cv_results_数组的索引)。
Methods:
-
decision_function:使用找到的参数最好的分类器调用decision_function。
-
fit(X, y=None, groups=None, **fit_params):训练
-
get_params(deep=True):获取这个估计器的参数。
-
predict(X):用找到的最佳参数调用预估器。(直接预测每个样本属于哪一个类别)
-
predict_log_proda(X):用找到的最佳参数调用预估器。(得到每个测试集样本在每一个类别的得分取log情况)
-
predict_proba(X):用找到的最佳参数调用预估器。(得到每个测试集样本在每一个类别的得分情况)
-
score(X, y=None):返回给定数据上的得分,如果预估器已经选出最优的分类器。
-
transform(X):调用最优分类器进行对X的转换
gensim.models.Word2Vec
word2vec
Word2vec是一个用来产生词向量的模型。是一个将单词转换成向量形式的工具。 通过转换,可以把对文本内容的处理简化为向量空间中的向量运算,计算出向量空间上的相似度,来表示文本语义上的相似度。(向量空间上的相似度)
词向量
Word2vec 是 Word Embedding 的方法之一,中文名“词向量”,作用就是将自然语言中的文本转为计算机可以理解的稠密向量。在Word2vec出现之前**,自然语言处理经常把字词转为离散的单独的符号**,也就是One-Hot Encoder。
gensim.models.word2vec.Word2Vec(sentences=None, corpus_file=None, size=100, alpha=0.025, window=5, min_count=5,
max_vocab_size=None, sample=0.001, seed=1, workers=3, min_alpha=0.0001, sg=0, hs=0, negative=5,
ns_exponent=0.75, cbow_mean=1, hashfxn=, iter=5, null_word=0, trim_rule=None,
sorted_vocab=1, batch_words=10000, compute_loss=False, callbacks=(), max_final_vocab=None)
参数介绍
- sentences (iterable of iterables, optional):供训练的句子,可以使用简单的列表。
- corpus_file (str, optional):LineSentence格式的语料库文件路径。
- size (int, optional):word向量的维度。
- window (int, optional): 一个句子中当前单词和被预测单词的最大距离。
- min_count (int, optional) : 忽略词频小于此值的单词。
- workers (int, optional): 训练模型时使用的线程数。
- sg ({0, 1}, optional): **模型的训练算法: 1: skip-gram; 0: CBOW.
- hs ({0, 1}, optional): 1: 采用hierarchical softmax训练模型**; 0: 使用负采样。
- negative (int, optional): 0: 使用负采样,设置多个负采样(通常在5-20之间)。
- ns_exponent (float, optional): 负采样分布指数。1.0样本值与频率成正比,0.0样本所有单词均等,负值更多地采样低频词。
- cbow_mean ({0, 1}, optional): 0: 使用上下文单词向量的总和; 1: 使用均值**,适用于使用CBOW**。
- alpha (float, optional): 初始学习率。
- min_alpha (float, optional): 随着训练的进行**,学习率线性下降到min_alpha。**
- seed (int, optional): 随机数发生器种子。
- max_vocab_size (int, optional): 词汇构建期间RAM的限制; 如果有更多的独特单词,则修剪不常见的单词。 每1000万个类型的字需要大约1GB的RAM。
- max_final_vocab (int, optional): 自动选择匹配的min_count将词汇限制为目标词汇大小。
- sample (float, optional):高频词随机下采样的配置阈值,范围是(0,1e-5)。
- hashfxn (function, optional): 哈希函数用于随机初始化权重,以提高训练的可重复性。
- iter (int, optional): 迭代次数。
- trim_rule (function, optional): 词汇修剪规则,指定某些词语是否应保留在词汇表中,修剪掉或使用默认值处理。
- sorted_vocab ({0, 1}, optional):如果为1,则在分配单词索引前按降序对词汇表进行排序。
- batch_words (int, optional): 每一个batch传递给线程单词的数量。
- compute_loss (bool, optional):如果为True,则计算并存储可使用* get_latest_training_loss()检索的损失值。
- callbacks (iterable of CallbackAny2Vec, optional): 在训练中特定阶段执行回调序列。
深度学习
np_utils.to_categorical
用于分类,将标签转换为one-hot编码。
参数
- np_utils.to_categorical(y, num_classes)
- y:向量(数据的label),函数作用后,返回对应矩阵形式(从0到num_classes的整数)。
若num_classes=3,则y应为[0,1,2]
-
num_classes:种类的总数。如果是’ None ',则自动推断作为(y中最大的数)+ 1。
-
dtype:数据类型。默认值:“float32”。
Batch Normalization(批归一化操作)
前言
批归一化简称BN,是由Google于2015年提出,这是一个深度神经网络训练的技巧,它不仅可以加快了模型的收敛速度,而且更重要的是在一定程度缓解了深层网络中“梯度弥散(特征分布较散)”的问题,从而使得训练深层网络模型更加容易和稳定。所以目前BN已经成为几乎所有卷积神经网络的标配技巧了。
从字面意思看来Batch Normalization(简称BN)就是对每一批数据进行归一化,确实如此,对于训练中某一个batch的数据{x1,x2,…,xn},注意这个数据是可以输入也可以是网络中间的某一层输出。在BN出现之前,我们的归一化操作一般都在数据输入层,对输入的数据进行求均值以及求方差做归一化,但是BN的出现打破了这一个规定,我们可以在网络中任意一层进行归一化处理,因为我们现在所用的优化方法大多都是min-batch SGD,所以我们的归一化操作就成为Batch Normalization。
数据归一化
什么是数据归一化?数据归一化处理是数据挖掘的一项基础工作,不同评价指标往往具有不同的量纲和量纲单位,这样的情况会影响到数据分析的结果,为了消除指标之间的量纲影响,需要进行数据标准化处理,以解决数据指标之间的可比性。原始数据经过数据标准化处理后,各指标处于同一数量级,适合进行综合对比评价。数据归一化一般有两种方法。
1.[0,1]归一化,使结果值映射到[0 ,1]之间。
.正态分布归一化,这种方法给予原始数据的均值(mean)和标准差(standard deviation)进行数据的标准化。经过处理的数据符合标准正态分布,即均值为0,标准差为1
BN解决的问题
我们知道网络一旦训练起来,那么参数就要发生更新,除了输入层的数据外(因为输入层数据,我们已经人为的为每个样本归一化),后面网络每一层的输入数据分布是一直在发生变化的,因为在训练的时候,前面层训练参数的更新将导致后面层输入数据分布的变化。以网络第二层为例:网络的第二层输入,是由第一层的参数和input计算得到的,而第一层的参数在整个训练过程中一直在变化,因此必然会引起后面每一层输入数据分布的改变。(你可以理解为连锁反应)我们把在训练过程中**,网络中间层数据分布的改变称之为:“Internal Covariate Shift”**。BN的提出,就是要解决在训练过程中,中间层数据分布发生改变的情况,即Internal Covariate Shift问题。
BN如何做的数据归一化?
我们知道在神经网络训练时,数据归一化都是在数据输入时做的,但是实际上在任何位置都是可以进行数据归一化,而且在神经网络里上一层网络的输出不就是下一层网络的输入吗。
BN中的数据归一化是在正态分布式的归一化的基础上进行的修改,步骤如下:
如上图所示,BN步骤主要分为4步:
1.求每一个训练批次数据的均值
2**.求每一个训练批次数据的方差**
3.使用求得的均值和方差对该批次的训练数据做归一化,获得(0,1)正态分布。其中ε是为了避免除数为0时所使用的微小正数。
4.尺度变换和偏移:将xi乘以γ调整数值大小,再加上β增加偏移后得到yi,这里的γ是尺度因子,β是平移因子。这一步是BN的精髓,由于归一化后的xi基本会被限制在正态分布下,使得网络的表达能力下降。为解决该问题,我们引入两个新的参数:γ,β。 γ和β是在训练时网络自己学习得到的。
换句话说正态分布式的数据归一化变成了下面的形式来进行数据归一化,
BN的本质
一个标准的归一化步骤就是减均值除方差,那这种归一化操作有什么作用呢?我们观察下图:
a中左图是没有经过任何处理的输入数据,曲线是sigmoid函数,如果数据在梯度很小的区域,那么学习率就会很慢甚至陷入长时间的停滞。减均值除方差后,数据就被移到中心区域如右图所示,对于大多数激活函数而言,这个区域的梯度都是最大的或者是有梯度的(比如ReLU),这可以看做是一种对抗梯度消失的有效手段。对于一层如此,如果对于每一层数据都那么做的话,数据的分布总是在随着变化敏感的区域,相当于不用考虑数据分布变化了,这样训练起来更有效率。换句话说,就是把数据从梯度较小的区域移到了梯度较大区域,这样的话模型收敛速度就快了,这就是sigmoid激活函数被ReLU激活函数普遍替代的原因。
那么为什么要有尺度变换和偏移,不是仅使用减均值除方差操作就能获得目的效果吗?我们思考一个问题,减均值除方差得到的分布是正态分布,我们能否认为正态分布就是最好或最能体现我们训练样本的特征分布呢?不能,比如数据本身就很不对称,或者激活函数未必是对方差为1的数据最好的效果,比如Sigmoid激活函数,在-1~1之间的梯度变化不大,那么非线性变换的作用就不能很好的体现,换言之就是**,减均值除方差操作后可能会削弱网络的性能!针对该情况**,加入尺度变换和偏移才能完成真正的batch normalization。
BN的本质就是利用优化变一下方差大小和均值位置,使得新的分布更切合数据的真实分布,保证模型的非线性表达能力。BN的极端的情况就是这两个参数等于mini-batch的均值和方差,那么经过batch normalization之后的数据和输入完全一样,当然一般的情况是不同的。
在训练时,我们会对同一批的数据的均值和方差进行求解,进而进行归一化操作。但是对于预测时我们的均值和方差怎么求呢?比如我们预测单个样本时,那还怎么求均值和方法呀!其实是这种样子的,对于预测阶段时所使用的均值和方差,其实也是来源于训练集。比如我们在模型训练时我们就记录下每个batch下的均值和方差,待训练完毕后,我们求整个训练样本的均值和方差期望值,作为我们进行预测时进行BN的的均值和方差
关于BN的使用位置,在CNN中一般应作用与非线性激活函数之前,s型函数s(x)的自变量x是经过BN处理后的结果。因此前向传导的计算公式就应该是:
其实因为偏置参数b经过BN层后其实是没有用的,最后也会被均值归一化,当然BN层后面还有个β参数作为偏置项,所以b这个参数就可以不用了。因此最后把BN层+激活函数层就变成了:
text.Tokenizer
函数原型
tf.keras.preprocessing.text.Tokenizer(
num_words=None,
filters=‘!"#$%&()*+,-./:;<=>?@[\]^_`{|}~\t\n’,
lower=True,
split=’ ',
char_level=False,
oov_token=None,
document_count=0,
**kwargs
)
函数说明
Tokenizer函数用于创建一个分词器对象tokenizer。参数num_words用于表示应该保持的最大的单词数,如果小于输入数据所构成词汇表的不同的单词数,则一部分单词会被删掉。默认值为None,表示应该保持的单词数和词汇表的一致。
参数filters表示应该被过滤的单词或者字符。参数lower表示输入的大写字母是否应该转换成小写字母,默认为True。参数split表示用于分词的分隔符,默认情况下,文本变成以空格分隔的单词序列(单词可能包括 ’ 字符)。
参数char_level表示是对**一个单词进行分割还是对一个字符进行分割,**默认为True,表示对一个字符进行分割。
参数oov_token如果给定,它将被添加到 word_index 并用于在 text_to_sequence 调用期间替换词汇表外的单词。
tokenizer对象具有以下常用属性和方法:
1、fit_on_texts(texts):根据文本来更新内部词汇表,如果texts为一个字符串,那么结果都将按照字符划分;如果texts为一个字符串列表,比如[“hello world”]、[“hello”, “world”],则如果设置char_level=False,分词器按照单词划分。
2、get_config():**获取分词器的配置,**里面有word_index、index_word、word_docs、index_docs、document_count、word_counts等常用的信息。
3、sequences_to_texts(sequences):将数字序列转换成文本,形式为[[4], [3], [2], [2]]或者[[4, 3, 2, 2]]的列表或者numpy数组。
4、texts_to_sequences(texts):将文本转换成数字序列。
5、word_index:一个将文本映射为数字的字典
6、index_word:一个将数字映射为文本的字典
# 使用 keras tokenizer
token = text.Tokenizer(num_words=None)
max_len = 70
token.fit_on_texts(list(xtrain) + list(xvalid))
xtrain_seq = token.texts_to_sequences(xtrain)
xvalid_seq = token.texts_to_sequences(xvalid)
#对文本序列进行zero填充
xtrain_pad = sequence.pad_sequences(xtrain_seq, maxlen=max_len)
xvalid_pad = sequence.pad_sequences(xvalid_seq, maxlen=max_len)
word_index = token.word_index
总结
整理代码基本上整理到这里了,慢慢地将各种代码都跑通,各种代码以及模型全部将其搞定,慢慢的学会训练以及生成任何形式的代码以及生成策略,全部将其搞定都行啦的理由与打算,
开始找相关论文,进行复现, 并测试自己评估指标,学会自己调参,建立自己的评价体系,全部将其搞定都行啦的样子与打算。
学习心得
会自己在建模的时候,进行各种归一化操作。
感觉用keras进行深度学习建模,管道用着比较爽。全部将其搞定都行啦的样子啦的回事。
会自己照搬代码,然后自己进行打比赛,全部将其搞定都行啦的样子与打算。全部将其搞定完成都行啦的回事与打算。