第二章:机器学习基础

1 导论

 机器学习的一个重要的目标就是利用数学模型来理解数据,发现数据中的规律,用作数据的分析和预测。

根据数据是否有因变量,机器学习的任务可分为:有监督学习无监督学习

根据因变量的是否连续,有监督学习又分为回归分类

# 引入相关科学计算包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline 
plt.style.use("ggplot")      
import seaborn as sns

1.1 回归

例子:使用sklearn内置数据集Boston房价数据集

from sklearn import datasets
boston = datasets.load_boston()     # 返回一个类似于字典的类
X = boston.data
y = boston.target
features = boston.feature_names
boston_data = pd.DataFrame(X,columns=features) # DataFrame将数组转化为表格型数据结构,加列名
boston_data["Price"] = y
boston_data.head()
sns.scatterplot(boston_data['NOX'],boston_data['Price'],color="r",alpha=0.6)
plt.title("Price~NOX")
plt.show()

1.2 分类

例子:使用iris数据集

from sklearn import datasets
iris = datasets.load_iris()
X = iris.data
y = iris.target
features = iris.feature_names
iris_data = pd.DataFrame(X,columns=features)
iris_data['target'] = y
iris_data.head()
# 可视化特征
marker = ['s','x','o']
for index,c in enumerate(np.unique(y)):
    plt.scatter(x=iris_data.loc[y==c,"sepal length (cm)"],y=iris_data.loc[y==c,"sepal width (cm)"],alpha=0.8,label=c,marker=marker[c]) # loc()函数按索引取数据,先行后列
plt.xlabel("sepal length (cm)")
plt.ylabel("sepal width (cm)")
plt.legend()
plt.show()

1.3 无监督学习

# 生成月牙型非凸集
from sklearn import datasets
x, y = datasets.make_moons(n_samples=2000, shuffle=True,
                  noise=0.05, random_state=None)
for index,c in enumerate(np.unique(y)):
    plt.scatter(x[y==c,0],x[y==c,1],s=7)
plt.show()
# 生成符合正态分布的聚类数据
from sklearn import datasets
x, y = datasets.make_blobs(n_samples=5000, n_features=2, centers=3)
for index,c in enumerate(np.unique(y)):
    plt.scatter(x[y==c, 0], x[y==c, 1],s=7)
plt.show()

2 使用sklearn构建完整的机器学习项目流程

一般来说,一个完整的机器学习项目分为以下步骤:

明确项目任务:回归/分类
收集数据集并选择合适的特征。
选择度量模型性能的指标。
选择具体的模型并进行训练以优化模型。
评估模型的性能并调参。

2.1 使用sklearn构建完整的回归项目

step 1:收集数据集并选择合适的特征

from sklearn import datasets
boston = datasets.load_boston()     # 返回一个类似于字典的类
X = boston.data
y = boston.target
features = boston.feature_names
boston_data = pd.DataFrame(X,columns=features)
boston_data["Price"] = y
boston_data.head()

step 2:选择度量模型性能的指标

(1)MSE均方误差

(2)MAE平均绝对误差

(3)R2决定系数

(4)解释方差得分

在这个案例中,我们使用MSE均方误差为模型的性能度量指标。

step 3:选择具体的模型并进行训练

(1)线性回归模型

线性回归假设目标值与特征之间线性相关,即满足一个多元一次方程。

最小二乘估计:衡量真实值与线性回归模型的预测值之间的差距,在这里我们和使用二范数的平方和来描述这种差距。

\omega =(X^{T}X)^{-1}X^{T}Y

几何解释:X^{T}(Y-X\omega )=0

概率视角:线性回归的最小二乘估计\Leftrightarrow噪声 \varepsilon \sim N(0,\sigma ^{2})的极大似然估计

使用sklearn的线性回归实例来演示

from sklearn import linear_model      # 引入线性回归方法
lin_reg = linear_model.LinearRegression()       # 创建线性回归的类
lin_reg.fit(X,y)        # 输入特征X和因变量y进行训练
print("模型系数:",lin_reg.coef_)             # 输出模型的系数
print("模型得分:",lin_reg.score(X,y))    # 输出模型的决定系数R^2

(2)线性回归推广

推广的目的:表达非线性的关系

多项式回归:阶数越大,曲线越光滑,但不宜过大,在边界处有异常波动,预测稳定性下降

 广义可加模型(GAM):每一个变量都用一个非线性函数来代替,但是模型本身保持整体可加性。

