用 Pipeline 将训练集参数重复应用到测试集
当我们对训练集应用各种预处理操作时(特征标准化、主成分分析等等), 我们都需要对测试集重复利用这些参数。
pipeline 实现了对全部步骤的流式化封装和管理,可以很方便地使参数集在新数据集上被重复使用。
pipeline 可以用于下面几处:
- 模块化 Feature Transform,只需写很少的代码就能将新的 Feature 更新到训练集中。
- 自动化 Grid Search,只要预先设定好使用的 Model 和参数的候选,就能自动搜索并记录最佳的 Model。
- 自动化 Ensemble Generation,每隔一段时间将现有最好的 K 个 Model 拿来做 Ensemble。
栗子:
问题是要对数据集 Breast Cancer Wisconsin 进行分类, 它包含 569 个样本,第一列 ID,第二列类别(M=恶性肿瘤,B=良性肿瘤), 第 3-32 列是实数值的特征。
from pandas as pd
from sklearn.cross_validation import train_test_split
from sklearn.preprocessing import LabelEncoder
df = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/'
'breast-cancer-wisconsin/wdbc.data', header=None)
# Breast Cancer Wisconsin dataset
X, y = df.values[:, 2:], df.values[:, 1]
encoder = LabelEncoder()
y = encoder.fit_transform(y)
>>> encoder.transform(['M', 'B'])
array([1, 0])
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.2, random_state=0)
我们要用 Pipeline 对训练集和测试集进行如下操作:
- 先用
StandardScaler
对数据集每一列做标准化处理,(是 transformer) - 再用
PCA
将原始的 30 维度特征压缩的 2 维度,(是 transformer) - 最后再用模型
LogisticRegression
。(是 Estimator)
调用 Pipeline 时,输入由元组构成的列表,每个元组第一个值为变量名,元组第二个元素是 sklearn 中的 transformer 或 Estimator。
注意中间每一步是 transformer,即它们必须包含 fit 和 transform 方法,或者 fit_transform
。
最后一步是一个 Estimator,即最后一步模型要有 fit 方法,可以没有 transform 方法。
然后用 Pipeline.fit对训练集进行训练,pipe_lr.fit(X_train, y_train)
再直接用 Pipeline.score 对测试集进行预测并评分 pipe_lr.score(X_test, y_test)
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
还可以用来选择特征:
例如用 SelectKBest 选择特征, 分类器为 SVM,
anova_filter = SelectKBest(f_regression, k=5)
clf = svm.SVC(kernel='linear')
anova_svm = Pipeline([('anova', anova_filter), ('svc', clf)])
完整:
from sklearn import svm
from sklearn.datasets import samples_generator
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import f_regression
from sklearn.pipeline import Pipeline
# generate some data to play with
X, y = samples_generator.make_classification(
n_informative=5, n_redundant=0, random_state=42)
# ANOVA SVM-C
anova_filter = SelectKBest(f_regression, k=5)
clf = svm.SVC(kernel='linear')
anova_svm = Pipeline([('anova', anova_filter), ('svc', clf)])
anova_svm.set_params(anova__k=10, svc__C=.1).fit(X, y)
prediction = anova_svm.predict(X)
anova_svm.score(X, y)
当然也可以应用 K-fold cross validation:
model = Pipeline(estimators)
seed = 7
kfold = KFold(n_splits=10, random_state=seed)
results = cross_val_score(model, X, Y, cv=kfold)
print(results.mean())
完整:
# Create a pipeline that standardizes the data then creates a model
from pandas import read_csv
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
# load data
url = "https://archive.ics.uci.edu/ml/machine-learning-databases/pima-indians-diabetes/pima-indians-diabetes.data"
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
dataframe = read_csv(url, names=names)
array = dataframe.values
X = array[:,0:8]
Y = array[:,8]
# create pipeline
estimators = []
estimators.append(('standardize', StandardScaler()))
estimators.append(('lda', LinearDiscriminantAnalysis()))
model = Pipeline(estimators)
# evaluate pipeline
seed = 7
kfold = KFold(n_splits=10, random_state=seed)
results = cross_val_score(model, X, Y, cv=kfold)
print(results.mean())
Pipeline 的工作方式:
当管道 Pipeline 执行 fit 方法时, 首先 StandardScaler 执行 fit 和 transform 方法, 然后将转换后的数据输入给 PCA, PCA 同样执行 fit 和 transform 方法, 再将数据输入给 LogisticRegression,进行训练。
如下图
资料: http://blog.csdn.net/lanchunhui/article/details/50521648 https://dnc1994.com/2016/04/rank-10-percent-in-first-kaggle-competition/
- Linux | CentOS7下会玩JDK不?你确定?
- Linux | 不懂Linux的码神,不是真正的菜鸟
- 初体验Spring Boot 2支持的HikariCP连接池
- 快来了解JDK10中引入的全新JIT编译器:Graal
- 基于Ryu打造自定义控制器
- Junit 5新特性全集
- 深入了解浏览器的重绘与重排
- 自己动手写区块链(Java版)
- 自己动手写区块链-发起一笔交易(Java版)
- 详解JavaScript跨域问题
- OpenStack Magnum及Liberty新功能简介
- JDK10要来了:下一代 Java 有哪些新特性?
- 是时候忘掉finalize方法了
- 学会一个JVM插件:使用HSDIS反汇编JIT生成的代码
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 如何在Vue中自己实现v-model
- 【STM32F429】第1章 当前主流的小型嵌入式GUI
- 【Unity游戏开发】升级Unity2019后,资源管线后处理采坑记录
- Angular @Effect监听指定Action类型的实现原理
- SAP Spartacus shipping address页面请求1 - Address
- SAP Spartacus shipping address页面请求2.1 - setDefaultAddress
- SAP Spartacus只执行指定单元测试的小技巧
- SAP CDS view里将Date和time连接成timestamp的函数
- SAP CDS view里计算两个date & time字段间包含的seconds秒数
- SAP CDS view里的日期操作函数(往后推算X天得到新日期)
- SAP CDS view的日期格式转换,比如从YYYYMMDD转到DD/MM/YYYY
- SAP CDS view如何取得当前系统日期和系统时间戳
- Vue 父组件如何监听子组件的生命周期
- Django3+websocket+paramiko实现web页面实时输出
- 【5分钟玩转Lighthouse】开车也能跑程序