Python机器学习 | 基础教程归纳(下)

此系列文章提炼《Python机器学习基础教程》最核心要点


第四章 数据表示与特征工程

一、分类变量

1、One-Hot编码(虚拟变量)

  • 1)检查字符串编码的分类数据(可能有表示不同但是含义相同的数据:man、male等)
    print(data.gender.value_counts())
    
  • 2)利用get_dummies函数自动变换字符串和分类的列
    data_dummies=pd.get_dummies(data)
    
  • 3)用values属性将DataFrame转化为Numpy数组
    features = data_dummies.loc[:, 'feature_1':'feature_k']
    X = features.values
    y = data_dummies['target_1'].values
    #二分类时target也会变为两列,这个时候调出一列正好是0、1变量
    
  • 4)注意:要在同时含有训练和测试数据的数据集调用get_dummies

2、数字编码的分类变量
用OneHotEncoder或替换时转换为字符串

demo_df['Integer Feature'] = demo_df['Integer Feature'].astype(str)

二、分箱、离散化、线性模型与树

1、具体操作

bins = np.linspace(-3, 3, 11)
#创建-3到3中10个均匀分布的箱子
which_bin = np.digitize(X, bins=bins)
#记录每个数据点所属的箱子

2、特点
一个箱子内所有点,任何模型会预测相同的值
分箱特征提高线性模型性能,决策树模型准确率降低

三、交互特征与多项式特征

1、使用分箱扩展连续特征

  • 1)重新加入原始特征(向分箱数据上的线性模型添加斜率:图中x轴)
    X_combined = np.hstack([X, X_binned])
    reg = LinearRegression().fit(X_combined, y)
    line_combined = np.hstack([line, line_binned])
    reg.predict(line_combined)
    
  • 2)添加交互特征或乘积特征(每个箱子有不同的斜率)
    X_product = np.hstack([X_binned,X* X_binned])
    reg = LinearRegression().fit(X_product, y)
    line_product = np.hstack([line_binned, line*line_binned])
    reg.predict(line_product)
    

2、使用原始特征的多项式

  • 1)具体操作
    from sklearn.preprocessing import PolynomialFeatures
    poly = PolynomialFeatures(degree=10, include_bias=False)
    #直到x**10的多项式,include_bias默认为False则添加恒等于一的常数特征
    poly.fit(X)
    X_poly = poly.transform(X)
    poly.get_feature_names()
    #这一行用来查看获得特征的语义
    
  • 2)多项式回归模型(多项式特征与线性回归一同使用)
    reg = LinearRegression().fit(X_poly, y)
    line_poly = poly.transform(line)
    reg.predict(line_poly)
    

四、单变量非线性变换

log和exp函数可以帮助参数调节数据的相对比例,从而改进线性模型或神经网络的学习效果

X_train_log=np.log(X_train)
X_train_exp=np.exp(X_train)

使用:特征和目标之间存在非线性关系

五、自动化特征选择

1、概述
特征选择的原因:过多的特征会使得模型更为复杂
判断特征作用大小的基本策略:单变量统计、基于模型的选择、迭代选择(都是监督方法)
2、单变量统计

  • 1)概念
    操作:计算每个特征和目标值之间的关系是否存在统计显著性,然后选择具有最高置信度的特征(分类问题——方差分析)
    使用阈值:SelectKBest(选择固定个数k个特征)、SelectPercentile(选择固定百分比的特征)
  • 2)具体操作
    from sklearn.feature_selection import SelectPercentile
    select = SelectPercentile(percentile=50)
    #选择前50%的特征
    select.fit(X_train, y_train)
    X_train_selected = select.transform(X_train)
    
  • 3)可视化技巧
    mask = select.get_support()
    #用get_support查看哪些变量被选中
    print(mask)
    plt.matshow(mask.reshape(1, -1), cmap='gray_r')
    #将遮罩可视化,黑色为True,白色为False
    plt.xlabel("Sample index")
    plt.yticks(())
    

