第三章.逻辑回归

3.2 正确率/召回率/F1指标

正确率(Precision)和召回率(Recall)广泛应用于信息检索和统计学分类领域的两个度量值,用来评价结果的质量。

概念:

1).正确率:

  • 检索出来的条目有多少是正确的

2).召回率:

  • 所有正确的条目有多少被检索出来

3).F1:

  • 综合上面两个指标的评估指标,用于综合反映整体指标:F1=2*((正确率*召回率)/(正确率+召回率))

4).取值范围:

  • 这几个指标的取值都在0-1之间,数值越接近于1,效果越好。

5).举例:

  • 某池塘有1400条鲤鱼,300只虾,300只鳖。现在以捕鲤鱼为目的,撒一大网,逮着了700条鲤鱼,200只虾,100只鳖,那么这些指标如下:
    ①.正确率:700/(700+200+100)=70%
    ②.召回率:700/1400=50%
    ③.F值:2*((70*50)/(70+50))=58.3%

两个指标的平衡

  • 我们希望检索结果Precision和Recall越高越好,但事实上这两者在某些情况下是矛盾的
  • 比如极端情况下,我们只搜索出了一个结果,且是准确的,那个Precision就是100%,但是Recall就很低,而我们把所有结果都返回,那么比如Recall是100%,但是Precision就会很低。
  • 在不同的场合中需要自己判断是希望Precision比较高还是Recall比较高

综合评价指标

正确率与召回率指标有时候会出现矛盾的情况,这就需要综合考虑他们,最常见的方法就是F-Measure(又称F-Score)

1).公式:

逻辑回归预测癌症的数据集 逻辑回归预测准确率_逻辑回归

2).当β=1时,就是常见的F1指标:

逻辑回归预测癌症的数据集 逻辑回归预测准确率_sklearn_02

实战1:梯度下降法—非线性逻辑回归:

1).CSV中的数据:

2).代码

import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import classification_report
from sklearn import preprocessing
from sklearn.preprocessing import PolynomialFeatures  # 产生多项式的

# 数据是否是要标准化
scale = False

# 加载数据
data = np.genfromtxt('D:\\Data\\LR-testSet2.csv', delimiter=',')

# 数据切片
x_data = data[:, :-1]
y_data = data[:, -1, np.newaxis]


# 绘制散点图
def plot():
    x0 = []
    y0 = []
    x1 = []
    y1 = []
    # 切分不同类别的数据
    for i in range(len(x_data)):
        if y_data[i] == 0:
            x0.append(x_data[i, 0])
            y0.append(x_data[i, 1])
        else:
            x1.append(x_data[i, 0])
            y1.append(x_data[i, 1])

    scatter0 = plt.scatter(x0, y0, c='b', marker='o')
    scatter1 = plt.scatter(x1, y1, c='r', marker='x')

    plt.legend(handles=[scatter0, scatter1], labels=['label1', 'label2'])


plot()
plt.show()


# sigmoid函数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))


# 代价函数
def cost(xMat, yMat, ws):
    value1 = np.multiply(yMat, np.log(sigmoid(xMat * ws)))
    value2 = np.multiply(1 - yMat, np.log(1 - sigmoid(xMat * ws)))
    return np.sum(value1 + value2) / -(len(xMat))


# 梯度下降法
def gradAscent(xArr, yArr):
    if scale == True:
        xArr = preprocessing.scale(xArr)

    xMat = np.mat(xArr)
    yMat = np.mat(yArr)

    lr = 0.03
    epochs = 50000
    costList = []

    # 计算数据列数,有几列就有几个权值
    m, n = np.shape(xMat)

    # 初始化权值
    ws = np.mat(np.ones((n, 1)))

    for i in range(epochs + 1):
        h = sigmoid(xMat * ws)
        # 计算误差
        ws_grad = xMat.T * (h - yMat) / m
        ws = ws - lr * ws_grad

        if i % 50 == 0:
            costList.append(cost(xMat, yMat, ws))

    return ws, costList


# 定义多项式回归,degree的值可以调节多项式的特征
poly_reg = PolynomialFeatures(degree=3)

# 特征处理
x_poly = poly_reg.fit_transform(x_data)

# 训练模型
ws, costList = gradAscent(x_poly, y_data)

# 获取数据值所在的范围
x_min, x_max = x_data[:, 0].min() - 1, x_data[:, 0].max() + 1
y_min, y_max = x_data[:, 1].min() - 1, x_data[:, 1].max() + 1

# 生出网格矩阵
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02), np.arange(y_min, y_max, 0.02))

# 特征处理+维度转换
z = sigmoid(poly_reg.fit_transform(np.c_[xx.ravel(), yy.ravel()]).dot(np.array(ws)))

for i in range(len(z)):
    if z[i] >= 0.5:
        z[i] = 1
    else:
        z[i] = 0

z = z.reshape(xx.shape)

# 等高线图
cs = plt.contourf(xx, yy, z)
plot()
plt.show()


# 预测
def predict(x_data, ws):
    if scale == True:
        x_data = preprocessing(x_data)
    xMat = np.mat(x_data)
    ws = np.mat(ws)
    return [1 if x >= 0.5 else 0 for x in sigmoid(xMat * ws)]


predictions = predict(x_poly, ws)

print(classification_report(y_data, predictions))

3).结果展示:

①.数据

逻辑回归预测癌症的数据集 逻辑回归预测准确率_数据_03

②.图像

逻辑回归预测癌症的数据集 逻辑回归预测准确率_数据_04

实战2: sklearn—非线性逻辑回归:

1).代码

import matplotlib.pyplot as plt
import numpy as np
from sklearn import linear_model
from sklearn.preprocessing import PolynomialFeatures
from sklearn.datasets import make_gaussian_quantiles

# 生成二维正态分布,生成的数据按分位数分为两类,500个样本,2个样本特征
# 可以生成两类或多类数据
x_data, y_data = make_gaussian_quantiles(n_samples=500, n_features=2, n_classes=2)
plt.scatter(x_data[:, 0], x_data[:, 1], c=y_data)
plt.show()

# 定义多项式回归,degree的值可以调节多形式的特征
poly_reg = PolynomialFeatures(degree=5)

# 特征处理
x_poly = poly_reg.fit_transform(x_data)

# 定义并训练模型
logistic = linear_model.LogisticRegression()
logistic.fit(x_poly, y_data)

# 获取数值所在范围
x_min, x_max = x_data[:, 0].min() - 1, x_data[:, 0].max() + 1
y_min, y_max = x_data[:, 1].min() - 1, x_data[:, 1].max() + 1

# 生成网络矩阵
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02), np.arange(y_min, y_max, 0.02))

z = logistic.predict(poly_reg.fit_transform(np.c_[xx.ravel(), yy.ravel()]))

z = z.reshape(xx.shape)

# 绘制等高线
cs = plt.contourf(xx, yy, z)

# 样本散点图
plt.scatter(x_data[:, 0], x_data[:, 1], c=y_data)

plt.show()

print('score:', logistic.score(x_poly, y_data))

2).结果展示:

①.数据

逻辑回归预测癌症的数据集 逻辑回归预测准确率_数据_05

②.图像

逻辑回归预测癌症的数据集 逻辑回归预测准确率_数据_06