## 多项式回归实例介绍

#参数:
#degree:特征转换的阶数。
#interaction_onlyboolean:是否只包含交互项,默认False 。
#include_bias:是否包含截距项,默认True。
#order:str in {‘C’, ‘F’}, default ‘C’,输出数组的顺序。

from sklearn.preprocessing import PolynomialFeatures
X_arr = np.arange(6).reshape(3, 2)
print("原始X为:\n",X_arr)

poly = PolynomialFeatures(2)
print("2次转化X:\n",poly.fit_transform(X_arr))

poly = PolynomialFeatures(interaction_only=True)
print("2次转化X:\n",poly.fit_transform(X_arr))
## GAM模型实例介绍

#安装pygam:pip install pygam

from pygam import LinearGAM
gam = LinearGAM().fit(boston_data[boston.feature_names], y)
gam.summary()

(3)回归树

依据分层和分割的方式将特征空间划分为一系列简单的区域。对某个给定的待预测的自变量,用他所属区域中训练集的平均数或者众数对其进行预测。

结点有两种类型:内部结点(internal node)和叶结点(leaf node)。内部结点表示一个特征或属性,叶结点表示一个类别或者某个值。

建立回归树的过程大致可以分为以下步骤:

(a)选择最优切分特征j以及该特征上的最优点s

(b)按照(j,s)分裂特征空间

(c)继续调用步骤1,2直到满足停止条件,就是每个区域的样本数小于等于5

(d)将特征空间划分为J个不同的区域,生成回归树

回归树与线性模型的比较:

  • 如果特征变量与因变量的关系能很好的用线性关系来表达,那么线性回归通常有着不错的预测效果,拟合效果则优于不能揭示线性结构的回归树。
  • 如果特征变量与因变量的关系呈现高度复杂的非线性,那么树方法比传统方法更优。

树模型的优缺点:

  • 树模型的解释性强,在解释性方面可能比线性回归还要方便。
  • 树模型更接近人的决策方式。
  • 树模型可以用图来表示,非专业人士也可以轻松解读。
  • 树模型可以直接做定性的特征而不需要像线性回归一样哑元化。
  • 树模型能很好处理缺失值和异常值,对异常值不敏感,但是这个对线性模型来说却是致命的。
  • 树模型的预测准确性一般无法达到其他回归模型的水平,但是改进的方法很多。
## sklearn使用回归树的实例

#参数:(列举几个重要的,常用的,详情请看上面的官网)
#criterion:{“ mse”,“ friedman_mse”,“ mae”},默认=“ mse”。衡量分割标准的函数 。
#splitter:{“best”, “random”}, default=”best”。分割方式。
#max_depth:树的最大深度。
#min_samples_split:拆分内部节点所需的最少样本数,默认是2。
#min_samples_leaf:在叶节点处需要的最小样本数。默认是1。
#min_weight_fraction_leaf:在所有叶节点处(所有输入样本)的权重总和中的最小加权分数。如果未提供#sample_weight,则样本的权重相等。默认是0。

from sklearn.tree import DecisionTreeRegressor    
reg_tree = DecisionTreeRegressor(criterion = "mse",min_samples_leaf = 5)
reg_tree.fit(X,y)
reg_tree.score(X,y)

(4)支持向量机回归(SVR)

约束优化问题(P)

KKT条件(最优解的一阶必要条件):

  • 用于求解带有等式和不等式约束的优化问题,是拉格朗日乘数法的推广。
  • 给出了这类问题取得极值的一阶必要条件。
  • 如果一个最优化问题是凸优化问题,则KKT条件是取得极小值的充分条件。

对偶理论:任何一个原问题在变成对偶问题后都会变成一个凸优化的问题

SVR认为:落在𝑓(𝑥)的ϵ邻域空间中的样本点不需要计算损失,这些都是预测正确的,其余的落在ϵ邻域空间以外的样本才需要计算损失。

## sklearn中使用SVR实例

#参数:
#kernel:核函数,{‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’}, 默认=’rbf’。(后面会详细介绍)
#degree:多项式核函数的阶数。默认 = 3。
#C:正则化参数,默认=1.0。(后面会详细介绍)
#epsilon:SVR模型允许的不计算误差的邻域大小。默认0.1。

