当前位置: 首页 > news >正文

11_13小结

总结

  • 数据表示与特征工程:理解连续特征离散特征(分类特征),掌握处理离散变量的方法(One-Hot编码)、连续变量特征分箱(离散化)、单变量非线性变换、自动化特征选择;
  • 模型评估与改进:掌握交叉验证、网格搜索、模型评估指标与评分
  • 算法链与管道:掌握Pipeline的用法、以及在网格搜索中的作用

数据表示与特征工程

分类变量

分类变量的特点是类型之间是互斥的,如果数据特征中有用数字表示分类变量时一定要小心,如果不进行干预,特征很有可能被识别为连续特征。

使用 one-hot 编码(one-hot-encoding)来表示分变量(分类可以是二分类,也可以是多分类)。

在sklearn中,推荐使用OneHotEncoder对分类变量(特征)进行处理。

from sklearn.preprocessing import OneHotEncoderone_hot = OneHotEncoder().fit(df_sub_X)
X_scaled = one_hot.transform(df_sub_X) # 转换后的X_scaled与原df_sub_X有较大差异(特征数会增加)

OneHotEncoder的categorical_features 参数可以指定需要转换的特征列(默认’all’,可以设置一个数组,指定哪几列进行转换)

实际应用中,可以先提取处特征分类集合,然后给集合中的特征值编号(做成字典)。使用模式时先将原数据通过OneHotEncoder实例转换后才能用于模型的predict方法。

分箱

如果过需要将连续特征离散化,可以使用分箱技术(可以参考Pandas中的分箱)。性模型的表现力在数据变换后能得到了极大的提高。

交互特征与多项式特征

丰富特征表示,特别是对于线性模型而言,这种特征工程通常用于统计建模。

始特征的多项式(polynomial)在preprocessing模块的PolynomialFeatures中实现(对线性模型有用,不适用树模型)。如果实际中需要考虑多项式特征时,可以考虑更复杂的模型(如SVM)。

单变量非线性变换

如果在特征和目标之间存在非线性关系,那么建模就变得非常困难,特别是对于回归问题。log 和 exp 函数可以帮助调节数据的相对比例,从而改进线性模型或神经网络的学习效果。

自动化特征选择

在添加新特征或处理一般的高维数据集时,最好将特征的数量减少到只包含最有用的那些特征,并删除其余特征。这样会得到泛化能力更好、更简单的模型。

单变量统计

单变量统计,需要计算每个特征和目标值之间的关系是否存在统计显著性,然后选择具有最高置信度的特征。对于分类问题,这也被称为方差分析(ANOVA)。

在 scikit-learn 中使用单变量特征选择,需要选择一项测试——对分类问题通常是 f_classif(默认值),对回归问题通常是 f_regression——然后基于测试中确定的 p 值来选择一种舍弃特征的方法。可以通过SelectKBest和 SelectPercentile单变量统计,前者选择固定数量的 k 个特征,后者选择固定百分比的特征。

from sklearn.feature_selection import SelectPercentile
from sklearn.feature_selection import SelectKBestselect = SelectPercentile(percentile=50) # 使用f_classif(默认值)和SelectPercentile来选择50%的特征
select.fit(X_train,Y_train)
X_train_selected = select.transform(X_train)select_best = SelectKBest(k=15)
select_best.fit(X_train,Y_train)
X_train_selected = select_best.transform(X_train)

基于模型的特征选择

基于模型的特征选择使用一个监督机器学习模型来判断每个特征的重要性,并且仅保留最重要的特征。想使用基于模型的特征选择,需要使用 SelectFromModel 变换器(使用 RandomForestClassifier 的 SelectFromModel 选择的特征)。

from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import RandomForestClassifierselect = SelectFromModel(RandomForestClassifier(n_estimators=100,random_state=42),threshold='median')# 借助随机深林
select.fit(X_train,Y_train)
X_train_l1 = select.transform(X_train)

迭代特征选择

在迭代特征选择中,构建一系列模型,每个模型都使用不同数量的特征。有两种基本方法:开始时没有特征,然后逐个添加特征,直到满足某个终止条件;或者从所有特征开始,然后逐个删除特征,直到满足某个终止条件。

