Overview
Scikit-learn
是一个开源机器学习库,支持监督和非监督学习。它还为模型拟合、数据预处理、模型选择、模型评估和许多其他实用程序提供了各种工具。
Scikit-learn
提供数十种内置的机器学习算法和模型,称为 estimator (估计器)。估计器是任何从数据中学习的对象;它可能是分类、回归或聚类算法,也可能是从原始数据中提取/过滤有用特征的。每个估计器都可以使用 fit
方法拟合数据,然后使用 predict
方法预测或使用transform
方法转化数据。
Scikit-Learn: The most popular and widely used library for machine learning in Python.
- 分类:SVM、近邻、随机森林、逻辑回归等等。
- 回归:Lasso、岭回归等等。
- 聚类:k-均值、谱聚类等等。
- 降维:PCA、特征选择、矩阵分解等等。
- 选型:网格搜索、交叉验证、度量。
- 预处理:特征提取、标准化。
建模流程
The simplest sklearn workflow
以下是一个简单的示例,以 GradientBoostingClassifier 为例,简述下sklearn建模流程:
Step 1: 加载数据集
from sklearn.datasets import load_digits |
Step 2: 拟合模型
from sklearn.ensemble import GradientBoostingClassifier |
Step 3: 模型评估
clf.score(X_test,y_test) |
Step 4: 模型保存和导入
from sklearn.externals import joblib |
Step 5: 模型预测
y_pred = clf.predict(X_test) |
数据准备
内置数据集 | 说明 |
---|---|
load_iris | 鸢尾花数据集(150x4),常用于分类任务 |
load_boston | 波士顿房价预测,常用于回归任务示例 |
load_digits | 手写数字预测(1797x64),常用于神经网络 |
from sklearn.datasets import load_iris, load_digits |
创建数据集 | 说明 |
---|---|
make_classification | 生成分类数据集 |
make_blobs | 生成分类数据集,有更大的灵活性 |
make_multilabel_classification | 生成带有多个标签的分类数据 |
make_regression | 生成回归数据集 |
make_circles | 生成2d分类数据集,两个球面 |
make_moons | 生成2d分类数据集,两个交错半圆 |
常用参数:
- n_samples:指定样本数
- n_features:指定特征数
- n_classes:分类问题类的数量
- n_informative:有效特征数量
- n_redundant:冗余特征数量
- n_repeated:重复特征数量
- n_clusters_per_class:每个类的集群数量
- coef:bool,否返回线性模型的系数
- random_state:随机数
>>> from sklearn.datasets import make_classification, make_regression |
数据集拆分
from sklearn.model_selection import train_test_split |
常用参数:
- test_size:float,样本比例,默认0.25;int,样本量
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25) |
模型持久化
# 已建好模型 model |
机器学习常用算法
回归和分类
sklearn.linear_model | 线性模型 |
---|---|
LinearRegression | 普通最小二乘法 |
Ridge | 岭回归 |
Lasso | 估计稀疏系数的线性模型回归 |
MultiTaskLasso | 多任务 Lasso 回归 |
LogisticRegression | logistic 回归 |
SGDRegressor | 随机梯度下降回归 |
SGDClassifier | 随机梯度下降分类 |
ElasticNetCV | 弹性网络回归 |
MultiTaskElasticNet | 多任务弹性网络回归 |
from sklearn.kernel_ridge import KernelRidge |
sklearn.svm | 支持向量机 |
---|---|
SVC | 支持向量机分类 |
SVR | 支持向量机回归 |
sklearn.neighbors | 最近邻算法 |
---|---|
NearestNeighbors | 无监督最近邻 |
KNeighborsClassifier | k-近邻分类 |
RadiusNeighborsClassifier | 固定半径近邻分类 |
KNeighborsRegressor | 最近邻回归 |
RadiusNeighborsRegressor | |
NearestCentroid | 最近质心分类 |
sklearn.gaussian_process | 高斯过程 |
---|---|
GaussianProcessRegressor | 高斯过程回归(GPR) |
GaussianProcessClassifier | 高斯过程分类(GPC) |
Kernel | 高斯过程内核 |
sklearn.tree | 决策树 |
---|---|
DecisionTreeClassifier | 决策树分类 |
DecisionTreeRegressor | 决策树回归 |
sklearn.kernel_ridge | 内核岭回归 |
---|---|
KernelRidge | 内核岭回归 |
sklearn.isotonic.IsotonicRegression | 等式回归 |
---|---|
IsotonicRegression |
sklearn.multiclass | 多类多标签算法 |
---|---|
multiclass |
sklearn.naive_bayes | 朴素贝叶斯分类器 |
---|---|
GaussianNB | 高斯朴素贝叶斯 |
MultinomialNB | 多项分布朴素贝叶斯 |
BernoulliNB | 伯努利朴素贝叶斯 |
sklearn.ensemble | 集成方法 |
---|---|
BaggingClassifier | Bagging分类 |
BaggingRegressor | Bagging回归 |
RandomForestClassifier | 随机森林分类 |
RandomForestRegressor | 随机森林回归 |
ExtraTreesClassifier | 极限随机树分类 |
ExtraTreesRegressor | 极限随机树回归 |
AdaBoostClassifier | AdaBoost分类 |
AdaBoostRegressor | AdaBoost回归 |
GradientBoostingClassifier | 梯度树提升分类 |
GradientBoostingRegressor | 梯度树提升回归 |
HistGradientBoostingClassifier | 梯度树提升分类 |
HistGradientBoostingRegressor | 梯度树提升回归 |
VotingClassifier | 投票分类器 |
VotingRegressor | 投票回归器 |
StackingClassifier | 堆叠范化 |
StackingRegressor | 堆叠范化 |
from sklearn import datasets |
堆叠算法
from sklearn.linear_model import RidgeCV, LassoCV |
sklearn.neural_network | 神经网络 |
---|---|
MLPClassifier | 多层感知器(MLP)分类 |
MLPRegressor | 多层感知器(MLP)回归 |
高斯混合模型
sklearn.mixture | 高斯混合模型 |
---|---|
GaussianMixture | 高斯混合 |
BayesianGaussianMixture | 变分贝叶斯高斯混合 |
聚类
sklearn.cluster | 聚类 |
---|---|
KMeans | K-means聚类 |
AffinityPropagation | AP聚类 |
MeanShift | |
SpectralClustering | |
AgglomerativeClustering | 层次聚类 |
DBSCAN | |
Birch |
from sklearn.cluster import MiniBatchKMeans |
sklearn.cluster.bicluster | 双聚类 |
---|---|
SpectralCoclustering | |
SpectralBiclustering |
矩阵分解
sklearn.decomposition | 矩阵分解 |
---|---|
PCA | 准确的主成分分析和概率解释 |
IncrementalPCA | 增量主成分分析 |
KernelPCA | 核主成分分析 |
SparsePCA | 稀疏主成分分析 |
MiniBatchSparsePCA | 小批量稀疏主成分分析 |
TruncatedSVD | 截断奇异值分解 |
SparseCoder | 带有预计算词典的稀疏编码 |
DictionaryLearning | 通用词典学习 |
MiniBatchDictionaryLearning | 小批量字典学习 |
FactorAnalysis | 高斯分布因子分析 |
FastICA | 隐变量基于非高斯分布因子分析 |
FastICA | 独立成分分析 |
NMF | 非负矩阵分解 |
LatentDirichletAllocation | 隐 Dirichlet 分配(LDA) |
from sklearn.datasets import load_digits |
流形学习
sklearn.manifold | 流形学习,是一种非线性降维方法 |
---|---|
Isomap | 等距映射(Isometric Mapping) |
LocallyLinearEmbedding | 局部线性嵌入 |
SpectralEmbedding | 谱嵌入 |
MDS | 多维尺度分析 |
TSNE | t 分布随机邻域嵌入(t-SNE) |
模型选择和评估
评分指标
sklearn.metrics | Description |
---|---|
accuracy_score(y_true, y_pred) | 分类:准确率 |
balanced_accuracy_score(y_true, y_pred) | 分类:平衡准确率 |
f1_score(y_true, y_pred) | 分类:f1 score |
precision_score(y_true, y_pred) | 分类:精准率 |
average_precision_score(y_true, y_pred) | 分类:平均精准率 |
log_loss(y_true, y_pred) | 分类:损失 |
roc_auc_score(y_true, y_score) auc(fpr, tpr) |
分类:auc值(ROC曲线下面积) |
recall_score(y_true, y_pred) | 分类:召回率 |
confusion_matrix(y_true, y_pred) | 分类:混淆矩阵 |
explained_variance_score(y_true, y_pred) | 回归:可解释方差 |
mean_absolute_error(y_true, y_pred) | 回归:MAE |
mean_squared_error(y_true, y_pred) | 回归:均方误差(MSE) |
root_mean_squared_error(y_true, y_pred) | 回归:均方标准差(RMSE) |
r2_score(y_true, y_pred) | 回归:R2 |
label_ranking_loss | 排序度量 |
adjusted_mutual_info_score | 聚类:互信息 |
completeness_score | 聚类:完整性 |
homogeneity_score | 聚类:同质性 |
示例:
import numpy as np |
混淆矩阵:
0, 0, 0, 1, 1, 1, 1, 1] y_true = [ |
分类报告:
from sklearn.metrics import classification_report |
从二分类到多分类多标签
一些指标基本上是为二进制分类任务定义的(例如 f1_score,roc_auc_score),这些情况下,只评估正类,默认情况下正类被标记为 1(当然也可以通过 pos_label 参数配置)。
在将二分类度量扩展到多类或多标签问题时,数据被视为二分类问题的集合。在可用的情况下,应该使用average参数从下面选择计算方法。
"macro"
简单地计算二分类度量的平均值,给每个类同等权重"weighted"
计算每个类分数的加权平均值,权重由数据样本权重得到"micro"
在多标签任务中,微平均可能是首选"samples"
仅适用于多标签问题- 选择
average=None
将返回一个包含每个类分数的数组
from sklearn import metrics |
交叉验证
单指标评估
scores = cross_val_score(estimator, X, y=None, scoring=None, cv=None) |
常用参数:
- scoring:评分函数或sklearn预定义的评分字符串
- cv:交叉验证(Cross-validation)数量
return:包含所有的结果的 ndarray
from sklearn import svm, datasets |
Note:如果传递了错误的评分名称,则会引发InvalidParameterError。您可以通过调用get_scorer_names来检索所有可用度量的名称。
多指标评估
Scikit-learn还允许在GridSearchCV
、RandomizedSearchCV
和cross_validate
中评估多个指标。
scores = cross_validate(estimator, X, y=None, scoring=None, cv=None) |
常用参数:
- scoring:str, callable, list, tuple, or dict
- cv:交叉验证(Cross-validation)数量
return:包含所有的结果的 dict
3) cv_results = cross_validate(lasso, X, y, cv= |
多个指标可以指定为列表、元组或一组预定义的记分器名称:
'accuracy', 'precision'] scoring = [ |
或者作为dict映射记分器名称到预定义或自定义记分函数:
from sklearn.metrics import make_scorer |
ROC 曲线
Receiver operating characteristic (ROC)
import numpy as np |
回归模型残差分布
import matplotlib.pyplot as plt |
当拟合线性最小二乘回归模型时(LinearRegression和Ridge),我们可以使用此图来检查是否满足一些模型假设,特别是残差应不相关,其期望值应为零,其方差应为常数。
验证曲线
绘制得分曲线以评估模型
import numpy as np |
如果训练分数和验证分数都很低,模型将不合适。如果训练分数高,验证分数低,则模型过拟合,否则效果很好。
可以使用 validation_curve 的 from_estimator 方法来只绘制验证曲线:
from sklearn.model_selection import ValidationCurveDisplay |
学习曲线
学习曲线显示了不同数量的训练样本的估计器的验证和训练分数。可以让我们了解从添加更多训练数据中获益多少,以及估算器是否因方差误差或偏差误差而造成更多损失。
可以使用函数learning_curve来生成绘制此类学习曲线所需的值:
from sklearn.model_selection import learning_curve |
可以使用LearningCurveDisplay的from_estimator方法来只绘制学习曲线
from sklearn.model_selection import LearningCurveDisplay |
超参数调优
超参数是估计器中没有直接学习的参数。在scikit-learn中,它们作为参数传递给估计器类的构造函数。建议在超参数空间中搜索最佳交叉验证分数进行优化。要获得估计器所有参数的名称和当前值,请使用:
estimator.get_params() |
目前来说sklearn中超参数优化器有四种:
sklearn.model_selection | 模型选择 |
---|---|
GridSearchCV | 网格搜索详尽地考虑了所有参数组合 |
RandomizedSearchCV | 随机搜索可以从具有指定分布的参数空间中抽样给定数量的候选者 |
HalvingGridSearchCV | 对半网格搜索 |
HalvingRandomSearchCV | 对半随机网格搜索 |
其中,对半网格搜索采用了类似锦标赛的筛选机制进行多轮的参数搜索,每一轮输入原始数据一部分数据进行模型训练,并且剔除一半的备选超参数。由于每一轮都只输入了一部分数据,因此不同备选超参数组的评估可能存在一定的误差,但由于每一轮都只剔除一半的超参数组而不是直接选出最优的超参数组,因此也拥有一定的容错性。不难发现,这个过程也像极了RFE过程——每一轮用一个精度不是最高的模型剔除一个最不重要的特征,即保证了执行效率、同时又保证了执行精度。
网格搜索
GridSearchCV 将评估所有可能的参数值组合,并保留最佳组合。
GridSearchCV(estimator, param_grid, scoring=None, cv=None, verbose=0) |
常用参数:
- estimator:估计器
- param_grid:参数 dict or list of dict
- verbose:日志冗长度,int:冗长度,0:不输出训练过程,1:偶尔输出,>1:对每个子模型都输出。
- scoring:控制评分,见 sklearn.metrics
常用方法 | 说明 |
---|---|
fit(X, y) | 拟合所有参数 |
get_params() | 获得估计器的参数 |
predict(X) | 调用最优参数估计器的predict方法 |
predict_proba(X) | 调用最优参数估计器的predict_proba方法 |
transform(X) | 调用最优参数估计器的transform方法 |
常用属性 | 说明 |
---|---|
cv_results_ | dict of numpy (masked) ndarrays |
best_params_ | 最优参数 |
best_estimator_ | 最优估计器 |
best_score_ | 最优得分 |
Examples:
from sklearn import svm, datasets |
首先需要明确的是,参数空间内总备选参数组合的数量为各参数取值之积,且随着参数空间内每个参数取值增加而呈现指数级上升,且随着参数空间内参数维度增加(增加新的超参数)呈指数级上升,且二者呈现叠加效应。
我们可以通过“小步迭代快速调整”的方法来进行超参数的搜索。在这个策略里,我们每次需要设置一个相对较小的参数搜索空间,然后快速执行一次超参数搜索,并根据超参数搜索结果来调整参数空间,并进行更进一步的超参数搜索,如此往复,直到参数空间内包含了全部参数的最优解为止。
随机搜索
RandomizedSearchCV(estimator, param_grid, n_iter=10, scoring=None, cv=None, verbose=0) |
常用参数:
- param_grid:参数 dict or list
- verbose:日志冗长度,int:冗长度,0:不输出训练过程,1:偶尔输出,>1:对每个子模型都输出。
- scoring:控制评分,见 sklearn.metrics
- n_iter:参数指定计算预算,即抽样候选数或抽样迭代的数量。
常用方法 | 说明 |
---|---|
fit(X, y) | 拟合所有参数 |
get_params() | 获得估计器的参数 |
predict(X) | 调用最优参数估计器的predict方法 |
predict_proba(X) | 调用最优参数估计器的predict_proba方法 |
transform(X) | 调用最优参数估计器的transform方法 |
常用属性 | 说明 |
---|---|
cv_results_ | dict of numpy (masked) ndarrays |
best_params_ | 最优参数 |
best_estimator_ | 最优估计器 |
best_score_ | 最优得分 |
Examples:
from sklearn.datasets import load_iris |
连续减半搜索
Scikit-learn还提供了HalvingGridSearchCV和HalvingRandomSearchCV估计器,可用于使用连续减半搜索参数空间。
HalvingGridSearchCV(estimator, param_distributions, cv=5, scoring=None, verbose=0) |
from sklearn.datasets import make_classification |
数据预处理
scikit-learn 提供了数据清洗、特征变换、特征提取、特征生成的数据处理估计器。
这些估计器通过fit
方法从训练集学习模型参数(例如标准化的平均值和标准差),然后通过transform
方法转换数据。fit_transform
方法可以同时训练和转换数据,更方便、更有效。
sklearn 目前已经支持 get_feature_names 方法获取转换后的特征名
特征提取
特征提取被用于将原始特征提取成机器学习算法支持的数据格式,比如文本和图像特征提取。
sklearn.feature_extraction | 特征提取 |
---|---|
DictVectorizer | 从字典加载特征 |
FeatureHasher | 特征hashing技术 |
text.CountVectorizer | 文本特征向量化 |
text.TfidfTransformer | 将文本计数矩阵归一化为TF-IDF矩阵 |
text.TfidfVectorizer | 将原始文档提取为TF-IDF特征 |
text.HashingVectorizer | 大型文本文档的hash向量化 |
image.extract_patches_2d | 将2D图像reshape成分块集合(patches) |
image.grid_to_graph | 像素到像素连接的图形 |
image.img_to_graph | 像素到像素t梯度连接的图形 |
image.reconstruct_from_patches_2d | 从patches重建图像 |
image.PatchExtractor | 从图像集合中提取patches |
从字典加载特征
measurements = [ |
文本特征向量化
from sklearn.feature_extraction.text import CountVectorizer |
from sklearn.feature_extraction.text import CountVectorizer |
标准化/归一化
sklearn.preprocessing | 预处理 |
---|---|
StandardScaler() | z-score标准化 |
Normalizer(norm=‘l2’) | 使用l1 、l2 或max 范数归一化 |
MinMaxScaler() | min-max归一化 |
MaxAbsScaler() | Max-abs归一化,缩放稀疏数据的推荐方法 |
RobustScaler() | 分位数归一化,缩放有离群值的数据 |
from sklearn import preprocessing |
非线性变换
sklearn.preprocessing | 预处理 |
---|---|
QuantileTransformer | 分位数转换,将数据映射到0-1之间的均匀分布,或高斯分布 |
PowerTransformer | 幂变换,将数据从任何分布映射到尽可能接近高斯分布,以稳定方差并最小化倾斜度。 |
'box-cox', standardize=False) pt = preprocessing.PowerTransformer(method= |
分类特征编码
sklearn.preprocessing | 预处理 |
---|---|
OrdinalEncoder | 编码分类特征 |
OneHotEncoder | One-hot 编码 |
LabelEncoder | 目标变量重编码 |
LabelBinarizer | 目标标签二值化 |
MultiLabelBinarizer | 多标签目标二值化 |
常用参数:
- categories:每个特征的类别。’auto’ or a list of array-like,
- drop=‘if_binary’:删除二分类特征的第一个类别
- handle_unknown:’error’, ‘ignore’:忽略未知类别, ‘infrequent_if_exist’:未知类别编码到不频繁类别
- min_frequency:生成低频率类别。int or float
- max_categories:类别数,可生成低频率类别。
默认情况下,每个特征的取值可以自动从数据集推断,并可以在categories_
属性中找到
X = pd.DataFrame([['male', 'US', 'Safari'], |
也可以使用参数categories
显式指定类别
'female', 'male'] genders = [ |
可以使用get_feature_names_out()
方法获取列名:
enc.get_feature_names_out() |
对于二分类别,OneHotEncoder
通过设置参数drop='if_binary'
支持保持其中一列
'male', 'US', 'Safari'], X = [[ |
OneHotEncoder和OrdinalEncoder支持将不频繁类别的组合到一个类别,能够收集不频繁类别的参数是min_frequency和max_categories。当指定handle_unknown='infrequent_if_exist'
时,在转换过程中遇到未知类别时,则被视为不频繁类别,从而不会引发错误。
'dog'] * 5 + ['cat'] * 20 + ['rabbit'] * 10 + X = np.array([[ |
OneHotEncoder.get_feature_names_out
使用 “infrequent_sklearn”
作为不频繁的特征的名称:
array(['x0_cat', 'x0_rabbit', 'x0_infrequent_sklearn'], dtype=object) |
彩蛋:常用的年龄编码
bins = [0, 1, 13, 20, 60, np.inf] |
连续特征离散化
sklearn.preprocessing | 预处理 |
---|---|
KBinsDiscretizer | K-bins离散化 |
Binarizer(threshold=0.0) | 二值化 |
常用参数:
- n_bins:分箱数
- encode:{‘onehot’, ‘onehot-dense’, ‘ordinal’}, default='onehot’
- strategy:定义分箱策略。{‘uniform’, ‘quantile’, ‘kmeans’}, default=‘quantile’
3., 5., 15 ], X = np.array([[ - |
注意:第一个和最后一个分箱边界被扩展到无穷 [-np.inf, bin_edges[1:-1], np.inf]
。因此,对于当前示例,这些特征边界被定义为:
- feature 1:
- feature 2:
- feature 3:
生成多项式特征
sklearn.preprocessing | 预处理 |
---|---|
PolynomialFeatures(degree=2, interaction_only=False) | 生成多项式特征 |
SplineTransformer(n_knots=5, degree=3, knots=‘uniform’) | 生成单变量样条(B-Splines)特征 |
import numpy as np |
degree=2
: 的特征从 转换为interaction_only=True
:只生成交互项
样条是分段的多项式,由其多项式degree和knots的位置参数控制。
缺失值插补
scikit-learn估计器假设数组中的所有值都是数值,且都有意义。
sklearn.impute | 缺失值插补 |
---|---|
SimpleImputer | 单变量插补 |
IterativeImputer | 多重插补 |
KNNImputer | 最近邻插补 |
MissingIndicator | 标记缺失值 |
SimpleImputer类提供了估算缺失值的基本策略。缺失值可以用提供的常量值估算,也可以使用缺失值所在的每列的统计信息(平均值、中位数或最频繁值)。该类还允许不同的缺失值编码。
常用参数:
- missing_values:缺失值的占位符。int, float, str, np.nan, None or pandas.NA, default=np.nan
- strategy:估算策略。“mean”, “median”, “most_frequent”, “constant”, default=’mean’
- fill_value:str or numerical value, default=None。当 strategy=“constant”,fill_value 用于替换所有出现的 missing_values。
import numpy as np |
当使用’most_frequent’或’constant’策略时,SimpleImputer还支持分类数据插补:
import pandas as pd |
更复杂的方法是使用 IterativeImputer类,该类将每个缺失值的特征指定为目标变量y,其他特征列被处理为输入变量X,然后拟合回归模型,用预测值插补缺失值。迭代 max_iter次,返回最后一轮估算的结果。
import numpy as np |
KNNImputer使用k-Nearest Neighbors方法填充缺失值。默认情况下,使用欧几里得距离查找最近的邻居。每个缺失的值都使用n_neighbors个最近邻的均值填充。
import numpy as np |
MissingIndicator 将数据集转换为相应的 bool 矩阵,用来标记缺失值。
from sklearn.impute import MissingIndicator |
异常值检测
远离其它内围点(inlier)的数据通常被定义为离群值(outlier),也称异常值。异常检测(anomaly detection)分为离群点检测以及新奇值检测两种。
- Outlier Detection(OD):离群值检测。训练数据包含异常值,这些异常值被定义为远离其他样本。
- Novelty Detection(ND):新奇值检测。训练数据没有异常值,我们检测新样本是否为异常值。在这种情况下,异常值也被称为新奇值。
scikit-learn项目提供了一套无监督学习方法,用于新奇值或异常值检测。
sklearn | 说明 |
---|---|
svm.OneClassSVM | 基于 SVM (使用高斯内核) 的思想在特征空间中训练一个超球面,边界外的点即为异常值。 |
linear_model.SGDOneClassSVM | 基于随机梯度下降(SGD)的One-Class SVM |
covariance.EllipticEnvelope | 假设数据是高斯分布,训练一个椭圆包络线,边界外的点则为离群点 |
ensemble.IsolationForest | 每次分裂都是随机的,路径长度小的点即为离群点 |
neighbors.LocalOutlierFactor | 局部离群因子。基于密度的异常检测算法 |
先拟合数据,然后新样本可以使用predict
方法分类为内值或外值:内值被标记为1,而异常值被标记为-1。
estimator.fit(X_train) |
注意:neighbors.LocalOutlierFactor 默认不支持 predict
, decision_function
and score_samples
方法,仅支持 fit_predict
,就像最初被设计检测离群值检测的一样。训练样本的异常值得分可以通过 negative_outlier_factor_
属性获得。
如果真的想使用neighbors.LocalOutlierFactor进行新奇值检测,可以在拟合估计器之前将novelty
参数设置为True
来实例化估计器。在这种情况下,fit_predict
不可用。请注意,此时必须只对新样本使用predict
、decision_function
andscore_samples
方法,而不是在训练样本上使用,因为这会导致错误的结果。即predict
的结果将与fit_predict
不同。训练样本的异常分数仍然可以通过 negative_outlier_factor_
属性获得。
Method | Outlier detection | Novelty detection |
---|---|---|
fit_predict |
OK | Not available |
predict |
Not available | Use only on new data |
decision_function |
Not available | Use only on new data |
score_samples |
Use negative_outlier_factor_ |
Use only on new data |
negative_outlier_factor_ |
OK | OK |
import numpy as np |
特征选择
sklearn.feature_selection | 特征选择 |
---|---|
VarianceThreshold(threshold=0.0) | 移除低方差特征,单变量特征选择 |
SelectKBest(score_func, k=10) | 选择 K 个评分最高的特征 |
SelectPercentile(score_func, percentile=10) | 根据最高分数的百分位数选择特征 |
SelectFpr, SelectFdr, SelectFwe | 根据假设检验的p-value选择特征 |
GenericUnivariateSelect | 单变量特征选择估计器汇总 |
RFECV | 在交叉验证中执行递归式特征消除 |
SelectFromModel | 通过特征重要性筛选特征 |
SequentialFeatureSelector | 顺序特征选择 |
评分函数:
- 对于回归问题:f_regression , mutual_info_regression, r_regression
- 对于分类问题:chi2 , f_classif , mutual_info_classif
单变量特征选择通过单变量统计相关性选择最佳特征。
from sklearn.datasets import load_iris |
递归式特征消除 RFECV 通过特征重要性筛选特征
常用参数:
- estimator:具有fit方法的监督学习估计器,通过
coef_
属性或feature_importances_
属性筛选特征 - step:int,每次迭代删除的特征数量,float,每次迭代要删除的特征百分比
- min_features_to_select:要选择的最小特征数
- cv:交叉验证
- scoring:评分函数
from sklearn.datasets import make_friedman1 |
SelectFromModel 通过特征重要性筛选特征
常用参数:
- estimator:具有fit方法的监督学习估计器,通过
coef_
属性或feature_importances_
属性筛选特征 - threshold:特征选择的阈值,大于阈值的特征将被留下。float,特征百分比,str,“median”, “mean” or “0.1*mean”
- min_features_to_select:要选择的最小特征数
SequentialFeatureSelector 按顺序添加(向前选择)或删除(向后选择)特征,以贪婪的方式找出最佳特征子集
常用参数:
- estimator:估计器
- n_features_to_select:要选择的特征数量。“auto”, int or float, default=”auto”
- direction:向前或向后搜索。{‘forward’, ‘backward’}, default=’forward’
- scoring:评分。str or callable, default=None
- cv:交叉验证
自定义转换器
有时,您会希望将现有的Python函数转换为Transformer,以协助数据预处理。FunctionTransformer可以把任意可调用对象构建成一个Transformer。FunctionTransformer将其 X 参数转发到用户定义的函数,并返回此函数的结果。
sklearn.preprocessing.FunctionTransformer(func=None, inverse_func=None, validate=False, accept_sparse=False, check_inverse=True, feature_names_out=None, kw_args=None, inv_kw_args=None) |
例如
import pandas as pd |
注意:
- 设置feature_names_out参数后才能启用get_feature_names_out方法。feature_names_out:callable, ‘one-to-one’ or None, default=None
- validate参数控制X是否转换为Numpy数组,最好设置validate=True,只有这样才能正常使用feature_names_out参数定义特征名,从而使特征名在管道内正常传输
- 最好设置accept_sparse=True,可接受稀疏矩阵,避免不必要的报错
0, 1], [2, 3]], columns=['a', 'b']) X = pd.DataFrame([[ |
FunctionTransformer非常方便,但是如果您希望您的转换器是可训练的,在fit()方法中学习一些参数,然后在transform()方法中使用它们。为此,我们需要编写一个自定义类。Scikit-Learn依赖于duck类型,所以这个类不必从任何特定的基类继承。它只需要三个方法:fit()(必须返回self)、transform () 和 fit_transform()。
只需添加TransformerMixin作为基类,就可以免费获得fit_transform():默认实现将只调用fit(),然后再调用transform()。如果将BaseEstimator添加为基类(并避免使用*args和**kwargs),您还将获得两个额外的方法:get_params ()和set_params()。这些对于自动超参数调优非常有用。
例如,这里有一个自定义 transformer,其行为与StandardScaler非常相似:
from sklearn.base import BaseEstimator, TransformerMixin |
这里有几点需要注意:
- sklearn.utils.validation 包含几个我们可以用来验证输入的函数。
- Scikit-Learn管道要求fit()方法有两个参数X和y,这就是为什么我们需要y=None,即使我们不使用y。
- 所有Scikit-Learn估计器都在fit()方法中设置
n_features_in_
,并且它们确保传递给transform()或predict()的数据具有此数量的特征。 - fit ()方法必须返回self。
- (可选)所有的估算器都应该在拟合中设置
feature_names_in_()
方法,它们被传递一个DataFrame。此外,所有的转换器都应该提供get_feature_names_out()
方法。以及当它们的转换可以被逆转时的inverse_transform()
方法。
回归任务中的目标变换
TransformedTargetRegressor在拟合回归模型之前转换目标变量y,预测时则通过逆变换映射回原始值。它以回归估计器和将转换操作作为参数:
import numpy as np |
对于简单的变换,可以传递变换和逆变换函数:
def func(x): |
Pipeline
Pipeline允许按顺序将多个估计器连接成一个。这很有帮助,因为处理数据时通常有固定的步骤序列,例如特征选择、标准化和分类。Pipeline 只需在数据上调用拟合并预测一次,即可拟合整个估计器序列。
优秀的应用案例:
机器学习之构建Pipeline(一)
机器学习之构建Pipeline(二)自定义Transformer和Pipeline
机器学习之构建Pipeline(三)从pipeline获取特征重要度
Pipeline
Pipeline 拟合数据,相当于依次对每个估计器拟合转换数据,且上一个估计器的输出作为下一个估计器的输入。因此,Pipeline 的中间步骤必须必须实现fit_transform
和transform
方法,最终估算器只需要实现fit
。
Pipeline 具有最后一个估计器的所有方法。
sklearn.pipeline.Pipeline(steps, memory=None, verbose=False) |
Pipeline
使用(key,value)
列表构建,其中key
是名称字符串,value
是估计器对象。Pipeline 中的估计器可以使用memory参数进行缓存。
from sklearn.svm import SVC |
常用方法 | 说明 |
---|---|
fit(X, y) | 拟合模型 |
fit_predict(X, y) | 转换数据,并调用最终估计器fit_predict方法 |
fit_transform(X, y) | 拟合模型,并调用最终估计器transform方法 |
predict(X) | 转换数据,并调用最终估计器的predict方法 |
predict_proba(X) | 转换数据,并调用最终估计器的predict_proba方法 |
transform(X) | 转换数据,并调用最终估计器的transform方法 |
get_feature_names_out() | 获取/自定义切片估计器特征名称 |
get_params() | 获得切片估计器的参数 |
set_params() | 设置切片估计器的参数 |
管道的估计器作为列表存储在steps
属性中
1] pipe[: |
sklearn.pipeline.make_pipeline
是Pipeline
的快捷方式,依次传入估计器即可,不需要命名
from sklearn.pipeline import make_pipeline |
注意,make_pipeline并不是以列表的形式传入估计器
FeatureUnion
FeatureUnion将几个Transformer组合成一个新的Transformer。其中每个Transformer都独立并行拟合数据,然后将它们输出联合。
sklearn.pipeline.FeatureUnion(transformer_list, *, n_jobs=None, transformer_weights=None, verbose=False) |
FeatureUnion
使用(key,value)
列表构建,其中key
是名称字符串,value
是估计器对象:
from sklearn.pipeline import FeatureUnion |
ColumnTransformer
许多数据集包含不同类型的特征,例如文本型、浮点型和日期型,其中每种类型的特征都需要单独的预处理或特征提取步骤。ColumnTransformer 对于每列,可以应用不同的变换,并且每个Transformer生成的特征将被连接起来,形成一个特征空间。
sklearn.compose.ColumnTransformer(transformers, *, remainder='drop', sparse_threshold=0.3, n_jobs=None,transformer_weights=None, verbose=False, verbose_feature_names_out=True) |
使用 (name, transformer, columns)
列表构建,分别指定名称、Transformer对象和对应的特征名。
注意:转换特征矩阵中列的顺序遵循transformers
列表中指定列的顺序。未指定的原始特征矩阵的列默认情况下(remainder='drop'
)将从生成的转换特征矩阵中删除,除非设置remainder='passthrough
,那自动通过的列将被添加到transformers
输出的末尾。如果remainder
是一个估计器,则剩余未指定的列使用remainder
估计器。
import pandas as pd |
增量学习
我们在现实模型的训练过程中会有一些细节问题需要我们去解决。比如在很多流量很大的电商及资讯类网站的推荐系统中,每天的数据其实是增长很快的,所以模型迭代的频率也是非常高的;或者训练数据量太多的时候,模型有时候会出现Memory Error的错误。在这两种情况下,那么增量学习(incremental learning)就派上用场了。增量学习是近来才出现的概念,其目的在于训练数据的同时,也能保留以前模型的效果,即在之前模型的基础上对新增的数据进行训练,从而使模型能不断适应最新的数据。
partial_fit 方法
sklearn中提供了很多增量学习算法。虽然不是所有的算法都可以增量学习,但是提供了 partial_fit 方法的估计器都可以进行增量学习。事实上,使用 mini-batch的数据进行增量学习是这些估计器的核心,因为它能让内存中始终只有少量的数据。
以下是不同任务的增量估计器列表:
- Classification
- sklearn.naive_bayes.MultinomialNB
- sklearn.naive_bayes.BernoulliNB
- sklearn.linear_model.Perceptron
- sklearn.linear_model.SGDClassifier
- sklearn.linear_model.PassiveAggressiveClassifier
- sklearn.neural_network.MLPClassifier
- Regression
- sklearn.linear_model.SGDRegressor
- sklearn.linear_model.PassiveAggressiveRegressor
- sklearn.neural_network.MLPRegressor
- Clustering
- sklearn.cluster.MiniBatchKMeans
- sklearn.cluster.Birch
- Decomposition / feature Extraction
- sklearn.decomposition.MiniBatchDictionaryLearning
- sklearn.decomposition.IncrementalPCA
- sklearn.decomposition.LatentDirichletAllocation
- sklearn.decomposition.MiniBatchNMF
- Preprocessing
- sklearn.preprocessing.StandardScaler
- sklearn.preprocessing.MinMaxScaler
- sklearn.preprocessing.MaxAbsScaler
不同于使用fit方法,partial_fit 方法不需要清空模型,只需要每次传入mini-batch 数据,每个 batch 的数据的 shape 应保持一致。一般来说,在调用partial_fit时不应修改估计器参数。相比之下,warm_start常用于相同的数据使用不同的参数重复拟合。
在可迭代训练的模型中,partial_fit 方法通常是执行一次迭代。以 SGDClassifier 为例,增量学习流程如下
# Create data streaming |
Example: 增量学习Demo之partial_fit 方法
warm_start 参数
warm_start 直译为热启动,在模型训练过程中起作用。如果 warm_start=True 就表示模型在重复调用 fit 方法时可以在前一阶段的训练结果上继续训练,而不清除原有模型,可以提升模型的训练速度,且训练结果保持一致。如果 warm_start=False 就表示从头开始训练模型。
在集成算法中,warm_start 将与 n_estimators交互。如果训练好了一个包含 n_estimators=N 个估计器的集成模型后,想在此基础上训练一个包含 n_estimators=M 个估计器的模型,则可以设置 warm_start=True,新模型在原有的基础上再训练 M-N 个新的估计器。
Example: 增量学习Demo之warm_start 参数
utils
计算 sample_weight
from sklearn.utils.class_weight import compute_sample_weight |
计算 class_weight
import numpy as np |