from sklearn.svm import SVR
from sklearn.preprocessing import StandardScaler     # 标准化数据
from sklearn.pipeline import make_pipeline   # 使用管道,把预处理和模型形成一个流程

reg_svr = make_pipeline(StandardScaler(), SVR(C=1.0, epsilon=0.2))
reg_svr.fit(X, y)
reg_svr.score(X,y)

step 4:优化基础模型

在回归问题中使用训练集估计模型的参数的原则一般都是使得我们的损失函数在训练集达到最小值,其实在实际问题中我们是可以让损失函数在训练集最小化为0。

(a) 训练均方误差与测试均方误差:模型在训练误差很小,但是测试均方误差很大时,我们称这种情况叫模型的过拟合

(b) 偏差-方差的权衡:

  • 测试均方误差的期望值可以分解为\hat{f(x_{0})}的方差、\hat{f(x_{0})}的偏差平方和误差项ϵ的方差。
  • 模型的方差就是:用不同的数据集去估计𝑓f时,估计函数的改变量。
  • 一般来说,模型的复杂度越高,f的方差就会越大。
  • 模型的偏差是指:为了选择一个简单的模型去估计真实函数所带入的误差。
  • 偏差度量了学习算法的期望预测与真实结果的偏离程度,即刻画了学习算法本身的拟合能力。
  • 偏差度量的是单个模型的学习能力,而方差度量的是同一个模型在不同数据集上的稳定性。
  • “偏差-方差分解”说明:泛化性能是由学习算法的能力、数据的充分性以及学习任务本身的难度所共同决定的。
  • 模型越复杂,训练误差越小,测试误差先减后增。

(c) 特征提取

对测试误差进行估计,估计的方式有两种:训练误差修正与交叉验证。

训练误差修正:对测试误差的间接估计,加入关于特征个数的惩罚

  • 先构造一个特征较多的模型使其过拟合,此时训练误差很小而测试误差很大,那这时我们加入关于特征个数的惩罚。
  • 当我们的训练误差随着特征个数的增加而减少时,惩罚项因为特征数量的增加而增大,抑制了训练误差随着特征个数的增加而无休止地减小。
  • AIC赤池信息量准则
  • BIC贝叶斯信息量准则

交叉验证:对测试误差的直接估计。交叉验证比训练误差修正的优势在于:能够给出测试误差的一个直接估计。

特征选择的目标就是:从p个特征中选择m个特征,使得对应的模型的测试误差的估计最小。

  • 最优子集选择
  • 向前逐步选择
## 特征提取的实例:向前逐步回归
## 根据AIC准则定义向前逐步回归进行变量筛选

#定义向前逐步回归函数
def forward_select(data,target):
    variate=set(data.columns)  #将字段名转换成字典类型
    variate.remove(target)  #去掉因变量的字段名
    selected=[]
    current_score,best_new_score=float('inf'),float('inf')  #目前的分数和最好分数初始值都为无穷大(因为AIC越小越好)
    #循环筛选变量
    while variate:
        aic_with_variate=[]
        for candidate in variate:  #逐个遍历自变量
            formula="{}~{}".format(target,"+".join(selected+[candidate]))  #将自变量名连接起来
            aic=ols(formula=formula,data=data).fit().aic  #利用ols训练模型得出aic值
            aic_with_variate.append((aic,candidate))  #将第每一次的aic值放进空列表
        aic_with_variate.sort(reverse=True)  #降序排序aic值
        best_new_score,best_candidate=aic_with_variate.pop()  #最好的aic值等于删除列表的最后一个值,以及最好的自变量等于列表最后一个自变量
        if current_score>best_new_score:  #如果目前的aic值大于最好的aic值
            variate.remove(best_candidate)  #移除加进来的变量名,即第二次循环时,不考虑此自变量了
            selected.append(best_candidate)  #将此自变量作为加进模型中的自变量
            current_score=best_new_score  #最新的分数等于最好的分数
            print("aic is {},continuing!".format(current_score))  #输出最小的aic值
        else:
            print("for selection over!")
            break
    formula="{}~{}".format(target,"+".join(selected))  #最终的模型式子
    print("final formula is {}".format(formula))
    model=ols(formula=formula,data=data).fit()
    return(model)