3、基于模型的特征选择

  • 1)概念
    使用一个监督学习模型判断每个特征的重要性
    用特征选择的监督模型不一定和最终监督模型相同
    与单变量选择不同,基于模型的选择同时考虑所有特征(可以获取交互项)
  • 2)具体操作
    • A.使用包含100棵树的随机森林分类器来计算特征重要性
      from sklearn.feature_selection import SelectFromModel
      from sklearn.ensemble import RandomForestClassifier
      select = SelectFromModel(RandomForestClassifier(n_estimators=100, random_state=42),threshold="median")
      
    • B.实际拟合模型
      select.fit(X_train, y_train)
      X_train_l1 = select.transform(X_train)
      
    • C.查看性能
      X_test_l1 = select.transform(X_test)
      score = LogisticRegression().fit(X_train_l1, y_train).score(X_test_l1, y_test)
      print("Test score: {:.3f}".format(score))
      

4、迭代特征选择

  • 1)概念
    构建一系列模型,每个模型使用不同数量的特征
    方法:逐一添加或逐一删除(递归特征消除,RFE)
  • 2)具体操作
    • A.构建模型
      from sklearn.feature_selection import RFE
      select = RFE(RandomForestClassifier(n_estimators=100, random_state=42),n_features_to_select=40)
      select.fit(X_train, y_train)
      
    • B.查看性能
      X_train_rfe = select.transform(X_train)
      X_test_rfe = select.transform(X_test)
      score = LogisticRegression().fit(X_train_rfe, y_train).score(X_test_rfe, y_test)
      print("Test score: {:.3f}".format(score))
      

六、利用专家知识


第五章 模型评估与改进

一、交叉验证

1、概述
交叉验证:评估泛化性能的统计学方法。数据集被多次划分,需要训练多个模型
优点:多次划分:可以看出模型对训练集选择的敏感度
缺点:增加了计算成本
目的:评估给定算法在特定数据集上训练后的泛化性能(不是一种构建可用于新数据模型的方法)

2、基本操作(k折交叉验证)

from sklearn.model_selection import cross_val_score
logreg = LogisticRegression()
scores = cross_val_score(logreg, iris.data, iris.target, cv=5)
#cv:指定交叉验证折数
print("Cross-validation scores: {}".format(scores))

3、分层k折交叉验证(每个折中类别的比例与整个数据集比例相同)

  • 1)kfold交叉验证分离器(可作为cv参数)
    from sklearn.model_selection import KFold
    kfold = KFold(n_splits=3, shuffle=True, random_state=0)
    #shuffle:将数据打乱(可以代替分层,random_state固定以获得可重复的打乱效果)
    print("Cross-validation scores:\n{}".format(cross_val_score(logreg, iris.data, iris.target, cv=kfold)))
    
  • 2)留一法交叉验证(每折只包含单个样本的k折交叉验证)
    from sklearn.model_selection import LeaveOneOut
    loo = LeaveOneOut()
    scores = cross_val_score(logreg, iris.data, iris.target, cv=loo)
    #留一交叉验证中,每次划分单个数据点作为测试集,非常耗时,小数据使用较好
    print("Number of cv iterations: ", len(scores))
    print("Mean accuracy: {:.2f}".format(scores.mean()))
    
  • 3)打乱交叉验证
    from sklearn.model_selection import ShuffleSplit
    shuffle_split = ShuffleSplit(test_size=.5, train_size=.5, n_splits=10)
    #每次划分为训练集取样train_size个点,测试集取样test_size个点,重复n_iter次,每次迭代使用部分数据:train_size+test_size<1​
    scores = cross_val_score(logreg, iris.data, iris.target, cv=shuffle_split)
    print("Cross-validation scores:\n{}".format(scores))
    
  • 4)分组交叉验证(适用于数据分组高度相关,如人脸表情识别,想要泛化到新的人)
    from sklearn.model_selection import GroupKFold
    groups = [0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3]
    scores = cross_val_score(logreg, X, y, groups, cv=GroupKFold(n_splits=3))
    #每次划分中,每个组会整体出现在训练集或测试集中
    print("Cross-validation scores:\n{}".format(scores))
    

二、网格搜索

1、概述
目的:找到一个模型提供最佳泛化性能的参数
简单的编程实现

for gamma in [0.001, 0.01, 0.1, 1, 10, 100]:
for C in [0.001, 0.01, 0.1, 1, 10, 100]:
svm = SVC(gamma=gamma, C=C)
svm.fit(X_train, y_train)
score = svm.score(X_test, y_test)