递归特征消除(recursive feature elimination,RFE),它从所有特征开始构建模型,并根据模型舍弃最不重要的特征,然后使用除被舍弃特征之外的所有特征来构建一个新模型,如此继续,直到仅剩下预设数量的特征。

使用随机森林分类器模型的递归特征消除选择的特征:

from sklearn.feature_selection import RFEselect = RFE(RandomForestClassifier(n_estimators=100,random_state=42),n_features_to_select=40)
select.fit(X_train,Y_train)

模型评估

交叉验证

scikit-learn 是利用 model_selection 模块中的 cross_val_score 函数来实现交叉验证的。cross_val_score 函数的参数是想要评估的模型、训练数据与真实标签。

from sklearn.model_selection import cross_val_scorelogreg = LogisticRegression()
scores = cross_val_score(logreg,iris.data,iris.target,cv=5)

可以通过修改 cv 参数来改变折数。

对交叉验证的更多控制

KFold 分离器类

scikit-learn允许提供一个交叉验证分离器(cross-validation splitter)作为 cv 参数,来对数据划分过程进行更精细的控制。

from sklearn.model_selection import KFoldkfold = KFold(n_splits=3,random_state=42,shuffle=True)

KFold 的shuffle 参数设为 True,表示是将数据打乱来代替分层。还需要固定 random_state 以获得可重复的打乱结果。

LeaveOneOut

可以将留一法交叉验证看作是每折只包含单个样本的 k 折交叉验证。对于每次划分,选择单个数据点作为测试集。

from sklearn.model_selection import LeaveOneOut
ShuffleSplit

打乱划分交叉验证,每次划分为训练集取样 train_size 个点,为测试集取样 test_size 个(不相交的)点。将这一划分方法重复 n_iter 次。

from sklearn.model_selection import ShuffleSplitshuffle_split = ShuffleSplit(test_size=0.5,train_size=0.5,n_splits=10)

乱划分交叉验证可以在训练集和测试集大小之外独立控制迭代次数,它还允许在每次迭代中仅使用部分数据,这可以通过设置 train_size 与 test_size 之和不等于 1 来实现。用这种方法对数据进行二次采样可能对大型数据上的试验很有用。

GroupKFold

分组交叉验证,以 groups 数组作为参数。

from sklearn.model_selection import GroupKFoldX,Y = make_blobs(n_samples=12,random_state=0)
groups = [0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3]

网格搜索

网格搜索的目的是找出提升模型的泛化性能的最优参数。scikit-learn提供了GridSearchCV类,首先需要用一个字典指定要搜索的参数,然后 GridSearchCV 会执行所有必要的模型拟合。字典的键是要调节的参数名称,字典的值是想要尝试的参数设置。

from sklearn.model_selection import GridSearchCVparam_grid={ 'C':[0.001,0.01,0.1,1,10,100], 'gamma':[0.001,0.01,0.1,1,10,100] }
grid_searchcv = GridSearchCV(SVC(),param_grid=param_grid,cv=5)
grid_searchcv.fit(X_train,Y_train)print('best parameters:{}'.format(grid_searchcv.best_params_))
print('best score:{}'.format(grid_searchcv.best_score_))
print('best model:{}'.format(grid_searchcv.best_estimator_ ))

best_score_ 属性保存的是交叉验证的平均精度,是在训练集上进行交叉验证得到的。

best_params_ 属性保存的是最佳参数

best_estimator_ 属性保存的是最佳参数对应的模型

由于 grid_search 本身具有 predict 和 score 方法,所以一般不需要使用 best_estimator_ 来进行预测或评估模型。

在非网格的空间中搜索

在某些情况下,尝试所有参数的所有可能组合并不可靠。例如SVC 有一个 kernel 参数,kernel值不同, C、gamma 可能会失效(如果 kernel=‘linear’,那么模型是线性的,只会用到 C 参数)。这种情况下,GridSearchCV的param_grid可以是字典组成的列表(a list of dictionaries)。列表中的每个字典可扩展为一个独立的网格。包含内核与参数的网格搜索可能如下所示。

param_grid = [{'kernel':['rbf'],'C':[0.001,0.01,0.1,1,10,100],'gamma':[0.001,0.01,0.1,1,10,100]},{'kernel':['linear'],'C':[0.001,0.01,0.1,1,10,100]}]grid_search = GridSearchCV(SVC(),param_grid,cv=5)
grid_search.fit(X_train,Y_train)

