机器学习分类与线性评价结果

1.分类准确度够用吗?

分类准确度在评价分类算法时,会有很大的问题的。分类算法的评价要比回归算法多很多。
对于一个癌症预测系统,输入检查指标,判断是否患有癌症,预测准确度99.9%。这个系统是好是坏呢?
如果癌症产生的概率是0.1%,那其实根本不需要任何机器学习算法,只要系统预测所有人都是健康的,即可达到99.9%的准确率。也就是说对于极度偏斜(Skewed Data)的数据,只使用分类准确度是不能衡量。
这是就需要使用混淆矩阵(Confusion Matrix)做进一步分析。

2.什么是混淆矩阵?

混淆矩阵预测值0预测值1
真实值0TNFP
真实值1FNTP

TN:真实值是0,预测值也是0,即我们预测是negative,预测正确了。
FP:真实值是0,预测值是1,即我们预测是positive,但是预测错误了。
FN:真实值是1,预测值是0,即我们预测是negative,但预测错误了。
TP:真实值是1,预测值是1,即我们预测是positive,预测正确了。

精准率(查准率):预测值为1,且预测对了的比例,即:我们关注的那个事件,预测的有多准。
召回率(查全率):所有真实值为1的数据中,预测对了的个数,即:我们关注的那个事件真实的发生情况下,我们成功预测的比例是多少。

3.究竟什么评价指标更合适?

视场景而定

比如我们做了一个股票预测系统,未来股票是📈还是📉这样一个二分类问题。很显然“涨”才是我们关注的焦点,那么我们肯定希望:系统预测上涨的股票中,真正上涨的比例越大越好,这就是希望查准率高。那么我们是否关注查全率呢?在大盘中有太多的真实上涨股票,虽然我们漏掉了一些上升周期,但是我们没有买进,也就没有损失。但是如果查准率不高,预测上涨的结果下跌了,那就是实实在在的亏钱了。所以在这个场景中,查准率更重要。
当然也有追求召回率的场景,在医疗领域做疾病诊断,如果召回率低,意味着本来有一个病人得病了,但是没有正确预测出来,病情就恶化了。我们希望尽可能地将所有有病的患者都预测出来,而不是在看在预测有病的样例中有多准。
但是,在实际业务场景中,也有很多没有这么明显的选择。那么在同时需要关注精准率和召回率,如何在两个指标中取得平衡呢?在这种情况下,我们使用一种新的指标:F1 Score

import numpy as np

def f1_score(precision, recall):
    try:
        return 2 * precision * recall / (precision + recall)
    except:
        return 0.0
        
precision = 0.5
recall = 0.5
f1_score(precision, recall)
# 输出:
# 0.5

在数据有偏移的情况下,F1评分更好

4.ROC曲线

4.1分类阈值、TPR和FPR

4.1.1分类阈值

分类阈值,即设置判断样本为正例的阈值thr,
如果某个逻辑回归模型对某封电子邮件进行预测时返回的概率为 0.9995,则表示该模型预测这封邮件非常可能是垃圾邮件。相反,在同一个逻辑回归模型中预测分数为 0.0003 的另一封电子邮件很可能不是垃圾邮件。可如果某封电子邮件的预测分数为 0.6 呢?为了将逻辑回归值映射到二元类别,您必须指定分类阈值(也称为判定阈值)。如果值高于该阈值,则表示“垃圾邮件”;如果值低于该阈值,则表示“非垃圾邮件”。人们往往会认为分类阈值应始终为 0.5,但阈值取决于具体问题,因此您必须对其进行调整。
在sklearn中有一个方法叫:decision_function,即返回分类阈值

decision_scores = log_reg.decision_function(X_test)
y_predict = np.array(decision_scores >= 5, dtype='int')

我们知道,精准率和召回率这两个指标有内在的联系,并且相互冲突。precision随着threshold的增加而降低,recall随着threshold的增大而减小。如果某些场景需要precision,recall都保持在80%,可以通过这种方式求出threshold
在这里插入图片描述

4.1.2 TPR

TPR:预测为1,且预测对了的数量,占真实值为1的数据百分比。很好理解,就是召回率。

4.1.3 FPR

FPR:预测为1,但预测错了的数量,占真实值不为1的数据百分比。与TPR相对应,FPR除以真实值为0的这一行所有的数字和 。

4.2 ROC曲线