2、降低参数过拟合风险——验证集

  • 1)两次划分
    X_trainval, X_test, y_trainval, y_test = train_test_split(iris.data, iris.target, random_state=0)
    X_train, X_valid, y_train, y_valid = train_test_split(X_trainval, y_trainval, random_state=1)
    
  • 2)改进核心代码:在验证集上评估模型
    score = svm.score(X_valid, y_valid)
    
  • 3)循环结束后:在训练+验证集上重构模型,在测试集上评估
    svm.fit(X_trainval, y_trainval)
    test_score = svm.score(X_test, y_test)
    

3、带交叉验证的网格搜索

  • 1)改进核心代码:执行交叉验证并计算平均精度
    scores = cross_val_score(svm, X_trainval, y_trainval, cv=5)
    score = np.mean(scores)
    
  • 2)利用sklearn中的估计器
    param_grid = {'C': [0.001, 0.01, 0.1, 1, 10, 100],'gamma': [0.001, 0.01, 0.1, 1, 10, 100]}
    #需要一个字典指定搜索参数
    from sklearn.model_selection import GridSearchCV
    grid_search = GridSearchCV(SVC(), param_grid, cv=5,return_train_score=True)
    grid_search.fit(X_train, y_train)
    #仍需要划分训练测试集
    print("Test set score: {:.2f}".format(grid_search.score(X_test, y_test)))
    #未使用测试集选择参数:best_score_是在训练集上交叉验证得到的,与之前全数据集得到的score不同
    
  • 3)分析结果
    results = pd.DataFrame(grid_search.cv_results_)
    #可考虑用热图可视化​​
    
  • 4)非网格搜索:param_grid可改为字典组成的列表
    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]}]
    

三、评估指标与评分

1、回归指标:使用默认的R^2(由所有回归器的score方法给出)

2、不平和数据集:一个类占据绝大多数

3、二分类指标

  • 1)混淆矩阵
    from sklearn.metrics import confusion_matrix
    confusion = confusion_matrix(y_test, pred_logreg)
    #这里confusion是一个2*2的数组
    
  • 2)评估指标
    • A.准确率:正例中真正正例比例
    • B.召回率:真正正例被预测为正例比例
    • C.F1分数:准确率与召回率的调和平均
    • D.绘制报表
      from sklearn.metrics import classification_report
      print(classification_report(y_test, svc.predict(X_test)))
      
    • E.绘制准确率-召回率曲线
      from sklearn.metrics import precision_recall_curve
      precision, recall, thresholds = precision_recall_curve(y_test, svc.decision_function(X_test))
      plt.plot(precision, recall, label="precision recall curve")
      
    • F.总计曲线:平均准确率(曲线积分面积,返回浮点数)
      from sklearn.metrics import average_precision_score
      ap_svc = average_precision_score(y_test, svc.decision_function(X_test))
      
    • G.ROC曲线(受试者工作特征曲线,假正例率和真正例率)
      from sklearn.metrics import roc_curve
      fpr, tpr, thresholds = roc_curve(y_test, svc.decision_function(X_test))
      plt.plot(fpr, tpr, label="ROC Curve")
      
    • H.总结曲线:曲线下面积(AUC,返回浮点数)
      from sklearn.metrics import roc_auc_score
      svc_auc = roc_auc_score(y_test, svc.decision_function(X_test))
      

4、多分类指标

  • 1)多分类指标的混淆矩阵
  • 2)不平衡数据集:f-分数(多分类版本)
  • 对每个类别计算一个二分类f-分数(其他所有类别都是反类)
  • 使用如下策略对按类别的f-分数进行平均
    • 宏平均:所有类别给出相同权重,无论样本大小
    • 加权平均:每个类别的支持作为权重来计算按类别f-分数平均值
    • 微平均:计算所有类别中FP、FN、TP总数,从而计算准确率、召回率和f-分数
  • 使用方式
    • 对每个样本同等看待:微平均f-分数
      f1_score(y_test, pred, average="micro")
      
    • 对每个类别同等看待:宏平均f-分数
      f1_score(y_test, pred, average="macro")
      

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

  • 目的:在使用GridSearchCV或cross_val_score进行模型选择时使用AUC等指标
  • 方法:scoring参数
    • 交叉验证
      roc_auc =  cross_val_score(SVC(), X, y == 1,scoring="roc_auc")
      #分类问题默认就是‘accuracy’(准确率),可以改为‘roc_auc’(AUC)
      
    • 网格搜索
      grid = GridSearchCV(SVC(), param_grid=param_grid, scoring="roc_auc")
      #与上同理
      
  • 常用的是scoring参数
    • 分类问题
      • 准确率(accuracy)
      • ROC曲线下面积(roc_auc)
      • 准确率-召回率曲线下面积(average_precision)
      • 四个二分类f1分数及加权变体(f1, f1_macro, f1_micro, f1_weighted)
    • 回归问题
      • R^2分数(r2)
      • 均方误差(mean_squared_error)
      • 平均绝对误差(mean_absolute_error)