import statsmodels.api as sm #最小二乘
from statsmodels.formula.api import ols #加载ols模型
forward_select(data=boston_data,target="Price")
lm=ols("Price~LSTAT+RM+PTRATIO+DIS+NOX+CHAS+B+ZN+CRIM+RAD+TAX",data=boston_data).fit()
lm.summary()

(d) 压缩估计(正则化)

对回归的系数进行约束或者加罚的技巧对p个特征的模型进行拟合,显著降低模型方差,这样也会提高模型的拟合效果。

具体来说,就是将回归系数往零的方向压缩,这也就是为什么叫压缩估计的原因了。

  • 岭回归(L2正则化的例子):通过牺牲线性回归的无偏性降低方差,有可能使得模型整体的测试误差较小,提高模型的泛化能力。
  • Lasso回归(L1正则化的例子):能做到特征选择
## 岭回归实例分享

#参数:
#alpha:较大的值表示更强的正则化。浮点数
#sample_weight:样本权重,默认无。
#solver:求解方法,{‘auto’, ‘svd’, ‘cholesky’, ‘lsqr’, ‘sparse_cg’, ‘sag’, ‘saga’}, 默认=’auto’。“ svd”使用X的奇异值分解来计算Ridge系数。'cholesky'使用标准的scipy.linalg.solve函数通过dot(XT,X)的Cholesky分解获得封闭形式的解。'sparse_cg'使用scipy.sparse.linalg.cg中的共轭梯度求解器。作为一种迭代算法,对于大规模数据(可能设置tol和max_iter),此求解器比“ Cholesky”更合适。 lsqr”使用专用的正则化最小二乘例程scipy.sparse.linalg.lsqr。它是最快的,并且使用迭代过程。“ sag”使用随机平均梯度下降,“ saga”使用其改进的无偏版本SAGA。两种方法都使用迭代过程,并且当n_samples和n_features都很大时,通常比其他求解器更快。请注意,只有在比例大致相同的要素上才能确保“ sag”和“ saga”快速收敛。您可以使用sklearn.preprocessing中的缩放器对数据进行预处理。最后五个求解器均支持密集和稀疏数据。但是,当fit_intercept为True时,仅'sag'和'sparse_cg'支持稀疏输入。

from sklearn import linear_model
reg_rid = linear_model.Ridge(alpha=.5)
reg_rid.fit(X,y)
reg_rid.score(X,y)
## Lasso实例分享

#参数:
#alpha:正则化强度,1.0代表标准最小二乘。
#fit_intercept:是否计算模型截距。默认true。
#normalize:是否标准化,默认false。
#positive:是否强制系数为正,默认false。

from sklearn import linear_model
reg_lasso = linear_model.Lasso(alpha = 0.5)
reg_lasso.fit(X,y)
reg_lasso.score(X,y)

(e) 降维

将原始的特征空间投影到一个低维的空间实现变量的数量变少。

主成分分析(PCA):通过最大投影方差 将原始空间进行重构,即由特征相关重构为无关,即落在某个方向上的点(投影)的方差最大。

step 5:对模型超参数进行调优

参数与超参数:

  • 模型参数是模型内部的配置变量,其值可以根据数据进行估计;
  • 超参数通常用于帮助估计模型参数。

网格搜索GridSearchCV()

  • 暴力地从参数空间中每个都尝试一遍,然后选择最优的那组参数

随机搜索 RandomizedSearchCV() 

下面我们使用SVR的例子,结合管道来进行调优:

# 我们先来对未调参的SVR进行评价: 
from sklearn.svm import SVR     # 引入SVR类
from sklearn.pipeline import make_pipeline   # 引入管道简化学习流程
from sklearn.preprocessing import StandardScaler # 由于SVR基于距离计算,引入对数据进行标准化的类
from sklearn.model_selection import GridSearchCV  # 引入网格搜索调优
from sklearn.model_selection import cross_val_score # 引入K折交叉验证
from sklearn import datasets


boston = datasets.load_boston()     # 返回一个类似于字典的类
X = boston.data
y = boston.target
features = boston.feature_names
pipe_SVR = make_pipeline(StandardScaler(),
                                                         SVR())
score1 = cross_val_score(estimator=pipe_SVR,
                                                     X = X,
                                                     y = y,
                                                     scoring = 'r2',
                                                      cv = 10)       # 10折交叉验证