RandomizedSearchCV

RandomizedSearchCV 是一种更高效的超参数调优方法,它通过从超参数空间中随机选择一定数量的组合进行评估,从而加速调优过程。

from sklearn.model_selection import RandomizedSearchCVparam_grid =  {'C':[0.001,0.01,0.1,1,10,100],'gamma':[0.001,0.01,0.1,1,10,100],'kernel': ['linear', 'rbf']}
random_search = RandomizedSearchCV(SVC(), param_grid, n_iter=10, cv=5)
random_search.fit(iris.data, iris.target)

评估指标与评分

对于二分类问题,通常会说正类(positive class)和反类(negative class),而正类是要寻找的类。

对于二分类问题的评估结果,一种最全面的表示方法是使用混淆矩阵(confusion matrix)。利用 confusion_matrix 函数来获取结果

from sklearn.metrics import confusion_matrixconfusion = confusion_matrix(Y_test,pred_logreg)
#
# 反类   TN         FP
# 正类   FN         TP
#	 预测为反类  预测为正类

混淆矩阵的结构(混淆矩阵主对角线上的元素对应于正确的分类,而其他元素则告诉我们一个类别中有多少样本被错误地划分到其他类别中)

有几种方法可以总结混淆矩阵中包含的信息:

  • 精度:精度是正确预测的数量(TP 和 TN)除以所有样本的数量 $Accuracy = (TP+TN) / (TP+TN+FP+FN) $
  • 准确率:准确率(precision)度量的是被预测为正例的样本中有多少是真正的正例 P r e c i s i o n = T P / ( T P + F P ) Precision = TP / (TP+FP) Precision=TP/(TP+FP)
  • 召回率:召回率(recall)度量的是正类样本中有多少被预测为正类 R e c a l l = T P / ( T P + F N ) Recall = TP/(TP+FN) Recall=TP/(TP+FN)
  • f-分数:它是准确率与召回率的调和平均 F = 2 ∗ ( p r e c i s i o n ∗ r e c a l l ) / ( p r e c i s i o n + r e c a l l ) F = 2*(precision*recall)/(precision + recall) F=2(precisionrecall)/(precision+recall)

如果目标是限制假正例的数量,那么可以使用准确率作为性能指标。

如果需要找出所有的正类样本,即避免假反例是很重要的情况下,那么可以使用召回率作为性能指标。

如果想要对准确率、召回率和 f1- 分数做一个更全面的总结,可以使用 classification_report 这个很方便的函数,它可以同时计算这三个值:

from sklearn.metrics import classification_report
print(classification_report(Y_test,pred_logreg,target_names=['not nine','nine']))

ROC曲线 与 AUC

  • ROC 曲线:受试者工作特征曲线(receiver operating characteristics curve),简称为 ROC 曲线(ROC curve),ROC 曲线考虑了给定分类器的所有可能的阈值,但它显示的是假正例率(falsepositive rate,FPR)和真正例率(true positive rate,TPR),而不是报告准确率和召回率。
  • AUC:使用一个数字来总结 ROC 曲线,即 ROC 曲线下的面积。 AUC 分数越高,表示模型越好。

可以用 roc_curve 函数来计算 ROC 曲线,以利用 roc_auc_score 函数来计算 ROC 曲线下的面积(通常被称为 AUC)

from sklearn.metrics import roc_curve
from sklearn.metrics import roc_auc_scorefpr,tpr,thresholds = roc_curve(Y_test,svc.decision_function(X_test))plt.plot(fpr,tpr,label='ROC Curve')
plt.xlabel("FPR")
plt.ylabel("TPR(recall)")close_zero = np.argmin(np.abs(thresholds))
plt.plot(fpr[close_zero],tpr[close_zero],'o',label='thresholds zero',fillstyle='none',c='k',mew=1)
plt.legend()svc_auc = roc_auc_score(Y_test,svc.decision_function(X_test))
print("AUC for SVC: {:.3f}".format(svc_auc))