ROC曲线(Receiver Operation Characteristic Cureve),描述TPR和FPR之间的关系。x轴是FPR,y轴是TPR。
我们已经知道,TPR就是所有正例中,有多少被正确地判定为正;FPR是所有负例中,有多少被错误地判定为正。 分类阈值取不同值,TPR和FPR的计算结果也不同,最理想情况下,我们希望所有正例 & 负例 都被成功预测 TPR=1,FPR=0,即 所有的正例预测值 > 所有的负例预测值,此时阈值取最小正例预测值与最大负例预测值之间的值即可。
TPR越大越好,FPR越小越好,但这两个指标通常是矛盾的。为了增大TPR,可以预测更多的样本为正例,与此同时也增加了更多负例被误判为正例的情况。

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression

digits = datasets.load_digits()
X = digits.data
y = digits.target.copy()

# 要构造偏斜数据,将数字9的对应索引的元素设置为1,0~8设置为0
y[digits.target==9]=1
y[digits.target!=9]=0

# 使用逻辑回归做一个分类
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=666)

log_reg = LogisticRegression()
log_reg.fit(X_train,y_train)
# 计算逻辑回归给予X_test样本的决策数据值
# 通过decision_function可以调整精准率和召回率
decision_scores = log_reg.decision_function(X_test)

# TPR
def TPR(y_true, y_predict):
    tp = TP(y_true, y_predict)
    fn = FN(y_true, y_predict)
    try:
        return tp / (tp + fn)
    except:
        return 0.0

# FPR
def FPR(y_true, y_predict):
    fp = FP(y_true, y_predict)
    tn = TN(y_true, y_predict)
    try:
        return fp / (fp + tn)
    except:
        return 0.0

fprs = []    
tprs = []

# 以0.1为步长,遍历decision_scores中的最小值到最大值的所有数据点,将其作为阈值集合
thresholds = np.arange(np.min(decision_scores), np.max(decision_scores), 0.1)
for threshold in thresholds:
    # decision_scores >= threshold 是布尔型向量,用dtype设置为int
    # 大于等于阈值threshold分类为1,小于为0,用这种方法得到预测值
    y_predict = np.array(decision_scores >= threshold, dtype=int)
    #print(y_predict)
    # print(y_test)
    #print(FPR(y_test, y_predict))
    # 对于每个阈值,所得到的FPR和TPR都添加到相应的队列中
    fprs.append(FPR(y_test, y_predict))
    tprs.append(TPR(y_test, y_predict))
    
# 绘制ROC曲线,x轴是fpr的值,y轴是tpr的值
plt.plot(fprs, tprs)
plt.show()

在这里插入图片描述
可以看到曲线每次都是一个“爬坡”,遇到正例往上爬一格,错了往右爬一格,显然往上爬对于算法性能来说是最好的。
sklearn中的ROC曲线:

from sklearn.metrics import roc_curve

fprs, tprs, thresholds = roc_curve(y_test, decision_scores)
plt.plot(fprs, tprs)
plt.show()

4.2.1 分析

ROC曲线距离左上角越近,证明分类器效果越好。如果一条算法1的ROC曲线完全包含算法2,则可以断定性能算法1>算法2。这很好理解,此时任做一条 横线(纵线),任意相同TPR(FPR) 时,算法1的FPR更低(TPR更高),故显然更优。
在这里插入图片描述
从上面ROC图中的几个标记点,我们可以做一些直观分析:
我们可以看出,左上角的点(TPR=1,FPR=0),为完美分类,也就是这个医生医术高明,诊断全对。点A(TPR>FPR),说明医生A的判断大体是正确的。中线上的点B(TPR=FPR),也就是医生B全都是蒙的,蒙对一半,蒙错一半;下半平面的点C(TPR<FPR),这个医生说你有病,那么你很可能没有病,医生C的话我们要反着听,为真庸医。
很多时候两个分类器的ROC曲线交叉,无法判断哪个分类器性能更好,这时可以计算曲线下的面积AUC,作为性能度量。

5 AUC