print("CV accuracy: %.3f +/- %.3f" % ((np.mean(score1)),np.std(score1)))
# 下面我们使用网格搜索来对SVR调参:
from sklearn.pipeline import Pipeline
pipe_svr = Pipeline([("StandardScaler",StandardScaler()),
                                                         ("svr",SVR())])
param_range = [0.0001,0.001,0.01,0.1,1.0,10.0,100.0,1000.0]
param_grid = [{"svr__C":param_range,"svr__kernel":["linear"]},  # 注意__是指两个下划线,一个下划线会报错的
                            {"svr__C":param_range,"svr__gamma":param_range,"svr__kernel":["rbf"]}]
gs = GridSearchCV(estimator=pipe_svr,
                                                     param_grid = param_grid,
                                                     scoring = 'r2',
                                                      cv = 10)       # 10折交叉验证
gs = gs.fit(X,y)
print("网格搜索最优得分:",gs.best_score_)
print("网格搜索最优参数组合:\n",gs.best_params_)
# 下面我们使用随机搜索来对SVR调参:
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import uniform  # 引入均匀分布设置参数
pipe_svr = Pipeline([("StandardScaler",StandardScaler()),
                                                         ("svr",SVR())])
distributions = dict(svr__C=uniform(loc=1.0, scale=4),    # 构建连续参数的分布
                     svr__kernel=["linear","rbf"],                                   # 离散参数的集合
                    svr__gamma=uniform(loc=0, scale=4))

rs = RandomizedSearchCV(estimator=pipe_svr,
                                                     param_distributions = distributions,
                                                     scoring = 'r2',
                                                      cv = 10)       # 10折交叉验证
rs = rs.fit(X,y)
print("随机搜索最优得分:",rs.best_score_)
print("随机搜索最优参数组合:\n",rs.best_params_)

2.2 使用sklearn构建完整的分类项目

step 1:收集数据集并选择合适特征

from sklearn import datasets
iris = datasets.load_iris()
X = iris.data
y = iris.target
feature = iris.feature_names
data = pd.DataFrame(X,columns=feature)
data['target'] = y
data.head()

step 2:选择度量模型性能的指标

  • 真阳性TP:预测值和真实值都为正例;
  • 真阴性TN:预测值与真实值都为正例;
  • 假阳性FP:预测值为正,实际值为负;
  • 假阴性FN:预测值为负,实际值为正;

分类模型的指标:

  • 准确率:分类正确的样本数占总样本的比例
  • 精度:预测为正且分类正确的样本占预测值为正的比例
  • 召回率:预测为正且分类正确的样本占类别为正的比例
  • F1值:综合衡量精度和召回率
  • ROC曲线:以假阳率为横轴,真阳率为纵轴画出来的曲线,曲线下方面积越大越好。

在本次小案例中,我们使用ROC曲线作为最终评价指标。

step 3:选择具体的模型并进行训练

(1)逻辑回归logistic regression

(2)线性判别分析

  • 基于贝叶斯公式对线性判别分析的理解:通过贝叶斯定理计算贝叶斯定理的分子,比较分子最大的那个类别为最终类别。
  • 降维分类的思想理解线性判别分析:将高维的数据降维至一维,然后使用某个阈值将各个类别分开。

(3)朴素贝叶斯

  • 朴素贝叶斯算法对线性判别分析作进一步的模型简化,它将线性判别分析中的协方差矩阵中的协方差全部变成0,只保留各自特征的方差。
  • 朴素贝叶斯假设各个特征之间是不相关的。
  • 朴素贝叶斯比线性判别分析模型的方差小,偏差大。
#  逻辑回归
'''
penalty       {‘l1’, ‘l2’, ‘elasticnet’, ‘none’}, default=’l2’正则化方式
dual      bool, default=False   是否使用对偶形式,当n_samples> n_features时,默认dual = False。   
C        float, default=1.0      
solver       {‘newton-cg’, ‘lbfgs’, ‘liblinear’, ‘sag’, ‘saga’}, default=’lbfgs’     
l1_ratio         float, default=None           
'''
from sklearn.linear_model import LogisticRegression
log_iris = LogisticRegression()
log_iris.fit(X,y)
log_iris.score(X,y)
# 线性判别分析
'''
参数:
solver:{'svd','lsqr','eigen'},默认='svd'
solver的使用,可能的值:
'svd':奇异值分解(默认)。不计算协方差矩阵,因此建议将此求解器用于具有大量特征的数据。

'lsqr':最小二乘解,可以与收缩结合使用。

'eigen':特征值分解,可以与收缩结合使用。
'''
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
lda_iris = LinearDiscriminantAnalysis()
lda_iris.fit(X,y)
lda_iris.score(X,y)
# 朴素贝叶斯             
from sklearn.naive_bayes import GaussianNB
NB_iris = GaussianNB()
NB_iris.fit(X, y)
NB_iris.score(X,y)

