1. 写在前面
在上一讲中,我们对于Sklearn框架有了一个较为直观的认识,但是对于其中的细节部分,可能还是不知甚解。这次,我们将会详细的介绍其中的一些知识,包括:Sklearn版本注意事项、最基本的评估器与转换器、fit、transform与fit_transform的区别、pipeline使用,tfidf与CountVectorizer方法等。
2. Sklearn版本注意事项
在网上很多Sklearn的例子,但是很多时候copy下来又运行不了,其实很多时候是因为Sklearn版本不同。机器学习是一个非常活跃的领域,而Sklearn又是一个非常活跃的框架,版本更新迭代速度很快,而且修改比较多,很多时候上一个版本的函数与方法,在下一个版本中就已经不能使用了。大家需要自己去Sklearn官网里查看最新的API。另外一点,好在Pycharm里会提醒,在接下来的版本中可能移除的方法,让你及时调整代码。因此如果出现了网上的示例不能运行的情况,有可能是版本已经更新了。
3. 评估器与转换器
说到评估器与转换器,大家可能没有一个直观的认识。事实上,基本上大部分的分类器都属于评估器,这点你可以从分类器的包名可以看到:
这里面类汇总,第一个为基础评估器,第二个为基础分类器,最后一个为基础转换器。基本上所有的评估器与转换器都有三个基本方法,fit,transform,fit_transform。为什么着重讲这个,因为在pipeline中,它的最后一部分为评估器,也就是说最后一步一定是个分类器,而前面的预处理、降维、正则化等都是转换器。这点我们会在后面讲到。
4. fit、transform与fit_transform的区别
其实程序员最应去的一个地方就是Stackoverflow,那里有最权威、最清楚的Bug调试解决方案。虽然大部分都是英语,但是英语解释的比较确切。
fit原义指的是安装、使适合的意思,其实有点train的含义但是和train不同的是,它并不是一个训练的过程,而是一个适配的过程,过程都是定死的,最后只是得到了一个统一的转换的规则模型。
transform则指的是转换.。从可利用信息的角度来说,转换分为无信息转换和有信息转换。无信息转换是指不利用任何其他信息进行转换,比如指数、对数函数转换等。有信息转换从是否利用目标值向量又可分为无监督转换和有监督转换。无监督转换指只利用特征的统计信息的转换,统计信息包括均值、标准差、边界等等,比如标准化、PCA法降维等。有监督转换指既利用了特征信息又利用了目标值信息的转换,比如通过模型选择特征、LDA法降维等。
而fit_transform方法则是把上述2个过程统一起来,对模型先训练,然后根据输入的训练数据返回一个转换矩阵。这个过程通常只存在训练过程中。在Pipeline中尤为明显。
5. pipeline的使用
给出一幅图,就可以大致了解pipeline的运行方式与流程:
这里我们可以看到pipeline的最后一步一定是一个分类器,而开始部分可以是一个规约化,中间可以是降维、可以是特征选取等等一套流程。当然,这里用的都是包里自带的评估器与分类器,如果想自己写其中的一个过程然后添加到整个pipeline中,还需要继承基类(第3节讲到)后才能添加进去。
具体的使用样例如下:
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
pipe_lr = Pipeline([('sc',StandardScaler()),('pca',PCA(n_components=2)),('clf',LogisticRegression(random_state=1))
])
pipe_lr.fit(X_train,y_train)
print('Test accuracy: %.3f' % pipe_lr.score(X_test,y_test))
# Test accuracy: 0.947
6. CountVectorizer()与TfidfTransformer()
在第三节中,我们讲到了评估器与转换器,这2个都是有上面那3个方法,评估器可能还会多一个predict预测这个方法。主要是用来分类的。
同样的,评估器里的算法多为机器学习算法,而转换器里的算法多为转换算法。像TFIDF算法就是转换器,它只不过是把一个文档列表转换为一个TFIDF矩阵,但是如何转换是有一个模型的,这个模型这个被训练语料fit后的模型,它同样可以被用来转换(transform)测试语料,例如下面这代码:
#初始化一个ftidf对象
tfidf=TfidfTransformer();
from sklearn.feature_extraction.text import CountVectorizer
#初始化一个统计词频对象
count_vect = CountVectorizer()
#返回的是一个稀疏矩阵
train_data = count_vect.fit_transform(train_data)
#通过稀疏矩阵获得tfidf矩阵
train_result=tfidf.fit_transform(train_data);
#使用同样的统计词频模型来生成训练语料的统计词频矩阵。
test_data = count_vect.transform(test_data)
#使用同样的模型对测试语料转换,可以得到和测试语料同样的TFIDF矩阵。
test_result=tfidf.transform(test_data);
这里我们在使用tfidf转换器的同时需要使用一个统计词频转换器,因为统计词频转换器可以把文章列表转换为一个词频的矩阵,如下表:
文档顺序 | 单词1 | 单词2 | ··· |
---|---|---|---|
1 | 1 | 2 | ··· |
2 | 0 | 2 | ··· |
··· | ··· | ··· | ··· |