
作者 | Ideogram 提供图片
7个您可能不知道的Scikit-Learn技巧
作为具备Python编程技能的数据科学家,我们经常使用Scikit-Learn。它是一个通常会先教给新用户的机器学习包,并且可以一直用到生产环境中。然而,目前教授的大部分内容都是基础实现,而Scikit-Learn包含许多可以改进我们数据工作流程的秘密。
本文将讨论七个您可能不知道的Scikit-Learn技巧。话不多说,让我们开始吧。
1. 概率校准
一些机器学习模型的分类任务模型会为每个类别提供概率输出。概率估计输出的问题在于它不一定是经过良好校准的,这意味着它不反映输出的实际可能性。
例如,您的模型可能提供95%的“欺诈”类别输出,但实际上只有70%的该预测是正确的。概率校准旨在调整概率以反映实际可能性。
有一些校准方法,尽管最常见的是Sigmoid校准和等otonic回归。以下代码使用Scikit-Learn来校准分类器中的技术。
1 2 3 4 5 6 7 |
from sklearn.calibration import CalibratedClassifierCV from sklearn.svm import SVC svc = SVC(probability=False) calibrated_svc = CalibratedClassifierCV(base_estimator=svc, method='sigmoid', cv=5) calibrated_svc.fit(X_train, y_train) probabilities = calibrated_svc.predict_proba(X_test) |
只要模型提供概率输出,您就可以更改模型。该方法允许您在“sigmoid”或“isotonic”之间切换。
例如,这里是一个带有等otonic校准的Random Forest分类器。
1 2 3 4 5 6 7 |
from sklearn.calibration import CalibratedClassifierCV from sklearn.ensemble import RandomForestClassifier rf = RandomForestClassifier(random_state=42) calibrated_rf = CalibratedClassifierCV(base_estimator=rf, method='isotonic', cv=5) calibrated_rf.fit(X_train, y_train) probabilities = calibrated_rf.predict_proba(X_test) |
如果您的模型无法提供所需的预测,请考虑校准您的分类器。
2. 特征联合
下一个我们要探索的秘密是特征联合的实现。如果您不知道它,特征联合是一个Scikit-Class,它提供了一种将多个转换器对象组合成一个单一转换器的方法。
当我们想要从同一数据集中执行多个转换和提取,并在机器学习建模中使用它们时,它是一个非常有价值的类。
让我们通过以下代码看看它们是如何工作的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
from sklearn.pipeline import FeatureUnion, Pipeline 从 sklearn.分解 导入 PCA 从 sklearn.特征选择 导入 SelectKBest from sklearn.svm import SVC combined_features = FeatureUnion([ ("pca", PCA(n_components=2)), ("select_best", SelectKBest(k=1)) ]) pipeline = Pipeline([ ("features", combined_features), ("svm", SVC()) ]) pipeline.fit(X_train, y_train) |
在上面的代码中,我们可以看到我们将两种用于降维的方法:PCA和选择最佳特征,组合成一个特征联合的转换器流水线。通过流水线将它们组合起来,将允许我们的特征联合在一个单一的流程中使用。
如果您希望更好地控制特征操作和预处理,也可以链接特征联合。这里有一个我们之前讨论过的方法的例子,增加了一个特征联合。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# 第一个特征联合 first_union = FeatureUnion([ ("pca", PCA(n_components=5)), ("select_best", SelectKBest(k=5)) ]) # 第二个特征联合 second_union = FeatureUnion([ ("poly", PolynomialFeatures(degree=2, include_bias=False)), ("scaled", StandardScaler()) ]) pipeline = Pipeline([ ("first_union", first_union), ("second_union", second_union), ("svm", SVC()) ]) pipeline.fit(X_train, y_train) score = pipeline.score(X_test, y_test) |
对于那些需要在机器学习建模过程开始时进行大量预处理的人来说,这是一种极好的方法。
3. 特征聚集
下一个我们将探索的秘密是特征聚集。这是一个来自Scikit-Learn的特征选择方法,但它使用层次聚类来合并相似的特征。
特征聚集是一种降维方法,这意味着当存在许多特征且某些特征彼此高度相关时,它会很有用。它也基于层次聚类,根据我们设定的链接标准和距离度量来合并特征。
让我们通过以下代码看看它是如何工作的。
1 2 3 4 |
from sklearn.cluster import FeatureAgglomeration agglo = FeatureAgglomeration(n_clusters=10) X_reduced = agglo.fit_transform(X) |
我们通过设置聚类数来确定我们想要的特征数量。让我们看看如何将距离度量更改为余弦相似度。
1 |
agglo = FeatureAgglomeration(metric='cosine') |
我们也可以通过以下代码更改链接方法。
1 |
agglo = FeatureAgglomeration(linkage='average') |
然后,我们还可以更改聚合新特征的函数。
1 2 |
import numpy as np agglo = FeatureAgglomeration(pooling_func=np.median) |
尝试实验特征聚集以获取最适合您建模的数据集。
4. 预定义分割
预定义分割是Scikit-Learn中用于自定义交叉验证策略的类。它在训练和测试数据分割期间指定了模式。当我们想要以特定方式分割数据,而标准的K折或分层K折不足时,它是一种有用的方法。
让我们使用下面的代码来尝试预定义分割。
1 2 3 4 5 6 7 8 9 |
from sklearn.model_selection import PredefinedSplit, GridSearchCV # -1 表示训练集,0 表示测试集 test_fold = [-1 if i < 100 else 0 for i in range(len(X))] ps = PredefinedSplit(test_fold) param_grid = {'parameter': [1, 10, 100]} grid_search = GridSearchCV(model, param_grid, cv=ps) grid_search.fit(X, y) |
在上面的例子中,我们通过选择前一百条数据作为训练集,其余作为测试集来设置数据分割模式。
分割策略取决于您的要求。我们可以通过加权过程来更改它。
1 2 3 |
sample_weights = np.random.rand(100) test_fold = [-1 if i < 80 else 0 for i in range(len(X))] ps = PredefinedSplit(test_fold) |
此策略为数据分割过程提供了一种新颖的思路,因此请尝试一下,看看它是否能为您带来好处。
5. Warm Start (暖启动)
您是否训练过一个需要庞大数据集且希望分批训练的机器学习模型?或者您是否在使用需要增量学习的在线学习,利用流式数据?如果您遇到这些情况,您可能不想从头开始重新训练模型。
这时warm start就可以派上用场了。
Warm start是Scikit-Learn模型中的一个参数,它允许我们在再次拟合模型时重用我们上次训练的解决方案。当我们不想从头开始重新训练模型时,此方法很有价值。
例如,下面的代码展示了当我们向模型添加更多树并重新训练它而不从头开始的过程。
1 2 3 4 5 6 7 8 9 |
from sklearn.ensemble import GradientBoostingClassifier # 100棵树 model = GradientBoostingClassifier(n_estimators=100, warm_start=True) model.fit(X_train, y_train) # 添加50棵树 model.n_estimators += 50 model.fit(X_train, y_train) |
通过warm start功能也可以进行分批训练。
1 2 3 4 5 6 7 8 9 |
from sklearn.linear_model import SGDClassifier model = SGDClassifier(max_iter=1000, warm_start=True) # 在第一批数据上训练 model.fit(X_batch_1, y_batch_1) # 在第二批数据上继续训练 model.fit(X_batch_2, y_batch_2) |
尝试使用warm start,这样您就可以始终拥有最佳模型,而不会牺牲训练时间。
6. 增量学习
说到增量学习,我们也可以使用Scikit-Learn来实现。如上所述,增量学习(或在线学习)是一种机器学习训练过程,我们在此过程中顺序地引入新数据。
当我们的数据集很大,或者预计数据会随时间到来时,通常会使用它。当预计数据分布会随时间变化时,也会使用它,因此需要不断地重新训练,但不是从头开始。
在这种情况下,Scikit-Learn中的一些算法通过使用partial_fit方法提供增量学习支持。这将允许模型训练分批进行。
让我们看一个代码示例。
1 2 3 4 5 6 7 |
from sklearn.linear_model import SGDClassifier import numpy as np classes = np.unique(y_train) model = SGDClassifier() for batch_X, batch_y in data_stream: model.partial_fit(batch_X, batch_y, classes=classes) |
只要循环继续,增量学习就会一直运行。
不仅可以对模型训练进行增量学习,也可以对预处理进行增量学习。
1 2 3 4 5 6 |
from sklearn.preprocessing import StandardScaler scaler = StandardScaler() for batch_X, batch_y in data_stream: batch_X = scaler.partial_fit_transform(batch_X) model.partial_fit(batch_X, batch_y, classes=classes) |
如果您的建模需要增量学习,请尝试使用Scikit-Learn的partial_fit方法。
7. 访问实验性功能
并非Scikit-Learn中的所有类和函数都已发布为稳定版本。有些仍处于实验阶段,在使用它们之前我们需要启用它们。
如果我们要启用这些功能,我们需要查看哪些功能仍处于实验阶段,并从Scikit-Learn导入enable_experiment API。
让我们看下面的代码示例。
1 2 3 4 5 |
# 启用实验性功能 from sklearn.experimental import enable_iterative_imputer from sklearn.impute import IterativeImputer imputer = IterativeImputer(random_state=0) |
在撰写本文时,IterativeImputer
类仍处于实验阶段,我们需要在开始使用该类之前导入其启用器。
另一个仍处于实验阶段的功能是halving search方法。
1 2 3 |
from sklearn.experimental import enable_halving_search_cv from sklearn.model_selection import HalvingRandomSearchCV from sklearn.model_selection import HalvingGridSearchCV |
如果您在Scikit-Learn中发现有用的功能但无法访问它们,它们可能处于实验阶段,因此请尝试通过导入启用器来访问它们。
结论
Scikit-Learn是一个在许多机器学习实现中使用的流行库。该库中有如此多的功能,肯定有很多是您不知道的。回顾一下,本文涵盖的七个秘密是:
- 概率校准
- 特征联合
- 特征聚集
- 预定义分割
- Warm Start (暖启动)
- 增量学习
- 访问实验性功能
希望这对您有所帮助!
暂无评论。