zoukankan      html  css  js  c++  java
  • 回归与聚类算法 学习笔记

    4.回归与聚类算法

    4.1 线性回归

    4.1.1 线性回归的原理

    1 线性回归应用场景

    • 房价预测
    • 销售额度预测
    • 金融:贷款额度预测、利用线性回归以及系数分析因子

    2 什么是线性回归

    1) 定义与公式

    线性回归(Linear regression)是利用回归方程(函数)对一个或多个自变量(特征值)和因变量(目标值)之间关系进行建模的一种分析方式。

    • 特点:只有一个自变量的情况称为单变量回归,多于一个自变量情况的叫做多元回归

    通用公式:(h(w) = w1x1+w2x2+w3x3...+b=w^Tx+b)

    其中w,x可以理解为矩阵:

    (w=egin{pmatrix} b \ w1 \ w2 end{pmatrix},x=egin{pmatrix} 1 \ x1 \ x2 end{pmatrix})

    特征值与目标值之间建立了一个关系,这个关系可以理解为线性模型。

    2) 线性回归的特征与目标的关系分析

    线性回归当中线性模型有两种,一种是线性关系,另一种是非线性关系。

    注:单特征与目标值的关系呈直线关系,或者两个特征与目标值呈现平面的关系
    更高维度的我们不用自己去想,记住这种关系即可

    如果是非线性关系那么回归方程可以理解为:w1x1 + w2x2^2 + w3x3^2

    线性模型包括:

    • y = w1x1 + w2x2 + w3x3 + ... + wnxn + b
    • y = w1x1 + w2x2^2 + w3x3^2 + b

    线性关系&线性模型

    • 线性关系一定是线性模型
    • 线性模型不一定是线性关系

    4.1.2 线性回归的损失和优化原理(理解记忆)

    目标:求模型参数 → 模型参数能够使得预测准确

    1 损失函数

    损失函数/cost/成本函数/目标函数

    总损失定义为:

    [J( heta) = (h_w(x_1)-y_1)^2 + (h_w(x_2)-y_2)^2+...+(h_w(x_m)-y_m)^2 \ = sum_{i=1}^m(h_w(x_i) - y_i) ^2 ]

    • yi为第i个样本的真实值
    • h(xi)为第i个训练样本特征值组合预测函数
    • 又称最小二乘法

    减少这个损失的过程称为损失优化

    2 优化算法

    线性回归经常使用的两种优化算法

    • 正规方程
      天才 - 直接求解w
      $ w = (XTX){-1}X^Ty$

      理解:X为特征值矩阵,y为目标值矩阵,直接求到最好的结果
      缺点:当特征值过多过复杂时,求解速度太慢且得不到结果

    • 梯度下降(Gradient Descent)
      勤奋努力的普通人 - 不断试错、改进
      (w1' := w1 - alphafrac{ heta (w0+w1x1)}{ heta w1})
      (w0' := w0 - alphafrac{ heta (w0+w1x1)}{ heta w1})

      理解:α为学习速率,需要手动指定(超参数),α旁边的整体表示方向,沿着这个函数下降的方向找,最后就能找到山谷的最低点,然后更新W值
      使用:面对训练数据规模十分庞大的任务,能够找到较好的结果

    4.1.3 线性回归API

    • sklearn.linear_moder.LinearRegression(fit_intercept=True)
      • 通过正规方程优化
      • fit_intercept:是否计算偏置
      • LinearRegression.coef_:回归系数
      • LinearRegression.intercept_:偏置
    • sklearn.linear_moder.SGDRegressor(loss="squared_loss",fit_intercept=True,learning_rate='invscaling',eta0=0.01)
      • SGDRegressor类实现了随机梯度下降学习,它支持不同的loss函数和正则化惩罚项来拟合线性回归模型。
      • loss:损失类型
        • loss="squared_loss":普通最小二乘法
      • fit_intercept:是否计算偏置
      • learning_rate:string,optional
        • 学习率填充
        • 'constant':eta = eta0
        • 'optimal':eta = 1.0/(alpha *(t+t0))[default]
        • 'invscaling':eta = eta0 / pow(t,power_t)
          power_t=0.25:存在父类当中
        • 对于一个常数值的学习率来说,可以使用learning_rate='constant',并使用eta0来指定学习率。
      • SGDRegressor.coef_:回归系数
      • SGDRegressor.intercept_:偏置

    sklearn提供给我们两种实现的API,可以根据选择使用

    4.1.4 波士顿房价预测

    1 分析

    回归当中的数据大小不一致,会导致结果影响较大。所以需要做标准化处理。

    • 数据分割与标准化处理
    • 回归预测
    • 线性回归的算法效果评估

    2 回归性能评估

    均方误差(Mean Squared Error)MSE 评价机制:

    (MSE = frac{1}{m} sum_{i=1}^{m}(y^i(预测值)-ar{y}(真实值))^2)

    • sklearn.metrics.mean_squared_error(y_true, y_pred)
      • 均方误差回归损失
      • y_true:真实值
      • y_pred:预测值
      • return:浮点数结果

    3 代码

    from sklearn.datasets import load_boston
    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import StandardScaler
    from sklearn.linear_model import LinearRegression, SGDRegressor
    from sklearn.metrics import mean_squared_error
    
    def linear1():
        """
        正规方程的优化方法对波士顿房价进行预测
        :return:
        """
        # 1)获取数据
        boston = load_boston()
        
        # 2)划分数据集
        x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, random_state=22)
        
        # 3)标准化
        transfer = StandardScaler()
        x_train = transfer.fit_transform(x_train)
        x_test = transfer.transform(x_test)
        
        # 4)预估器
        estimator = LinearRegression()
        estimator.fit(x_train, y_train)
        
        # 5)得到模型
        print("正规方程-权重系数为:",estimator.coef_)
        print("正规方程-偏置为:",estimator.intercept_)
        
        # 6)模型评估
        y_predict = estimator.predict(x_test)
        print("预测房价:
    ",y_predict)
        error = mean_squared_error(y_test, y_predict)
        print("正规方程-均方误差为:
    ",error)
        
        return None
    
    def linear2():
        """
        梯度下降的优化方法对波士顿房价进行预测
        :return:
        """
        # 1)获取数据
        boston = load_boston()
        
        # 2)划分数据集
        x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, random_state=22)
        
        # 3)标准化
        transfer = StandardScaler()
        x_train = transfer.fit_transform(x_train)
        x_test = transfer.transform(x_test)
        
        # 4)预估器
        estimator = SGDRegressor() 
        # SGDRegressor()可以设置(调参)
        estimator.fit(x_train, y_train)
        
        # 5)得到模型
        print("梯度下降-权重系数为:",estimator.coef_)
        print("梯度下降-偏置为:",estimator.intercept_)
        
        # 6)模型评估
        y_predict = estimator.predict(x_test)
        print("预测房价:
    ",y_predict)
        error = mean_squared_error(y_test, y_predict)
        print("梯度下降-均方误差为:
    ",error)
        
        return None
    
    if __name__ == '__main__':
        # 代码1:正规方程的优化方法对波士顿房价进行预测
        linear1()
    	# 代码2:梯度下降的优化方法对波士顿房价进行预测
        linear2()
    

    4 回归方程和梯度下降对比

    • 文字对比

      梯度下降 正规方程
      需要选择学习率 不需要
      需要迭代求解 一次运算得出
      特征数量较大可以使用 需要计算方程,时间复杂度高O(n3)
    • 选择:

      • 小规模数据:
        • LinearRegression(不能解决拟合问题)
        • 岭回归
      • 大规模数据:SGDRegressor

    正规方程不一定比梯度下降好,梯度下降灵活性高,参数设置不一样结果不一样。梯度下降通用性强,正规方程局限性大

    4.1.5 拓展-关于优化方法GD、SGD、SAG

    1 GD

    梯度下降(Gradient Descent),原始的梯度下降法需要计算所有样本的值才能够得出梯度,计算量大,所以后面才有一系列的改进。

    2 SGD

    随机梯度下降(Stoochatic gradient descent)是一个优化方法,它在一次迭代时只考虑一个训练样本。

    • SGD的优点是:
      • 高效
      • 容易实现
    • SGD的缺点是:
      • SGD需要许多超参数:比如正规项参数、迭代数
      • SGD对于特征标准化是敏感的。

    3 SAG

    随机平均梯度法(Stochasitc Average Gradient),由于收敛的速度太慢,有人提出SAG等基于梯度下降的算法

    Scikit-learn:岭回归、逻辑回归等当中都会有SAG优化

    4.2 欠拟合与过拟合

    4.2.1 什么是过拟合与欠拟合

    定义

    • 过拟合:一个假设在训练数据上能够获得比其他假设更好的拟合,但是在测试数据集上却不能很好的拟合数据,此时认为这个假设出现了过拟合现象。(模型过于复杂)
    • 欠拟合:一个假设在训练数据上不能获得更好的拟合,并且在测试数据集上也不能很好地拟合数据,此时认为这个假设出现了欠拟合现象。(模型过于简单)

    4.2.2 原因以及解决方法

    • 欠拟合原因以及解决方法
      • 原因:学习到数据的特征过少
      • 解决方法:解决数据的特征数量
    • 过拟合原因以及解决方法
      • 原因:原始特征过多,存在一些嘈杂特征,模型过于复杂是因为模型尝试去兼顾各个测试数据点
      • 解决方法:正则化(尽量减小高次项特征的影响)

    1 正则化类别

    • L2正则化

      • 作用:可以使得其中一些w都很小,都接近于0,削弱某个特征的影响

      • 优点:越小的参数说明模型越简单,越简单的模型则越不容易产生过拟合现象。

      • Ridge回归

      • 加入L2正则化后的损失函数:
        (J(w) = frac{1}{2m} sum_{i=1}^m(h_w(x_i)-y_i)^2 + lambda sum_{j=1}^n w_j^2)

        损失函数 + 惩罚系数λ*惩罚项(平方)
        注:m为样本数,n为特征数

    • L1正则化

      • 作用:可以使得其中一些W的值直接为0,删除这个特征的影响
      • LASSO回归
      • 损失函数 + 惩罚系数λ*惩罚项(绝对值)

    4.3 线性回归的改进 - 岭回归

    4.3.1带有L2正则化的线性回归-岭回归

    岭回归,其实也是一种线性回归。只不过在算法建立回归方程时,加上正则化的限制,从而达到解决过拟合的效果。

    1 API

    • sklearn.linear_model.Ridge(alpha=1.0,fit_intercept=True,solver="auto",normalize=False)
      • 具有L2正则化的线性回归
      • alpha:正则化力度,也叫λ
        • λ取值:0~1 1~10
      • solver:会根据数据自动选择优化方法
        • sag:如果数据集、特征都比较大,选择该随机梯度下降优化
      • normalize:数据是否进行标准化
        • normalize=False:是否可以在fit之前调用preprocessing.StandardScaler标准化数据
      • Ridge.coef_:回归权重
      • Ridge.intercept_:回归偏置

    Ridge方法相当于SGDRegressor(penalty='l2',loss="squared_loss"),只不过SGDRegressor实现了一个普通的随机梯度下降学习,推荐使用Ridge(实现了SAG)

    • sklearn.linear_model.RidgeCV(_BaseRidgeCV,RegressorMixin)
      • 具有l2正则化的线性回归,可以进行交叉验证
      • coef_:回归系数

    2 观察正则化程度的变化,对结果的影响?

    • 正则化力度越大,权重系数会越小
    • 正则化力度越小,权重系数会越大
    from sklearn.datasets import load_boston
    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import StandardScaler
    from sklearn.linear_model import Ridge
    from sklearn.metrics import mean_squared_error
    
    def linear3():
        """
        岭回归对波士顿房价进行预测
        :return:
        """
        # 1)获取数据
        boston = load_boston()
        
        # 2)划分数据集
        x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, random_state=22)
        
        # 3)标准化
        transfer = StandardScaler()
        x_train = transfer.fit_transform(x_train)
        x_test = transfer.transform(x_test)
        
        # 4)预估器
        estimator = Ridge()
        estimator.fit(x_train, y_train)
        
        # 5)得到模型
        print("岭回归-权重系数为:",estimator.coef_)
        print("岭回归-偏置为:",estimator.intercept_)
        
        # 6)模型评估
        y_predict = estimator.predict(x_test)
        print("预测房价:
    ",y_predict)
        error = mean_squared_error(y_test, y_predict)
        print("岭回归-均方误差为:
    ",error)
        
        return None
    
    
    if __name__ == '__main__':
        # 代码3:岭回归对波士顿房价进行预测
        linear3()
    

    4.4 分类算法-逻辑回归与二分类

    4.4.1 逻辑回归的应用场景

    • 广告点击率 → 是否被点击
    • 是否为垃圾邮件
    • 是否患病
    • 是否为金融诈骗
    • 是否为虚假账号

    都属于二分类问题

    4.4.2 逻辑回归的原理

    1 输入

    (h(w) = w_1x_1+w_2x_2+w_3x_3 ... + b)

    逻辑回归的输入就是一个线性回归的结果

    2 激活函数

    • sigmoid函数 (g( heta^Tx) = frac{1}{1+e^{-( heta^Tx)}})
    • 分析
      • 回归的结果输入到sigmoid函数当中
      • 输出结果:[0,1]区间中的一个概率值,默认为0.5为阈值(如果输出大于阈值就属于这个类别,小于则不属于这个类别)

    3 损失以及优化

    1 损失

    逻辑回归的损失,称之为对数似然损失,公式如下:

    • 分开类别:

      [cost(h_ heta (x),y) = egin{cases} -log(h_ heta (x)) & ext{if } y=1 \ -log(1-h_ heta (x)) & ext{if } y=0 end{cases} ]

    • 综合完整损失函数

      [cost(h_ heta (x),y) = sum_{i=1}^m -y_i log(h_ heta (x)) - (1 - y_i)log(1-h_ heta (x)) ]

    2 优化

    同样使用梯度下降优化算法,去减少损失函数的值。这样去更新逻辑回归前面对应算法的权重参数,提升原本属于1类别的概率,降低原本是0类别的概率。

    4.4.3 逻辑回归API

    • sklearn.linear_model.LogisticRegression(solver='liblinear',penalty='l2',C=1.0)

      • solver:优化求解方式(默认开源的liblinear库实现,内部使用了坐标轴下降法来迭代优化损失函数)
      • penalty:正则化的种类
      • C:正则化力度

      默认将类别数量少的当做正例

      LogisticsRegression方法相当于SGDClassifier(loss="log",penalty=" "),SGDClassifier实现了一个普通的随机梯度下降学习,也支持平均随机梯度下降法(ASGD),可以通过设置average = True。而使用LogisticsRegression(实现了SAG)

      4.4.4 案例:癌症分类预测

      流程分析:

      1. 获取数据(读取时加上names
      2. 数据处理(处理缺失值
      3. 数据集划分
      4. 特征工程(无量纲化处理—标准化
      5. 逻辑回归预估值
      6. 模型评估
      import pandas as pd
      import numpy as np
      from sklearn.model_selection import train_test_split
      from sklearn.preprocessing import StandardScaler
      from sklearn.linear_model import LogisticRegression
      
      def logisticregression():
          """
          逻辑回归进行癌症预测
          :return:None
          """
          # 1 读取数据,处理缺失值以及标准化
          column_name=['列名1','列名2',...,'列名n']
          data = pd.read_csv("数据地址",names=column_name)
          
          # 2 缺失值处理
          # 1)替换→np.nan
          data = data.replace(to_replace="?",value=np.nan)
          # 2)删除缺失样本
          data.dropna()
          
          # 3 划分数据集
          # 筛选特征值和目标值
          x = data.iloc[:,1:-1]
          y = data["目标值列名"]
          x_train, x_test, y_train, y_test = train_test_split(x,y)
          
          # 4 特征工程   标准化
          transfer = StandardScaler()
          x_train = transfer.fit_transform(x_train)
          x_test = transfer.transform(x_test)
          
          # 5 逻辑回归预估值
          estimator = LogisticRegression()
          estimator.fit(x_train, y_train)
          
          # 6 模型评估
          # 方法1:直接对比真实值和预测值
          y_predict = estimator.predict(x_test)
          print("y_predict:
      ",y_predict)
          print("直接对比真实值和预测值:
      ",y_test == y_predict)
      
          # 方法2:计算准确率
          score = estimator.score(x_test,y_test)
          print("准确率为:
      ",score)
          
          return None
      

    4.4.5 分类的评估方法

    1 精确率与召回率

    1 混淆矩阵

    在分类任务下,预测结果与正确标记之间存在四种不同的组合,构成混淆矩阵(适用于多分类)

    预测结果为正例 预测结果为伪例
    真实结果为正例 真正例TP 伪反例FN
    真实结果为伪例 伪正例FP 真反例TN
    2 精确率(Precision)与召回率(Recall)
    • 精确率:预测结果为正例样本中真实为正例的比例(查的对不对)(frac{TP}{TP+FP})
    • 召回率:真实为正例样本中预测结果为正例的比例(查的全不全)(frac{TP}{TP+FN})
    • 还有其他的评估标准,F1-score,反映了模型的稳健型(F12 = frac{2TP}{2TP+FN+FP} = frac{2*Precision*Recall}{Precision+Recall})
    3 分类评估报告API
    • sklearn.metrics.classification_report(y_true,y_pred,labels=[],target_names=None)
      • y_true:真实目标值
      • y_pred:预估器预测目标值
      • labels:指定类别对应数字
      • target_name:目标类别名称
      • return:每个类别精确率与召回率
    # 查看精确率、召回率、F1-score
    from sklearn.metrics import classification_report
    import pandas as pd
    import numpy as np
    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import StandardScaler
    from sklearn.linear_model import LogisticRegression
    
    def logisticregression():
        """
        逻辑回归进行癌症预测
        :return:None
        """
        # 1 读取数据,处理缺失值以及标准化
        column_name=['列名1','列名2',...,'列名n']
        data = pd.read_csv("数据地址",names=column_name)
        
        # 2 缺失值处理
        # 1)替换→np.nan
        data = data.replace(to_replace="?",value=np.nan)
        # 2)删除缺失样本
        data.dropna()
        
        # 3 划分数据集
        # 筛选特征值和目标值
        x = data.iloc[:,1:-1]
        y = data["目标值列名"]
        x_train, x_test, y_train, y_test = train_test_split(x,y)
        
        # 4 特征工程   标准化
        transfer = StandardScaler()
        x_train = transfer.fit_transform(x_train)
        x_test = transfer.transform(x_test)
        
        # 5 逻辑回归预估值
        estimator = LogisticRegression()
        estimator.fit(x_train, y_train)
        
        # 6 模型评估
        # 方法1:直接对比真实值和预测值
        y_predict = estimator.predict(x_test)
        print("y_predict:
    ",y_predict)
        print("直接对比真实值和预测值:
    ",y_test == y_predict)
    
        # 方法2:计算准确率
        score = estimator.score(x_test,y_test)
        print("准确率为:
    ",score)
        
        # 查看精确率、召回率、F1-score
        report = classification_report(y_test, y_predict. labels=[2,4],target_names=["良性","恶性"])
        print(report)
        
        return None
    	
    

    2 ROC曲线与AUC指标

    1 知道TPR与FPR
    • TPR = TP / (TP + FN) —— 召回率
      • 所有真实类别为1的样本中,预测类别为1的比例
    • FPR = FP / (FP + TN)
      • 所有真实类别为0的样本中,预测类别为1的比例
    2 ROC曲线
    • ROC曲线的横轴就是FPRate,纵轴就是TPRate,当两者相等时,表示的意义则是:对于不论真实类别是1还是0的样本,分类器预测为1的概率是相等的,此时AUC为0.5

    3 AUC指标
    • AUC的概率意义是随机取一对正负样本,正样本得分大于负样本的概率
    • AUC的最小值为0.5,最大值为1,取值越高越好
    • AUC=1,完美分类器,采用这个预测模型时,不管设定什么阈值都能得出完美预测。绝大多数预测的场合,不存在完美的分类器。
    • 0.5<AUC<1,优于随机猜测。这个分类器(模型)妥善设定阈值的话,能有预测价值。

    最终AUC的范围在[0.5,1]之间,并且越接近1越好

    4 AUC计算API
    • from sklearn.metrics import roc_auc_score
      • sklearn.metrics.roc_auc_score(y_true,y_score)
        • 计算ROC曲线面积,即AUC值
        • y_true:每个样本的真实类别,必须为0(反例),1(正例)标记
        • y_score:预测得分,可以是正类的估计概率、置信值或者分类器方法的返回值
    y_true = np.where(y_test > 3, 1, 0)
    
    print("AUC指标:",roc_auc_score(y_true,y_predict)
    
    5 总结
    • AUC只能用来评价二分类
    • AUC非常适合评价样本不平衡中的分类器性能

    4.5 模型保存和加载

    4.5.1 sklearn模型的保存和加载API

    • from sklearn.externals import joblib
      • 保存:joblib.dump(rf预估器,'test.pkl')
      • 加载:estimator = joblib.load('test.pkl')

    4.5.2 线性回归的模型保存加载案例

    • 保存
        # 4)预估器
        estimator = Ridge()
        estimator.fit(x_train, y_train)
        
        # 保存模型
        joblib.dump(estimator,"my_ridge.pkl")
    
    
    • 加载
     # 加载模型
        estimator = joblib.load("my_ridge.pkl")
    

    4.6 无监督学习 k-means算法

    4.6.1 什么是无监督学习

    从无标签的数据开始学习

    4.6.2 无监督学习包含算法

    • 聚类
      • K-means(K均值聚类)
    • 降维
      • PCA

    4.6.3 K-means原理

    K-means聚类步骤

    • 1、随机设置K个特征空间内的点作为初始的聚类中心(K — 超参数。取值→1)看需求,2)调节超参数)
    • 2、对于其他每个点计算到K个中心的距离,未知的点选择最近的一个聚类中心点作为标记类别
    • 3、全部标记后,重新计算出每个聚类的新中心点(平均值)
    • 4、如果计算得出的新中心点与原中心点一样,那么结束,否则重新进行第二步

    4.6.4 K-means API

    • sklearn.cluster.KMeans(n_clusters=8,init='k-means++')
      • k-means聚类
      • n_clusters:开始的聚类中心数量
      • init:初始化方法,默认为'k-means++'
      • labels_:默认标记的类型,可以和真实值比较(不是值比较)

    4.6.5 案例:K-means对Instacart Market用户聚类

    1 分析

    降维后的数据

    • 预估器流程
    • 看结果
    • 模型评估
    # 预估器流程
    from sklearn.cluster import KMeans
    
    estimator = KMeans(n_clusters=3)
    estimator.fit(data)
    estimator.predict(data)
    

    4.6.6 K-means性能评估指标

    1 轮廓系数

    (SC_i = frac{b_i-a_i}{max(b_i,a_i)})

    注:对于每个点i为已聚类数据中的样本,bi为i到其它族群的所有样本的距离最小值,ai为i到本身族的距离平均值。最终计算出所有的样本点的轮廓系数平均值

    2 轮廓系数值分析

    uploading-image-569648.png

    3 结论

    如果bi>>ai:趋近于1,效果越好;bi<<ai:趋近于-1,效果不好。轮廓系数的值是介于[-1,1],越趋近于1代表内聚度和分离度都相对较优。

    4 轮廓系数API

    • sklearn.metrics.silhouette_score(X,labels)
      • 计算所有样本的平均轮廓系数
      • X:特征值
      • labels:被聚类标记的目标值
    # 模型评估 - 轮廓系数
    from sklearn.metrics import silhouette_score
    
    silhouette_score(data,y_predict)
    

    4.6.7 K-means总结

    • 特点分析:采取迭代式算法,直观易懂并且非常实用
    • 缺点:容易收敛到局部最优解(多次类聚)

    注意:聚类一般坐在分类之前

  • 相关阅读:
    UltraEdit的配置
    字符编码笔记:ASCII,Unicode和UTF-8
    Hello World Hexo
    好久不见,味素
    记一次springboot+dubbo+zookeeper吐血的问题
    [深度学习]模型部署之优化
    [深度学习]pytorch部署之onnx
    count(*)、count(1)、count(column)
    like %和-的区别与使用
    SQL语言分类
  • 原文地址:https://www.cnblogs.com/l999q/p/12295507.html
Copyright © 2011-2022 走看看