AUC 可以被解释为评估正例样本的排名(ranking)。它等价于从正类样本中随机挑选一个点,由分类器给出的分数比从反类样本中随机挑选一个点的分数更高的概率。因此,AUC 最高为1,这说明所有正类点的分数高于所有反类点。对于不平衡类别的分类问题,使用 AUC 进行模型选择通常比使用精度更有意义

多分类指标

多分类问题的所有指标基本上都来自于二分类指标,但是要对所有类别进行平均。

一般来说,多分类结果比二分类结果更加难以理解。除了精度,常用的工具有混淆矩阵和分类报告。

利用 classification_report 函数,我们可以计算每个类别的准确率、召回率和 f- 分数:

from sklearn.metrics import classification_reportprint(classification_report(Y_test,pred))

对于多分类问题中的不平衡数据集,最常用的指标就是多分类版本的 f- 分数。

使用以下策略之一对这些按类别 f- 分数进行平均:

  • 宏平均:计算未加权的按类别 f- 分数。它对所有类别给出相同的权重,无论类别中的样本量大小。
  • 加权平均:以每个类别的支持作为权重来计算按类别 f- 分数的平均值,分类报告中给出的就是这个值。
  • 微平均:计算所有类别中假正例、假反例和真正例的总数,然后利用这些,计数来计算准确率、召回率和 f- 分数。
from sklearn.metrics import f1_scoreprint("Micro average f1 score: {:.3f}".format(f1_score(Y_test, pred, average="micro")))
print("Macro average f1 score: {:.3f}".format(f1_score(Y_test, pred, average="macro")))

回归指标

对于大多数应用来说,使用默认 R 2 R^2 R2 就足够了,它由所有回归器的 score 方法给出。

在模型选择中使用评估指标

在使用 GridSearchCV 或 cross_val_score 进行模型选择时,可以通过参数scoring指定想要使用的评估指标。

grid = GridSearchCV(SVC(), param_grid=param_grid,scoring='roc_auc')

对于分类问题,scoring 参数最重要的取值包括:accuracy(默认值)、roc_auc(ROC 曲线下方的面积)、average_precision(准确率 - 召回率曲线下方的面积)、f1、f1_macro、f1_micro 和 f1_weighted(这四个是二分类的 f1- 分数以及各种加权变体)。对于回归问题,最常用的取值包括:r2( R 2 R^2 R2分数)、mean_squared_error(均方误差)和 mean_absolute_error(平均绝对误差)。

可以查看 sklearn.metrics模块中定义的 SCORER 字典:

from sklearn.metrics import SCORERS
print("Available scorers:\n{}".format(sorted(SCORERS.keys())))

算法链与管道

在模型中的使用

使用管道可以简化模型操作步骤,用 Pipeline 类来表示在使用 MinMaxScaler 缩放数据之后再训练一个SVM 的工作流程。

from sklearn.svm import SVC
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from sklearn.pipeline import Pipelinepipe = Pipeline([('scaler',MinMaxScaler()),('svm',SVC())]) # 第一个步骤叫作 "scaler",是 MinMaxScaler 的实例;第二个步骤叫作"svm",是 SVC 的实例。
pipe.fit(X_train,Y_train)
print('test score :{:f}'.format(pipe.score(X_test,Y_test)))

利用管道,减少了“预处理 + 分类”过程所需要的代码量。

可以使用make_pipeline创建管道

from sklearn.pipeline import make_pipelinepipe = make_pipeline(MinMaxScaler(),SVC())
# ... 

这两个步骤被命名为 minmaxscaler 和 svc。一般来说,步骤名称只是类名称的小写版本。如果多个步骤属于同一个类,则会附加一个数字。

在网格搜索中的使用

定义一个需要搜索的参数网格,并利用管道和参数网格构建一个 GridSearchCV。在指定参数网格时存在一处细微的变化:参数格式为“步骤名__参数名“。

param_grid = {'svc__C':[0.001, 0.01, 0.1, 1, 10, 100],'svc__gamma':[0.001, 0.01, 0.1, 1, 10, 100]}
grid = GridSearchCV(SVC(),param_grid=param_grid,cv=5)
grid.fit(X_train_scaled,Y_train)

访问网格搜索管道中的属性

最简单的方法是通过 named_steps 属性,它是一个字典,将步骤名称映射为估计器:

