栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

机器学习细节问题

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

机器学习细节问题

机器学习细节问题
  • 1. 逻辑回归损失函数
  • 2. 二分类模型评估指标的混淆矩阵
  • 2. 二分类评估指标扩展至多分类模型
  • 3. 为什么进行归一化(损失均匀,加速归一化)
  • 4. class_weight样本权重作用
  • 5. 二分类模型扩展至多分类模型的方法
  • 6. make_pipeline的使用
  • 7. 交互项PolynomialFeatures
  • 8. MAE 和 MSE

1. 逻辑回归损失函数

交叉熵损失:
L ( θ ) = ∑ i = 1 m y i ln ⁡ P ( y = 1 ∣ x i ) + ( 1 − y i ) ln ⁡ ( 1 − P ( y = 1 ∣ x i ) ) = ∑ i = 1 m y i ln ⁡ h θ ( x i ) + ( 1 − y i ) ln ⁡ ( 1 − h θ ( x i ) ) begin{aligned} L(boldsymbol{theta}) &=sum_{i=1}^{m} y_{i} ln Pleft(y=1 mid x_{i}right)+left(1-y_{i}right) ln left(1-Pleft(y=1 mid x_{i}right)right) \ &=sum_{i=1}^{m} y_{i} ln h_{boldsymbol{theta}}left(x_{i}right)+left(1-y_{i}right) ln left(1-h_{boldsymbol{theta}}left(x_{i}right)right) end{aligned} L(θ)​=i=1∑m​yi​lnP(y=1∣xi​)+(1−yi​)ln(1−P(y=1∣xi​))=i=1∑m​yi​lnhθ​(xi​)+(1−yi​)ln(1−hθ​(xi​))​

2. 二分类模型评估指标的混淆矩阵
  • Actual condition positive(P):样本中阳性样本总数,一般也就是真实标签为1的样本总数;
  • Actual condition negative(N):样本中阴性样本总数,一般也就是真实标签为0的样本总数;
  • Predicted condition positive(PP):预测中阳性样本总数,一般也就是预测标签为1的样本总数;
  • Predicted condition negative(PN):预测中阴性样本总数,一般也就是预测标签为0的样本总数;
  • True positive(TP):样本属于阳性(类别1)、并且被正确识别为阳性(类别1)的样本总数;TP发生时也被称为正确命中(hit);
  • True negative(TN):样本属于阴性(类别0)、并且被正确识别为阴性(类别0)的样本总数;TN发生时也被称为正确拒绝(correct rejection);
  • False positive(FP):样本属于阴性(类别0),但被错误判别为阳性(类别1)的样本总数;FP发生时也被称为发生I类了错误(Type I error),或者假警报(False alarm)、低估(underestimation)等;
  • False negative(FN):样本属于阳性(类别1),但被错误判别为阴性(类别0)的样本总数;FN发生时也被称为发生了II类错误(Type II error),或者称为错过目标(miss)、高估(overestimation)等;

召回率:
R e c a l l = T P T P + F N Recall = frac{TP}{TP+FN} Recall=TP+FNTP​

精确率:
P r e c i s i o n = T P T P + F P Precision = frac{TP}{TP+FP} Precision=TP+FPTP​
特异度:
S p e c i f i c i t y = T N T N + F P Specificity = frac{TN}{TN+FP} Specificity=TN+FPTN​