一般在ROC曲线中,我们关注是曲线下面的面积, 称为AUC(Area Under Curve)。这个AUC是横轴范围(0,1 ),纵轴是(0,1)所以总面积是小于1的。
ROC和AUC的主要应用:比较两个模型哪个好?主要通过AUC能够直观看出来。
ROC曲线下方由梯形组成,矩形可以看成特征的梯形。因此,AUC的面积可以这样算:(上底+下底)* 高 / 2,曲线下面的面积可以由多个梯形面积叠加得到。AUC越大,分类器分类效果越好。
AUC = 1,是完美分类器,采用这个预测模型时,不管设定什么阈值都能得出完美预测。绝大多数预测的场合,不存在完美分类器。
0.5 < AUC < 1,优于随机猜测。这个分类器(模型)妥善设定阈值的话,能有预测价值。
AUC = 0.5,跟随机猜测一样,模型没有预测价值。
AUC < 0.5,比随机猜测还差;但只要总是反预测而行,就优于随机猜测。
可以在sklearn中求出AUC值

from sklearn.metrics import roc_auc_score
roc_auc_score(y_test, decision_scores)
# 输出:
# 0.9830452674897119

6 分类精确度总结

F1 Score是精准率和召回率的调和平均值,可以平衡这两个指标。
又学习了分类阈值、TPR、FPR这三个概念,进而引出ROC来反映分类器的性能。AUC是曲线下面积,用来直观比较模型的好坏。

7 线性回归的评价指标

在这里插入图片描述
在这里插入图片描述
在之前确定损失函数时,我们提过,绝对值函数不是处处可导的,因此没有使用绝对值。但是在评价模型时不影响。因此模型的评价方法可以和损失函数不同。

8 线性回归代码评价的实现

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets

# 查看数据集描述
boston = datasets.load_boston()
print(boston.DESCR)

因为是测试简单回归算法,因此我们选择其中的一个特征进行建模。选择:
RM average number of rooms per dwelling 每个住宅的平均房间数
下面我们进行简单的数据探索:

# 查看数据集的特征列表
boston.feature_names
输出:
array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',
       'TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='<U7')
       
# 取出数据中的第六例的所有行(房间数量)
x = boston.data[:,5]
x.shape
输出:
(506,)

# 取出样本标签
y = boston.target
y.shape
输出:
(506,)

plt.scatter(x,y)
plt.show()


np.max(y)
# 这里有一个骚操作,用比较运算符返回一个布尔值的向量,将其作为索引,直接在矩阵里对每个元素进行过滤。
x = x[y < 50.0]
y = y[y < 50.0]
plt.scatter(x,y)
plt.show()

在图中我们可以看到 50W 美元的档分布着一些点。这些点可能是超出了限定范围(比如在问卷调查中,价格的最高档位是“50万及以上”,那么就全都划到50W上了,因此在本例中,可以将这部分数据去除)

8.1 简单线性回归预测

from myAlgorithm.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(x, y, seed=666)
print(x_train.shape)    # (392,)
print(y_train.shape)    #(392,)
print(x_test.shape)     #(98,)
print(y_test.shape)     #(98,)

from myAlgorithm.SimpleLinearRegression import SimpleLinearRegression

reg = SimpleLinearRegression()
reg.fit(x_train,y_train)
print(reg.a_)   # 7.8608543562689555
print(reg.b_)   # -27.459342806705543

plt.scatter(x_train,y_train)
plt.plot(x_train, reg.predict(x_train),color='r')
plt.show()

y_predict = reg.predict(x_test)
print(y_predict)

从数学角度来分析,RMSE和MAE的量纲相同,但RMSE的结果较大,这是因为RMSE是将错误值平方,平方操作会放大样本中预测结果和真实结果较大的差距。MAE没有放大。而我们就是要解决目标函数最大差距,因为选RMSE更好一点

9 R Square介绍

在这里插入图片描述
在这里插入图片描述
这其实和调用SKlearn中的方法相同

from sklearn.metrics import r2_score
r2_score(y_test, y_predict)

10 简单线性回归总结

线性回归的评价指标与分类的评价指标有很大的不同,本篇介绍了均方误差MSE(预测值与真实值之差的平方和,再除以样本量)、均方根误差RMSE(为了消除量纲,将MSE开方)、平均绝对误差MAE(预测值与真实值之差的绝对值,再除以样本量)、以及非常重要的、效果非常好的R方(因此用1减去较少的错误除以较多的错误,实际上是衡量了我们的模型拟合住数据的地方,即没有产生错误的相应指标)。
在实际应用过程中,我们需要这些评价指标,来判别模型的好坏。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值