(4)决策树

选择分割点的标准:

  • 基尼系数:衡量的是K个类别的总方差
  • 交叉熵:和基尼系数一样,如果第m个结点的纯度越高,则交叉熵越小。

决策树分类算法的完整步骤:
(a)选择最优切分特征j以及该特征上的最优点s
(b) 按照(j,s)分裂特征空间,每个区域内的类别为该区域内样本比例最多的类别。
(c) 继续调用步骤1,2直到满足停止条件,就是每个区域的样本数小于等于5。
(d) 将特征空间划分为J个不同的区域,生成分类树。

# 使用决策树算法对iris分类:
'''
criterion:{“gini”, “entropy”}, default=”gini”
max_depth:树的最大深度。
min_samples_split:拆分内部节点所需的最少样本数
min_samples_leaf :在叶节点处需要的最小样本数。

'''
from sklearn.tree import DecisionTreeClassifier
tree_iris = DecisionTreeClassifier(min_samples_leaf=5)
tree_iris.fit(X,y)
tree_iris.score(X,y)

(5)支持向量机SVM

找到一个分割平面将两个类别分开。通常来说,如果数据本身是线性可分的,那么事实上存在无数个这样的超平面。这是因为给定一个分割平面稍微上移下移或旋转这个超平面,只要不接触这些观测点,仍然可以将数据分开。一个很自然的想法就是找到最大间隔超平面,即找到一个分割平面距离最近的观测点最远。

(6)非线性支持向量机

处理非线性问题:将数据投影至更加高的维度!

核函数的计算是在低维特征空间来计算的,它避免了在高维维度空间计算内积的恐怖计算量

下面介绍几种常用的核函数:

  • 多项式核函数
  • 高斯核函数
  • Sigmoid核函数
  • 余弦相似度核
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
'''
C:正则化参数。正则化的强度与C成反比。必须严格为正。惩罚是平方的l2惩罚。
kernel:{'linear','poly','rbf','sigmoid','precomputed'},默认='rbf'
degree:多项式和的阶数
gamma:“ rbf”,“ poly”和“ Sigmoid”的内核系数。
shrinking:是否软间隔分类,默认true

'''
svc_iris = make_pipeline(StandardScaler(), SVC(gamma='auto'))
svc_iris.fit(X, y)
svc_iris.score(X,y)

step 4:评估模型的性能并调参

# 使用网格搜索进行超参数调优:
# 方式1:网格搜索GridSearchCV()
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
import time

start_time = time.time()
pipe_svc = make_pipeline(StandardScaler(),SVC(random_state=1))
param_range = [0.0001,0.001,0.01,0.1,1.0,10.0,100.0,1000.0]
param_grid = [{'svc__C':param_range,'svc__kernel':['linear']},{'svc__C':param_range,'svc__gamma':param_range,'svc__kernel':['rbf']}]
gs = GridSearchCV(estimator=pipe_svc,param_grid=param_grid,scoring='accuracy',cv=10,n_jobs=-1)
gs = gs.fit(X,y)
end_time = time.time()
print("网格搜索经历时间:%.3f S" % float(end_time-start_time))
print(gs.best_score_)
print(gs.best_params_)
# 方式2:随机网格搜索RandomizedSearchCV()
from sklearn.model_selection import RandomizedSearchCV
from sklearn.svm import SVC
import time

start_time = time.time()
pipe_svc = make_pipeline(StandardScaler(),SVC(random_state=1))
param_range = [0.0001,0.001,0.01,0.1,1.0,10.0,100.0,1000.0]
param_grid = [{'svc__C':param_range,'svc__kernel':['linear']},{'svc__C':param_range,'svc__gamma':param_range,'svc__kernel':['rbf']}]
# param_grid = [{'svc__C':param_range,'svc__kernel':['linear','rbf'],'svc__gamma':param_range}]
gs = RandomizedSearchCV(estimator=pipe_svc, param_distributions=param_grid,scoring='accuracy',cv=10,n_jobs=-1)
gs = gs.fit(X,y)
end_time = time.time()
print("随机网格搜索经历时间:%.3f S" % float(end_time-start_time))
print(gs.best_score_)
print(gs.best_params_)