四、小结

数据划分:训练集-训练模型;验证集-选择模型与参数;测试集-模型评估
明确机器学习的最终目的:确保用于模型评估与选择的指标能够很好地替代模型的实际用途


第六章 算法链与管道

一、用预处理进行参数选择

  • 引入:在进行任何预处理之前完成数据集的划分(交叉验证位于处理过程的最外层循环)
  • Pipeline类
    将多个处理步骤合并(glue)为单个估计器
    本身具有fit、predict和score方法
    最常见:将预处理步骤(如缩放)与一个监督模型(如分类器)连接在一起

二、构建管道

from sklearn.pipeline import Pipeline
pipe=Pipeline([("scaler", MinMaxScaler()), ("svm",SVC())])
#创建了两个步骤,第一个叫scaler,是MinMaxScaler的实例,第二个叫svm,是SVC()的实例
pipe.fit(X_train, y_train)
#拟合管道
print("Test score: {:.2f}".format(pipe.score(X_test, y_test)))
#直接用管道的score方法进行评估

三、在网格搜索中使用管道

param_grid = {'svm__C': [0.001, 0.01, 0.1, 1, 10, 100],'svm__gamma': [0.001, 0.01, 0.1, 1, 10, 100]}
#为网格定义参数网络:步骤名称+双下划线+参数名称
grid = GridSearchCV(pipe, param_grid=param_grid, cv=5)
grid.fit(X_train, y_train)
#现在可以仅适用训练部分进行MinMaxScaler拟合,验证和测试集都没有变化,因此测试部分的信息不会泄露到参数搜索中
print("Best cross-validation accuracy: {:.2f}".format(grid.best_score_))
print("Test set score: {:.2f}".format(grid.score(X_test, y_test)))
print("Best parameters: {}".format(grid.best_params_))

四、通用的管道接口

1、用make_pipeline方便地创建管道

pipe_short = make_pipeline(MinMaxScaler(), SVC(C=100))
区别:会自动制定步骤名称,名称在step属性中

2、利用named_steps访问步骤属性

components = pipe.named_steps["pca"].components_

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

print("Best estimator:\n{}".format(grid.best_estimator_))
#访问GridSearchCV找到的最佳LogisticRegression模型的系数
print("Logistic regression coefficients:\n{}".format(grid.best_estimator_.named_steps["logisticregression"].coef_))
#访问每个输入特征相关权重

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

1、目的:使用监督任务的输出调节预处理参数

from sklearn.preprocessing import PolynomialFeatures
pipe = make_pipeline(StandardScaler(),PolynomialFeatures(),Ridge())
#缩放数据、计算多项式特征和岭回归放在同一个pipe里
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)

2、Tips:用热图将交叉验证结果可视化

plt.matshow(grid.cv_results_['mean_test_score'].reshape(3,-1),vmin=0,cmap='viridis')
plt.xlabel('ridge__alpha')
plt.ylabel('polynomialfeatures__degree')
plt.xticks(range(len(param_grid['ridge__alpha'])),param_grid['ridge__alpha'])
plt.yticks(range(len(param_grid['polynomialfeatures__degree'])),param_grid['polynomialfeatures__degree'])
plt.colorbar()

3、查看最佳模型和对应分数

print("Best parameters: {}".format(grid.best_params_))
print("Test-set score: {:.2f}".format(grid.score(X_test, y_test)))

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

使用搜索网格列表,跳过步骤(如random forest不需要预处理)则设置为None

param_grid = [{'classifier': [SVC()], 'preprocessing': [StandardScaler(), None],'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)],'preprocessing': [None], 'classifier__max_features': [1, 2, 3]}]

网格如此定义,其余同理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值