召回率和精确率的调和平均(受三个指标的影响度较大):
F 1 − S c o r e = 2 1 R e c a l l + 1 P r e c i s i o n = 2 ⋅ R e c a l l ⋅ P r e c i s i o n R e c a l l + P r e c i s i o n F1-Score = frac{2}{frac{1}{Recall}+frac{1}{Precision}}=frac{2 cdot Recall cdot Precision}{Recall+Precision} F1−Score=Recall1​+Precision1​2​=Recall+Precision2⋅Recall⋅Precision​
平均数
B A = R e c a l l + P r e c i s i o n 2 BA = frac{Recall+Precision}{2} BA=2Recall+Precision​
ROC空间将伪阳性率(FPR)定义为 X 轴,真阳性率(TPR)定义为 Y 轴。

  • TPR(召回率):在所有实际为阳性的样本中,被正确地判断为阳性之比率。
    T P R = T P / ( T P + F N ) T P R = T P / ( T P + F N ) {displaystyle TPR=TP/(TP+FN)}{displaystyle TPR=TP/(TP+FN)} TPR=TP/(TP+FN)TPR=TP/(TP+FN)
  • FPR(特异度):在所有实际为阴性的样本中,被错误地判断为阳性之比率。
    F P R = F P / ( F P + T N ) F P R = F P / ( F P + T N ) {displaystyle FPR=FP/(FP+TN)}{displaystyle FPR=FP/(FP+TN)} FPR=FP/(FP+TN)FPR=FP/(FP+TN)

关于ROC曲线:

  • 曲线越接近上面说明类别之间的差距越大,受阈值影响较小,判断模型更为精准。

ROC曲线示例

from sklearn.metrics import confusion_matrix, precision_score, recall_score
from sklearn.svm import SVC
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
import numpy as np

class_1 = 500
class_2 = 50
centers = [[0.0, 0.0], [2.0, 2.0]]  # 类别中心
clusters_std = [1.5, 0.5]  # 方差
x, y = make_blobs(n_samples=[class_1, class_2]
                  , centers=centers
                  , cluster_std=clusters_std
                  , random_state=0
                  # ,shuffle=False
                  , shuffle=True)

# 支持向量机自带概率,但是运算效率低(实例化时需要probability=True)
svc = SVC(kernel="linear", C=1.0, probability=True).fit(x, y)

recall = []
FPR = []
pro_range = np.linspace(svc.predict_proba(x)[:, 1].min()
                        , svc.predict_proba(x)[:, 1].max(), 50
                        , endpoint=False  # 不取最后一位
                        )
# 阈值列表pro_range
for i in pro_range:
    y_predict = []
    res = svc.predict_proba(x)
    for j in range(x.shape[0]):
        # 以i为分界概率
        if res[j, 1] > i:
            y_predict.append(1)
        else:
            y_predict.append(0)

    cm = confusion_matrix(y, y_predict, labels=[1, 0])  # 混淆矩阵

    recall.append(cm[0, 0] / cm[0, :].sum())
    FPR.append(cm[1, 0] / cm[1, :].sum())

plt.plot(FPR, recall, color="red")
plt.plot(pro_range, pro_range, color="black", linestyle="--")
plt.xlabel("FPR")
plt.ylabel("recall")
plt.show()

2. 二分类评估指标扩展至多分类模型


召回率评估:

# 假设真是结果:
y_true = np.array([0, 1, 2, 2, 0, 1, 1, 2, 0, 2])
# 根据上图的概率预测结果为:
y_pred = np.array([0, 1, 0, 2, 2, 1, 2, 2, 0, 2])
TP1 = 2
TP2 = 2
TP3 = 3

FN1 = 1
FN2 = 1
FN3 = 1

# 三个召回率:
re1 = 2/3
re2 = 2/3
re3 = 3/4

np.mean([re1, re2, re3])# 0.6944444444444443
recall_score(y_true, y_pred, average='macro')# macro就是召回率均值

re1 * 3/10 + re2 * 3/10 + re3 * 4/10 # 0.7
recall_score(y_true, y_pred, average='weighted')# weighted就是按照权值分配,偏向样本量大的数据类别

ROC曲线概率评估:

# 两类
y_true_1 = np.array([1, 0, 0, 0, 1, 0, 0, 0, 1, 0])
y_pred_1 = np.array([0.8, 0.2, 0.5, 0.2, 0.3, 0.1, 0.3, 0.3, 0.9, 0.3])
roc_auc_score(y_true_1, y_pred_1)
# 将第一类作为正类
y_true_1 = np.array([1, 0, 0, 0, 1, 0, 0, 0, 1, 0])
y_pred_1 = np.array([0.8, 0.2, 0.5, 0.2, 0.3, 0.1, 0.3, 0.3, 0.9, 0.3])
r1 = roc_auc_score(y_true_1, y_pred_1)
# 将第二类作为正类
y_true_2 = np.array([0, 1, 0, 0, 0, 1, 1, 0, 0, 0])
y_pred_2 = np.array([0.2, 0.6, 0.3, 0, 0.2, 0.8, 0.2, 0.3, 0, 0.1])
r2 = roc_auc_score(y_true_2, y_pred_2)
# 将第三类作为正类
y_true_3 = np.array([0, 0, 1, 1, 0, 0, 0, 1, 0, 1])
y_pred_3 = np.array([0, 0.2, 0.2, 0.8, 0.5, 0.1, 0.5, 0.4, 0.1, 0.6])
r3 = roc_auc_score(y_true_3, y_pred_3)

# 三个roc取均值
np.mean([r1, r2, r3])
# 0.8501984126984127

# 多分类使用roc_auc_score曲线进行实现
y_pred = np.concatenate([y_pred_1.reshape(-1, 1), y_pred_2.reshape(-1, 1), y_pred_3.reshape(-1, 1)], 1)
"""
array([[0.8, 0.2, 0. ],
       [0.2, 0.6, 0.2],
       [0.5, 0.3, 0.2],
       [0.2, 0. , 0.8],
       [0.3, 0.2, 0.5],
       [0.1, 0.8, 0.1],
       [0.3, 0.2, 0.5],
       [0.3, 0.3, 0.4],
       [0.9, 0. , 0.1],
       [0.3, 0.1, 0.6]])
"""
y_true = np.array([0, 1, 2, 2, 0, 1, 1, 2, 0, 2])
roc_auc_score(y_true, y_pred, average='macro', multi_class='ovr')
# 0.8501984126984127
3. 为什么进行归一化(损失均匀,加速归一化)

能够看出经过归一化处理的之后的数据损失函数等高线更加均匀,收敛效率更高。

关于归一化能够让等高线更加均匀从而加快迭代收敛过程的理解:

从理论角度出发,其实梯度下降过程每一步参数点移动的方向是能够让梯度最快速下降的方向,也就是图片上垂直于等高线的方向。但这种所谓的最快速的方向只在开始移动的一瞬间满足,由于梯度是连续变化的函数,因此当移动了一小步之后"最优方向“其实就可能发生了变化,但参数只能在下次移动时再改变方向,因此中间其实很长一段距离参数并不不一定是沿着最优方向在进行移动。这里需要注意,如果下一次移动的方向和上一次移动方向一致或者类似,那就说明这次移动过程中参数并没有偏离方向太多,反之则这次移动走了很多弯路
而当损失函数的等高线是均匀分布时,外圈的垂直线也就是内圈的垂直线,此时参数两次移动过程大概率最优方向一致,也就是说相同的移动能够更大程度降低损失函数值,内外圈分布不均匀,则参数两次迭代过程最优方向将发生偏移,也就是说明上一次迭代过程有很长一段距离没有沿着最优方向迭代,该次迭代只降低了有限的损失函数计算值。经次过程不断迭代,由于经过归一化的损失函数每次迭代效率都更高,因此相比其他损失函数,经过归一化的数据只需要更少次的迭代就能抵达最小值点,这也就是加快收敛速度的根本原因。

4. class_weight样本权重作用

class_weight其实代表各类样本在进行损失函数计算时的数值权重,例如假设一个二分类问题, 0 、 1 0、1 0、1两类的样本比例是2:1,此时可以输入一个字典类型对象用于说明两类样本在进行损失值计算时的权重,例如输入: 0 : 1 , 1 : 3 {0:1,1:3} 0:1,1:3,则代表1类样本的每一条数据在进行损失函数值的计算时都会在原始数值上 ∗ 3 *3 ∗3,也就是样本对应的损失乘以 c l a s s _ w e i g h t class_weight class_weight。而当我们将该参数选为 b a l a n c e d balanced balanced 时,则会自动将这个比例调整为真实样本比例的反比,以达到平衡的效果。