当类别为两类时,可以绘制混淆矩阵与ROC曲线

# 混淆矩阵:
# 加载数据
df = pd.read_csv("http://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/wdbc.data",header=None)
'''
乳腺癌数据集:569个恶性和良性肿瘤细胞的样本,M为恶性,B为良性
'''
# 做基本的数据预处理
from sklearn.preprocessing import LabelEncoder

X = df.iloc[:,2:].values
y = df.iloc[:,1].values
le = LabelEncoder()    #将M-B等字符串编码成计算机能识别的0-1
y = le.fit_transform(y)
le.transform(['M','B'])
# 数据切分8:2
from sklearn.model_selection import train_test_split

X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,stratify=y,random_state=1)
from sklearn.svm import SVC
pipe_svc = make_pipeline(StandardScaler(),SVC(random_state=1))
from sklearn.metrics import confusion_matrix

pipe_svc.fit(X_train,y_train)
y_pred = pipe_svc.predict(X_test)
confmat = confusion_matrix(y_true=y_test,y_pred=y_pred)
fig,ax = plt.subplots(figsize=(2.5,2.5))
ax.matshow(confmat, cmap=plt.cm.Blues,alpha=0.3)
for i in range(confmat.shape[0]):
    for j in range(confmat.shape[1]):
        ax.text(x=j,y=i,s=confmat[i,j],va='center',ha='center')
plt.xlabel('predicted label')
plt.ylabel('true label')
plt.show()
# 绘制ROC曲线:
from sklearn.metrics import roc_curve,auc
from sklearn.metrics import make_scorer,f1_score
scorer = make_scorer(f1_score,pos_label=0)
gs = GridSearchCV(estimator=pipe_svc,param_grid=param_grid,scoring=scorer,cv=10)
y_pred = gs.fit(X_train,y_train).decision_function(X_test)
#y_pred = gs.predict(X_test)
fpr,tpr,threshold = roc_curve(y_test, y_pred) ###计算真阳率和假阳率
roc_auc = auc(fpr,tpr) ###计算auc的值
plt.figure()
lw = 2
plt.figure(figsize=(7,5))
plt.plot(fpr, tpr, color='darkorange',
         lw=lw, label='ROC curve (area = %0.2f)' % roc_auc) ###假阳率为横坐标,真阳率为纵坐标做曲线
plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
plt.xlim([-0.05, 1.0])
plt.ylim([-0.05, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic ')
plt.legend(loc="lower right")
plt.show()

作业01

(1)请详细阐述线性回归模型的最大二乘法表达

(2)在线性回归模型中,极大似然估计与最小二乘估计有什么联系与区别

(3)为什么多项式回归在实际问题中的表现经常不是很好?

(4)决策树模型与线性模型之间的联系与区别

(5)什么是KKT条件?

(6)为什么要引入原问题的对偶问题?

(7)使用机器学习数学基础所学的内容,找到一个具体的数据集,使用线性回归模型拟合模型。

作业02

(1)请用一个具体的案例解释什么是偏差和方差

(2)偏差与方差和误差之间的关系

(3)训练误差与测试误差之间的联系和区别,如何估计测试误差

(4)岭回归和套索回归的异同点

(5)如果使用pca降维前是一个三维的椭球,那么把该图形降维成二维是一个什么样的图形

(6)尝试使用对偶理论和核函数对pca进行非线性拓展,使得pca变成非线性降维

(7)本教程讲述的三种模型简化的方法之间有什么异同点

(8)尝试使用sklearn对一组数据进行特征简化,再使用回归模型,最后使用网格搜索调参,观察不同方法的优劣。

作业03

(1)回归问题和分类问题的联系和区别,如何利用回归问题理解分类问题?

(2)为什么分类问题的损失函数可以是交叉熵而不是均方误差?

(3)线性判别分析和逻辑回归在估计参数方面有什么异同点?

(4)尝试从0推导svm

(5)二次判别分析,线性判别分析,朴素贝叶斯之间的联系和区别?

(6)使用python+numpy实现逻辑回归

(7)了解梯度下降法,牛顿法,拟牛顿法与smo算法等优化算法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值