pipe = make_pipeline(StandardScaler(),LogisticRegression())
param_grid = {'logisticregression__C':[0.01, 0.1, 1, 10, 100]}
_train,X_test,Y_train,Y_test = train_test_split(cancer.data,cancer.target,random_state=4)
grid = GridSearchCV(pipe,param_grid=param_grid,cv=5)
grid.fit(X_train,Y_train)print("Logistic regression step:\n{}".format(grid.best_estimator_.named_steps["logisticregression"])) # 可以看到最佳参模型
print("Logistic regression step:\n{}".format(grid.best_estimator_.named_steps["logisticregression"].coef_)) # 可以查看LogisticRegression实例属性

网格搜索预处理步骤与模型参数

结合Pipeline与GridSearchCV,搜索最佳参数。

from mglearn.datasets import load_boston
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import Ridgeboston = load_boston()
X_train,X_test,Y_train,Y_test = train_test_split(boston.data,boston.target,random_state=0)
pipe = make_pipeline(StandardScaler(),PolynomialFeatures(),Ridge())param_grid = {'polynomialfeatures__degree':[1,2,3],'ridge__alpha':[0.001, 0.01, 0.1, 1, 10, 100]
}grid = GridSearchCV(pipe,param_grid=param_grid,cv=5,n_jobs=-1)
grid.fit(X_train,Y_train)

网格搜索选择使用哪个模型

classifier 指定模型,结合参数搜索最佳模型

from sklearn.ensemble import RandomForestClassifier# 必须先示例化Pipeline,指定第一个步骤(param_grid的一个参数)
pipe = Pipeline([('preprocessing', StandardScaler()), ('classifier', SVC())])
param_grid = [ {'classifier':[SVC()],'preprocessing':[StandardScaler()],'classifier__gamma':[0.001, 0.01, 0.1, 1, 10, 100],'classifier__C':[0.001, 0.01, 0.1, 1, 10, 100]}, {'classifier':[RandomForestClassifier(n_estimators=100)],'classifier__max_features':[1,2,3]} ]
X_train,X_test,Y_train,Y_test = train_test_split(cancer.data,cancer.target,random_state=0)
grid = GridSearchCV(pipe,param_grid,cv=5,n_jobs=-1)
grid.fit(X_train,Y_train)print("Best params:\n{}\n".format(grid.best_params_))
print("Best cross-validation score: {:.2f}".format(grid.best_score_))
print("Test-set score: {:.2f}".format(grid.score(X_test, Y_test)))
http://www.xdnf.cn/news/1033993.html

相关文章:

  • 每天一个前端小知识 Day 1
  • 迁移数据库服务器和应用服务器步骤
  • Vue3中v-bind=“$attrs“应用实例
  • 最小费用最大流算法
  • 架构下的最终瓶颈:数据库如何破局?
  • ARDM:一款国产跨平台的Redis管理工具
  • React项目常用目录结构
  • 细节致胜:如何重塑反向海淘用户体验
  • MongoDB 事务有哪些限制和注意事项?
  • 系统学习·PHP语言
  • sqli-labs靶场46-53关(综合)
  • c 语言如何将 uint8_t *tg_pFrames的数据给 uint8_t **ppJpg
  • YOLO11中的C3K2模块
  • AORSA关键文件及参数解释
  • Go语言---闭包
  • golang字符串拼接
  • 【MFC 突然被问到,怎么实现一个星星按钮】原来问的是继承xs
  • CTF题目:Apache Flink目录遍历漏洞实战及CVE-2020-17519漏洞分析
  • 标准库转hal库
  • Kafka - 并发消费拉取数据过少故障分析
  • PyTorch张量操作中dim参数的核心原理与应用技巧:
  • 【机械视觉】Halcon—【十三、实例找各个区域面积和中心点】
  • 大模型成长过程-预训练tokenizer
  • 2.5 Rviz使用教程
  • 人工智能学习13-Numpy-规律数组生成
  • pytorch基本运算-梯度运算:requires_grad_(True)和backward()
  • 多个项目的信息流如何统一与整合
  • Spring AI Chat Tool Calling 指南
  • MySQL使用EXPLAIN命令查看SQL的执行计划
  • 13.20 LangChain多链协同架构实战:LanguageMentor实现67%对话连贯性提升