5. 二分类模型扩展至多分类模型的方法
  1. 一对一 One vs One

共有 C N 2 C^2_N CN2​个二分类器
新样本预测最后通过投票方式进行预测

  1. 一对多 One vs Rest

共有 N N N个二分类器

新样本预测通过每个模型谁预测为1就是谁,多个为1,就看谁概率值大。

  1. 多对多 Many vs Many

一个或多个类为1,其余为-1,二分类器数量不定(个数比较随意,假设为M),对于每个类别就会存在为一个长为M的结果序列:比如:类别为1样本序列为 1 , . . . , − 1 , 1 , . . . . , − 1 1,...,-1,1,....,-1 1,...,−1,1,....,−1

最后使用每个分类器预测会使用这M个分类器,预测出M个值( 每个值 ∈ − 1 , 1 每个值in {-1,1} 每个值∈−1,1),计算预测值在这N个类对应的结果序列中的距离,最小的就是预测结果。

闵可夫斯距离

d ( x , y ) = ∑ i = 1 n ( ∣ x i − y i ∣ ) k k d(x, y)=sqrt[k]{sum_{i=1}^{n}left(left|x_{i}-y_{i}right|right)^{k}} d(x,y)=ki=1∑n​(∣xi​−yi​∣)k ​

k为2就是欧式距离。

6. make_pipeline的使用
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LogisticRegression

def plr(degree=1, penalty='none', C=1.0):
    pipe = make_pipeline(PolynomialFeatures(degree=degree, include_bias=False), 
                         StandardScaler(), 
                         LogisticRegression(penalty=penalty, tol=1e-4, C=C, max_iter=int(1e6)))
    return pipe

pl1 = plr()

# 返回管道中的所有模型
pr2.named_steps
"""
{'polynomialfeatures': PolynomialFeatures(include_bias=False),
 'standardscaler': StandardScaler(),
 'logisticregression': LogisticRegression(max_iter=1000000, penalty='none')}
"""

pl1.get_params() # 显示所有管道模型参数
"""
{'memory': None,
 'steps': [('polynomialfeatures',
   PolynomialFeatures(degree=1, include_bias=False)),
  ('standardscaler', StandardScaler()),
  ('logisticregression',
   LogisticRegression(max_iter=1000000, penalty='none'))],
 'verbose': False,
 'polynomialfeatures': PolynomialFeatures(degree=1, include_bias=False),
 'standardscaler': StandardScaler(),
 'logisticregression': LogisticRegression(max_iter=1000000, penalty='none'),
 'polynomialfeatures__degree': 1,
 'polynomialfeatures__include_bias': False,
 'polynomialfeatures__interaction_only': False,
 'polynomialfeatures__order': 'C',
 'standardscaler__copy': True,
 'standardscaler__with_mean': True,
 'standardscaler__with_std': True,
 'logisticregression__C': 1.0,
 'logisticregression__class_weight': None,
 'logisticregression__dual': False,
 'logisticregression__fit_intercept': True,
 'logisticregression__intercept_scaling': 1,
 'logisticregression__l1_ratio': None,
 'logisticregression__max_iter': 1000000,
 'logisticregression__multi_class': 'auto',
...
 'logisticregression__random_state': None,
 'logisticregression__solver': 'lbfgs',
 'logisticregression__tol': 0.0001,
 'logisticregression__verbose': 0,
 'logisticregression__warm_start': False}
"""

# 设置调整PolynomialFeatures评估器中的include_bias参数
pl2 = pl1.set_params(polynomialfeatures__include_bias=True)
7. 交互项PolynomialFeatures

https://blog.csdn.net/huangguohui_123/article/details/111907132

8. MAE 和 MSE
  • MSE会更关注离群点
  • MAE相对对于离群点叛错结果损失减弱
  • criterion='friedman_mse’是MAE,MSE之间的损失,相对来说均衡一些,但是一般用于继承学习算法。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1018048.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号