精华内容
下载资源
问答
  • 实现多元逻辑回归

    千次阅读 2020-12-17 10:35:36
    逻辑回归:线性分类器,二分类 决策边界 通过前面的学习,我们知道逻辑回归是一个线性分类器,能够把线性可分的数据集分成两类,二维空间的数据都在一个平面上,可以被一条直线分成两类,这条直线就是决策边界。 在...

    课程回顾

    逻辑回归:线性分类器,二分类

    决策边界

    通过前面的学习,我们知道逻辑回归是一个线性分类器,能够把线性可分的数据集分成两类,二维空间的数据都在一个平面上,可以被一条直线分成两类,这条直线就是决策边界。
    在这里插入图片描述
    在三维空间中线性分类器的决策边界是一个平面。
    在这里插入图片描述
    在高维空间中是一个超平面。
    在这里插入图片描述

    Iris数据集

    在这节课中,我们就使用逻辑回归实现对鸢尾花的分类。

    鸢尾花数据集中一共有150个样本,每个样本中有4个属性,分别是花萼的长度和宽度,花瓣的长度和宽度。一共包括三个品种,分别是山鸢尾,变色鸢尾和维基尼亚鸢尾。

    • 150个样本
      • 4个属性
        • 花萼的长度
        • 花萼的宽度
        • 花瓣的长度
        • 花瓣的宽度
      • 1个标签
        • 山鸢尾
        • 变色鸢尾
        • 维基尼亚鸢尾

    这是把这些属性两两组合之后可视化的结果
    在这里插入图片描述
    其中蓝色的点是山鸢尾,红色的点是变色鸢尾,绿色的是维基尼亚鸢尾。

    可以看到蓝色的点和其他两种颜色的点差距比较大,选择任何两种属性的组合都能够很好的把它区分开。现在我们就选取山鸢尾和变色鸢尾这两种类型的样本,使用花鄂长度和花萼宽度,这两种属性通过逻辑回归实现对他们的分类

    第1步导入需要的库加载数据集

    鸢尾花数据集不是karas中自带的数据集,使用karas中的get_file()函数加载数据集。

    # 第1步导入需要的库加载数据集
    import tensorflow as tf
    import pandas as pd
    import numpy as np
    import matplotlib as mpl
    import matplotlib.pyplot as plt
    
    """这是iris训练数据集的下载地址"""
    TRAIN_URL = "https://download.tensorflow.org/data/iris_training.csv"
    train_path = tf.keras.utils.get_file(TRAIN_URL.split('/')[-1], TRAIN_URL)
    
    """使用pandas读取csv文件,结果是一个pandas二维数据表"""
    df_iris = pd.read_csv(train_path, header=0)
    

    第2步处理数据

    • 转化为NumPy数组
    • 提取属性和标签
    • 提取山鸢尾和变色鸢尾
    • 可视化样本
    • 属性中心化
    • 生成多元模型的属性矩阵和标签列向量
    # 第2步处理数据
    """首先把二维数据表转化为numpy数组"""
    iris = np.array(df_iris)
    """iris的训练集中有120条样本"""
    print(iris.shape)
    # (120, 5)
    
    """每条样本中有5列,前4列是属性,最后一列是标签。
    我们只取出前两列属性花萼的长度和宽度来训练模型"""
    train_x = iris[:, 0:2]
    """取出最后一列作为标签值"""
    train_y = iris[:, 4]
    print(train_x.shape, train_y.shape)
    # (120, 2) (120,)
    
    """这120个样本中有三种鸢尾花,可以采用这种方法提取出标签值为0和1的样本,也就是山鸢尾和变色鸢尾"""
    x_train = train_x[train_y < 2]
    y_train = train_y[train_y < 2]
    print(x_train.shape, y_train.shape)
    # (78, 2) (78,)
    """可以看到现在只有78条样本了"""
    
    """记录现在的样本数"""
    num = len(x_train)
    

    下面使用提取出的样本和属性绘制散点图。

    cm_pt = mpl.colors.ListedColormap(["blue", "red"])
    """使用花萼长度x_train[:, 0]和花萼宽度x_train[:, 1]作为样本点的横坐标和纵坐标
    cmap=cm_pt根据样本点的标签值确定返点的颜色,设置色彩方案
    """
    plt.scatter(x_train[:, 0], x_train[:, 1], c=y_train, cmap=cm_pt)
    plt.show()
    

    在这里插入图片描述
    之前的例程中,我们使用的都是matplotlib中预设的色彩方案,这里我们使用自己定义的色彩方案。在散点图中,蓝色的是山鸢尾,红色的是变色鸢尾,横坐标是花萼长度,纵坐标是花萼宽度。

    可以看到,这两个属性的尺度相同,因此不用进行归一化,可以直接对它们进行中心化处理。对每个属性中心化也就是按列中心化,所以选择axis=0。

    x_train = x_train - np.mean(x_train, axis=0)
    cm_pt = mpl.colors.ListedColormap(["blue", "red"])
    plt.scatter(x_train[:, 0], x_train[:, 1], c=y_train, cmap=cm_pt)
    plt.show()
    

    在这里插入图片描述
    可以看到,中心化之后样本点被整体平移。样本点的横坐标和纵坐标的均值都是0。

    下面,生成多元线性模型需要的属性矩阵X和标签列向量Y,这和多元线性回归是完全一样的。

    # 生成多元线性模型需要的属性矩阵X和标签列向量Y
    x0_train = np.ones(num).reshape(-1, 1)
    
    X = tf.cast(tf.concat((x0_train, x_train), axis=1), tf.float32)
    Y = tf.cast(y_train.reshape(-1, 1), tf.float32)
    # (78, 3) (78, 1)
    

    第3步设置超参数和显示间隔

    # 第3步设置超参数和显示间隔
    learn_rate = 0.2
    iter = 120
    display_step = 30
    

    第4步设置模型参数的初始值

    # 第4步设置模型参数的初始值
    np.random.seed(612)
    W = tf.Variable(np.random.randn(3, 1), dtype=tf.float32)
    

    这里的W是一个列向量,用三行一列的二维数组来表示

    第5步训练模型

    # 第5步训练模型
    """列表ce用来保存每一次迭代的交叉熵损失"""
    ce = []
    """acc用来保存准确率"""
    acc = []
    for i in range(0, iter + 1):
        with tf.GradientTape() as tape:
        	"""这是多元模型的sigmoid()函数
        	属性矩阵X和参数向量W相乘的结果是一个列向量,
        	因此计算得到的PRED的也是一个列向量,是每个样本的预测概率"""
            PRED = 1/(1 + tf.exp(-tf.matmul(X, W)))
            """这是计算交叉熵损失"""
            """Y*tf.math.log(PRED)+(1-Y)*tf.math.log(1-PRED)
            这一部分的结果是一个列向量,是每个样本的损失
            使用reduce_mean()函数求它们的平均值,得到平均交叉熵损失"""
            LOSS = -tf.reduce_mean(Y*tf.math.log(PRED)+(1-Y)*tf.math.log(1-PRED))
        """这是准确率也是一个数字,因为不需要对它求导,所以把它放在with语句的外面"""
        accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.where(PRED < 0.5, 0., 1.), Y), tf.float32))
    	
    	"""记录每一次迭代的损失和准确率"""
        ce.append(LOSS)
        acc.append(accuracy)
    	
    	"""更新模型参数"""
        dL_dw = tape.gradient(LOSS, W)
        W.assign_sub(learn_rate * dL_dw)
    	
    	"""输出准确率和损失"""
        if i % display_step == 0:
            print("i: %i, Acc: %f, Loss: %f" % (i, accuracy, LOSS))
    

    这是运行的结果。

    i: 0, Acc: 0.230769, Loss: 0.994269
    i: 30, Acc: 0.961538, Loss: 0.481892
    i: 60, Acc: 0.987179, Loss: 0.319128
    i: 90, Acc: 0.987179, Loss: 0.246626
    i: 120, Acc: 1.000000, Loss: 0.204982
    

    可以看到一开始的准确率只有23%,随着迭代次数的增加,准确率不断提高,最后达到了100%,同时损失也在不断下降。

    第6步可视化

    • 可视化
      • 绘制损失和准确率变化曲线
      • 绘制决策边界
      • 在训练过程中绘制决策边界
        绘制损失和准确率的变化曲线,蓝色的是损失,红色的是准确率。
    # 第6步可视化
    plt.figure(figsize=(5, 3))
    plt.plot(ce, color="blue", label="Loss")
    plt.plot(acc, color="red", label="acc")
    plt.legend()
    plt.show()
    

    在这里插入图片描述
    损失一直单调下降,所以损失变化曲线很光滑,而准确率上升到一定的数值之后,有时候会停留在某个数值一段时间,因此呈现出台阶上升的趋势。

    我们还可以绘制出线性分类器的决策边界,也就是这条绿色的直线,这是这条直线的表达式 w 1 x 1 + w 2 x 2 + w 0 = 0 w_1x_1+w_2x_2+w_0=0 w1x1+w2x2+w0=0,其中的W就是我们训练得到的模型参数,可以把它变换成这种形式 x 2 = − w 1 x 1 + w 0 w 2 x_2=-\frac{w_1x_1+w_0}{w_2} x2=w2w1x1+w0,给出一组 x 1 x_1 x1作为横坐标就可以计算出 x 2 x_2 x2,作为纵坐标。

    # 绘制决策边界
    """首先绘制散点图"""
    plt.scatter(x_train[:, 0], x_train[:, 1], c=y_train, cmap=cm_pt)
    """然后给出一组横坐标"""
    x_ = [-1.5, 1.5]
    """通过表达式二计算纵坐标"""
    y_ = -(W[1]*x_+W[0])/W[2]
    """使用这组坐标绘制直线就得到决策边界"""
    plt.plot(x_, y_, color="g")
    plt.show()
    

    在这里插入图片描述
    我们也可以把这段代码添加到模型训练的过程中,从而更加清晰的看到在迭代过程中分类边界的变化。

    # 第1步导入需要的库加载数据集
    import tensorflow as tf
    import pandas as pd
    import numpy as np
    import matplotlib as mpl
    import matplotlib.pyplot as plt
    
    TRAIN_URL = "https://download.tensorflow.org/data/iris_training.csv"
    train_path = tf.keras.utils.get_file(TRAIN_URL.split('/')[-1], TRAIN_URL)
    
    df_iris = pd.read_csv(train_path, header=0)
    
    # 第2步处理数据
    """首先把二维数据表转化为numpy数组"""
    iris = np.array(df_iris)
    """iris的训练集中有120条样本"""
    print(iris.shape)
    # (120, 5)
    
    """每条样本中有5列,前4列是属性,最后一列是标签。
    我们只取出前两列属性花萼的长度和宽度来训练模型"""
    train_x = iris[:, 0:2]
    """取出最后一列作为标签值"""
    train_y = iris[:, 4]
    print(train_x.shape, train_y.shape)
    # (120, 2) (120,)
    
    """这120个样本中有三种鸢尾花,可以采用这种方法提取出标签值为0和1的样本,也就是山鸢尾和变色鸢尾"""
    x_train = train_x[train_y < 2]
    y_train = train_y[train_y < 2]
    print(x_train.shape, y_train.shape)
    # (78, 2) (78,)
    """可以看到现在只有78条样本了"""
    
    """记录现在的样本数"""
    num = len(x_train)
    
    # 属性中心化
    x_train = x_train - np.mean(x_train, axis=0)
    cm_pt = mpl.colors.ListedColormap(["blue", "red"])
    # plt.scatter(x_train[:, 0], x_train[:, 1], c=y_train, cmap=cm_pt)
    # plt.show()
    
    # 生成多元线性模型需要的属性矩阵X和标签列向量Y
    x0_train = np.ones(num).reshape(-1, 1)
    
    X = tf.cast(tf.concat((x0_train, x_train), axis=1), tf.float32)
    Y = tf.cast(y_train.reshape(-1, 1), tf.float32)
    
    print(X.shape, Y.shape)
    
    # 第3步设置超参数和显示间隔
    learn_rate = 0.2
    iter = 120
    display_step = 30
    
    # 第4步设置模型参数的初始值
    np.random.seed(612)
    W = tf.Variable(np.random.randn(3, 1), dtype=tf.float32)
    """首先给出一组横坐标x_"""
    x_ = [-1.5, 1.5]
    """并且使用模型参数的初始值计算纵坐标y_"""
    y_ = -(W[1]*x_+W[0])/W[2]
    """在开始训练模型之前,首先绘制散点图"""
    plt.scatter(x_train[:, 0], x_train[:, 1], c=y_train, cmap=cm_pt)
    """然后使用模型参数的初始值,绘制决策边界对应的直线"""
    plt.plot(x_, y_, color="red", linewidth=3)
    """指定坐标轴的范围"""
    plt.xlim([-1.5, 1.5])
    plt.ylim([-1.5, 1.5])
    
    # 第5步训练模型
    """列表ce用来保存每一次迭代的交叉熵损失"""
    ce = []
    """acc用来保存准确率"""
    acc = []
    for i in range(0, iter + 1):
        with tf.GradientTape() as tape:
            """这是多元模型的sigmoid()函数
            属性矩阵X和参数向量W相乘的结果是一个列向量,
            因此计算得到的PRED的也是一个列向量,是每个样本的预测概率"""
            PRED = 1 / (1 + tf.exp(-tf.matmul(X, W)))
            """这是计算交叉熵损失"""
            """Y*tf.math.log(PRED)+(1-Y)*tf.math.log(1-PRED)
            这一部分的结果是一个列向量,是每个样本的损失
            使用reduce_mean()函数求它们的平均值,得到平均交叉熵损失"""
            LOSS = -tf.reduce_mean(Y * tf.math.log(PRED) + (1 - Y) * tf.math.log(1 - PRED))
        """这是准确率也是一个数字,因为不需要对它求导,所以把它放在with语句的外面"""
        accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.where(PRED < 0.5, 0., 1.), Y), tf.float32))
    
        """记录每一次迭代的损失和准确率"""
        ce.append(LOSS)
        acc.append(accuracy)
    
        """更新模型参数"""
        dL_dw = tape.gradient(LOSS, W)
        W.assign_sub(learn_rate * dL_dw)
    
        """输出准确率和损失"""
        if i % display_step == 0:
            print("i: %i, Acc: %f, Loss: %f" % (i, accuracy, LOSS))
            y_ = -(W[1]*x_+W[0])/W[2]
            plt.plot(x_, y_)
    plt.show()
    

    这是运行的结果。
    在这里插入图片描述
    这是使用初始参数时的直线
    在这里插入图片描述
    可以看到它是完全不靠谱的,分类准确率非常低。然后在训练的过程中不断调整模型参数。
    这些是对应的直线。
    在这里插入图片描述
    这是最后一次迭代得到的直线,已经能够比较好的区分开这两类样本了。
    在这里插入图片描述

    使用测试集

    第1步加载数据集

    在这个例子中我们只使用了训练集数据没有使用测试集。下面,我们在训练模型的同时使用测试集来评价模型的性能。

    这是鸢尾花的测试集文件地址,在下载训练数据集的同时下载测试数据集。

    # 使用测试集
    import tensorflow as tf
    import pandas as pd
    import numpy as np
    import matplotlib as mpl
    import matplotlib.pyplot as plt
    
    TRAIN_URL = "https://download.tensorflow.org/data/iris_training.csv"
    train_path = tf.keras.utils.get_file(TRAIN_URL.split('/')[-1], TRAIN_URL)
    TEST_URL = "https://download.tensorflow.org/data/iris_test.csv"
    test_path = tf.keras.utils.get_file(TEST_URL.split('/')[-1], TEST_URL)
    
    df_iris_train = pd.read_csv(train_path, header=0)
    df_iris_test = pd.read_csv(test_path, header=0)
    

    第2步处理数据

    """"别读取训练集和测试集中的数据,并把它们转化为numpy数组"""
    iris_train = np.array(df_iris_train)
    iris_test = np.array(df_iris_test)
    """iris的训练集中有120条样本"""
    print(iris_train.shape)
    # (120, 5)
    """可以看到测试集中有30个样本"""
    print(iris_test.shape)
    # (30, 5)
    
    """每条样本中有5列,前4列是属性,最后一列是标签。
    我们只取出前两列属性花萼的长度和宽度来训练模型"""
    train_x = iris_train[:, 0:2]
    test_x = iris_train[:, 0:2]
    """取出最后一列作为标签值"""
    train_y = iris_train[:, 4]
    test_y = iris_train[:, 4]
    
    print(train_x.shape, train_y.shape)
    # (120, 2) (120,)
    print(test_x.shape, test_y.shape)
    # (30, 2) (30,)
    
    """从训练集中提取出标签值为0和1的样本,也就是山鸢尾和变色鸢尾"""
    x_train = train_x[train_y < 2]
    y_train = train_y[train_y < 2]
    """可以训练集中有78条样本"""
    print(x_train.shape, y_train.shape)
    # (78, 2) (78,)
    
    """从测试集中提取出标签值为0和1的样本,也就是山鸢尾和变色鸢尾"""
    x_test = test_x[test_y < 2]
    y_test = test_y[test_y < 2]
    """可以测试集中有22条样本"""
    print(x_test.shape, y_test.shape)
    # (22, 2) (22,)
    
    
    """分别记录训练集合测试集中的样本数"""
    num_train = len(x_train)
    num_test = len(x_test)
    print(num_train, num_test)
    # 78,22
    
    plt.figure(figsize=(10, 3))
    cm_pt = mpl.colors.ListedColormap(["blue", "red"])
    
    plt.subplot(121)
    """绘制散点图"""
    plt.scatter(x_train[:, 0], x_train[:, 1], c=y_train, cmap=cm_pt)
    
    plt.subplot(122)
    plt.scatter(x_test[:, 0], x_test[:, 1], c=y_test, cmap=cm_pt)
    plt.show()
    

    在这里插入图片描述
    可以看到,在测试结束,这两类鸢尾花也能够被很好的。

    下面分别对训练集和测试集中的数据按列中心化。

    # 按列中心化
    x_train = x_train - np.mean(x_train, axis=0)
    x_test = x_test - np.mean(x_test, axis=0)
    

    在机器学习中,要求训练集和测试集是独立同分布的,也就是说它们具有相同的均值和方差。在样本数量有限的情况下可能无法做到完全相等,只要尽量接近就可以了。

    print(np.mean(x_train, axis=0))
    print(np.mean(x_test, axis=0))
    # [-2.61898765e-16 -5.29490981e-16]
    # [-2.61898765e-16 -5.29490981e-16]
    

    可以看到他们虽然有偏差,但是非常接近,不会影响模型的训练和测试效果,为了方便我们在使用公共数据及时最好尽量使用划分好的训练集和测试集。如果需要自己划分的话,也要注意这个独立同分布的约束。

    绘制中心化之后的散点图。

    import tensorflow as tf
    import pandas as pd
    import numpy as np
    import matplotlib as mpl
    import matplotlib.pyplot as plt
    
    TRAIN_URL = "https://download.tensorflow.org/data/iris_training.csv"
    train_path = tf.keras.utils.get_file(TRAIN_URL.split('/')[-1], TRAIN_URL)
    TEST_URL = "https://download.tensorflow.org/data/iris_test.csv"
    test_path = tf.keras.utils.get_file(TEST_URL.split('/')[-1], TEST_URL)
    
    df_iris_train = pd.read_csv(train_path, header=0)
    df_iris_test = pd.read_csv(test_path, header=0)
    # 第2步处理数据
    """"别读取训练集和测试集中的数据,并把它们转化为numpy数组"""
    iris_train = np.array(df_iris_train)
    iris_test = np.array(df_iris_test)
    """iris的训练集中有120条样本"""
    print(iris_train.shape)
    # (120, 5)
    """可以看到测试集中有30个样本"""
    print(iris_test.shape)
    # (30, 5)
    
    """每条样本中有5列,前4列是属性,最后一列是标签。
    我们只取出前两列属性花萼的长度和宽度来训练模型"""
    train_x = iris_train[:, 0:2]
    test_x = iris_test[:, 0:2]
    """取出最后一列作为标签值"""
    train_y = iris_train[:, 4]
    test_y = iris_test[:, 4]
    
    print(train_x.shape, train_y.shape)
    # (120, 2) (120,)
    print(test_x.shape, test_y.shape)
    # (30, 2) (30,)
    
    """从训练集中提取出标签值为0和1的样本,也就是山鸢尾和变色鸢尾"""
    x_train = train_x[train_y < 2]
    y_train = train_y[train_y < 2]
    """可以训练集中有78条样本"""
    print(x_train.shape, y_train.shape)
    # (78, 2) (78,)
    
    """从测试集中提取出标签值为0和1的样本,也就是山鸢尾和变色鸢尾"""
    x_test = test_x[test_y < 2]
    y_test = test_y[test_y < 2]
    """可以测试集中有22条样本"""
    print(x_test.shape, y_test.shape)
    # (22, 2) (22,)
    
    
    """分别记录训练集合测试集中的样本数"""
    num_train = len(x_train)
    num_test = len(x_test)
    print(num_train, num_test)
    # 78,22
    
    # 按列中心化
    x_train = x_train - np.mean(x_train, axis=0)
    x_test = x_test - np.mean(x_test, axis=0)
    
    print(np.mean(x_train, axis=0))
    print(np.mean(x_test, axis=0))
    # [-2.61898765e-16 -5.29490981e-16]
    # [-2.61898765e-16 -5.29490981e-16]
    
    plt.figure(figsize=(10, 3))
    cm_pt = mpl.colors.ListedColormap(["blue", "red"])
    
    plt.subplot(121)
    """绘制散点图"""
    plt.scatter(x_train[:, 0], x_train[:, 1], c=y_train, cmap=cm_pt)
    
    plt.subplot(122)
    plt.scatter(x_test[:, 0], x_test[:, 1], c=y_test, cmap=cm_pt)
    plt.show()
    

    在这里插入图片描述
    可以看到训练集和测试集中的数据都被中心化了。
    构造多元线性模型需要的属性矩阵和标签列向量。

    # 构造多元线性模型需要的属性矩阵和标签列向量。
    x0_train = np.ones(num_train).reshape(-1, 1)
    X_train = tf.cast(tf.concat((x0_train, x_train), axis=1), tf.float32)
    Y_train = tf.cast(y_train.reshape(-1, 1), tf.float32)
    print(X_train.shape, Y_train.shape)
    # (22, 3)
    
    x0_test = np.ones(num_test).reshape(-1, 1)
    X_test = tf.cast(tf.concat((x0_test, x_test), axis=1), tf.float32)
    Y_test = tf.cast(y_test.reshape(-1, 1), tf.float32)
    print(X_test.shape, Y_test.shape)
    # (22, 1)
    

    第3步设置超参数,设置模型参数初始值

    # 第3步设置超参数,设置模型参数初始值
    learn_rate = 0.2
    iter = 120
    display_step = 30
    
    np.random.seed(612)
    W = tf.Variable(np.random.randn(3, 1), dtype=tf.float32)
    

    第4步实现多元逻辑回归

    在训练模型时计算每一次迭代后训练集和测试集的损失和准确率,并记录它们。只使用训练集来更新模型参数。

    # 第4步训练模型
    """列表ce用来保存每一次迭代的交叉熵损失"""
    ce_train = []
    """acc用来保存准确率"""
    acc_train = []
    ce_test = []
    acc_test = []
    for i in range(0, iter + 1):
        with tf.GradientTape() as tape:
            """这是多元模型的sigmoid()函数
            属性矩阵X和参数向量W相乘的结果是一个列向量,
            因此计算得到的PRED的也是一个列向量,是每个样本的预测概率"""
            PRED_train = 1 / (1 + tf.exp(-tf.matmul(X_train, W)))
            """这是计算交叉熵损失"""
            """Y*tf.math.log(PRED)+(1-Y)*tf.math.log(1-PRED)
            这一部分的结果是一个列向量,是每个样本的损失
            使用reduce_mean()函数求它们的平均值,得到平均交叉熵损失"""
            LOSS_train = -tf.reduce_mean(Y_train * tf.math.log(PRED_train) + (1 - Y_train) * tf.math.log(1 - PRED_train))
    
            PRED_test = 1 / (1 + tf.exp(-tf.matmul(X_test, W)))
            LOSS_test = -tf.reduce_mean(Y_test * tf.math.log(PRED_test) + (1 - Y_test) * tf.math.log(1 - PRED_test))
        """这是准确率也是一个数字,因为不需要对它求导,所以把它放在with语句的外面"""
        accuracy_train = tf.reduce_mean(tf.cast(tf.equal(tf.where(PRED_train < 0.5, 0., 1.), Y_train), tf.float32))
        accuracy_test = tf.reduce_mean(tf.cast(tf.equal(tf.where(PRED_test < 0.5, 0., 1.), Y_test), tf.float32))
    
        """记录每一次迭代的损失和准确率"""
        ce_train.append(LOSS_train)
        acc_train.append(accuracy_train)
        ce_test.append(LOSS_test)
        acc_test.append(accuracy_test)
    
        """只使用训练集来更新模型参数"""
        dL_dw = tape.gradient(LOSS_train, W)
        W.assign_sub(learn_rate * dL_dw)
    
        """输出准确率和损失"""
        if i % display_step == 0:
            print("i: %i, TrainAcc: %f, TrainLoss: %f, TestAcc: %f, TestLoss: %f" % (i, accuracy_train, LOSS_train,
                                                                                     accuracy_test, LOSS_test))
    

    这是运行的结果。

    i: 0, TrainAcc: 0.230769, TrainLoss: 0.994269, TestAcc: 0.272727, TestLoss: 0.939684
    i: 30, TrainAcc: 0.961538, TrainLoss: 0.481892, TestAcc: 0.863636, TestLoss: 0.505456
    i: 60, TrainAcc: 0.987179, TrainLoss: 0.319128, TestAcc: 0.863636, TestLoss: 0.362112
    i: 90, TrainAcc: 0.987179, TrainLoss: 0.246626, TestAcc: 0.863636, TestLoss: 0.295611
    i: 120, TrainAcc: 1.000000, TrainLoss: 0.204982, TestAcc: 0.863636, TestLoss: 0.256212
    

    可以看到,虽然训练集的准确率达到了100%,但是测试集的准确率只有86%,训练集和测试集的损失仍然在持续下降,大家可以尝试继续训练这个模型,看下测试集的准确率是否也能够达到100%。

    第5步可视化

    分别绘制训练集合测试集的损失曲线,绘制训练集和测试集的准确率。

    # 第5步可视化
    plt.figure(figsize=(10, 3))
    plt.subplot(121)
    plt.plot(ce_train, color="blue", label="train")
    plt.plot(ce_test, color="red", label="test")
    plt.ylabel("Loss")
    plt.legend()
    
    plt.subplot(122)
    plt.plot(acc_train, color="blue", label="train")
    plt.plot(acc_test, color="red", label="test")
    plt.ylabel("Accuracy")
    plt.legend()
    
    plt.show()
    

    在这里插入图片描述
    可以看到训练集的损失下降更快,分类准确率也更高。

    现在我们就得到了一个能够区分山鸢尾和变色鸢尾的分类器,它使用花萼长度和花萼宽度这两个属性来完成对鸢尾花的分类,山鸢尾是比较容易和其他两种鸢尾花区分开的。

    在这6种可能的组合中,我们其实选择了一种难度最大的组合。
    在这里插入图片描述
    选择其他这几种属性的组合,看起来更容易把山鸢尾区分开。
    在这里插入图片描述
    另外观察,这张组图
    在这里插入图片描述
    可以发现山鸢尾的花瓣长度在这个区间中,而其他两种鸢尾在这个区间中,他们之间没有交集,也就是说我们其实只需要通过这一个属性就可以把山鸢尾区分出来,这采用一元逻辑回归就可以完成。
    在这里插入图片描述
    通过这张图可以看出来,仅用花瓣宽度也能够把山鸢尾区分开。
    在这里插入图片描述
    如果我们要把变色鸢尾和维基米亚鸢尾区分开,也就是要分开这些红色的点和绿色的点。那么应该选择哪两种属性的组合呢?采用花萼长度和花萼宽度是无法区分的。
    在这里插入图片描述
    而如果选择花瓣长度和花瓣宽度这两种属性的组合,虽然不能够把他们完全区分开,但是也可以找到一个准确率比较高的线性分类器。
    在这里插入图片描述
    那么是否有更好的办法呢?鸢尾花数据集中有4个属性,这个图中只是给出了两种属性组合的情况,如果采用三种或者4种属性去训练模型,能否把变色鸢尾和维吉尼亚鸢尾完全区分开呢,大家可以尝试一下并记录你的结果。

    展开全文
  • 多元逻辑回归与多元回归区别What do James Bond, Deepak Chopra, and Einstein have in common? They browse automatically in multiverses. You can, too, and make it harder to be tracked. James Bond,Deepak ...

    多元逻辑回归与多元回归区别

    What do James Bond, Deepak Chopra, and Einstein have in common? They browse automatically in multiverses. You can, too, and make it harder to be tracked.

    James Bond,Deepak Chopra和Einstein有什么共同点? 他们自动浏览多元宇宙。 您也可以,使其更难以跟踪。

    It all started reading this article in DEV.to.

    一切都开始在DEV.to中阅读本文

    Firefox is indeed a great browser, I said in the comment section. And mentioned my favorite add-on.

    在评论部分中说Firefox确实是一个很棒的浏览器。 并提到了我最喜欢的附加组件。

    树样式标签,我最喜欢的附件 (Tree Style Tabs, my favorite add-on)

    I mentioned how I can’t live without my favorite add-on Tree Style Tabs.

    我提到了如果没有我最喜欢的附加树样式选项卡,我将无法生存。

    This add-on allows me to comfortably see all of my open tabs in a vertical column to the left of the browser rather than on an unreadable list on the top of the browser:

    这个附加组件使我可以在浏览器左侧的垂直列中舒适地查看所有打开的选项卡,而不是浏览器顶部的不可读列表中:

    Image for post

    As you can see in the image, new tabs open in a tree-style fashion. This conveniently puts some order in an otherwise hectic sea of tabs. It also adds readability and makes it easier to find a tab-needle in the haystack.

    如您在图像中看到的,新选项卡以树形样式打开。 这可以方便地在繁忙的制表符海洋中下订单。 它还增加了可读性,并使在干草堆中更容易找到a针。

    If you need horizontal space back, the sidebar can be conveniently closed/opened using a keyboard shortcut, like a boss.

    如果需要向后水平空间,则可以使用键盘快捷键(例如老板)方便地关闭/打开侧栏。

    If you want, you can expand the sidebar width and read the whole title of the tab. Something impossible in the default crunched upper row of tabs.

    如果需要,可以扩展侧栏的宽度并阅读选项卡的整个标题。 默认情况下,上面显示的所有行中都是不可能的。

    简介:容器标签 (Intro: Container tabs)

    So what are container tabs?

    那么什么是容器标签?

    Firefox’s Containers are like profiles, allowing you to segregate browsing activity within different profiles on your computer. This allows for some helpful features, like logging in to different accounts on the same website simultaneously. If used properly, it can also protect the user’s privacy.

    Firefox的容器类似于配置文件,可让您在计算机上的不同配置文件中分隔浏览活动。 这提供了一些有用的功能,例如同时登录同一网站上的不同帐户。 如果使用得当,它还可以保护用户的隐私。

    Before the advent of containers, opening different sessions (think usernames/passwords) of the same domain could only be achieved opening different browsers.

    在容器出现之前,只能通过打开不同的浏览器来实现打开同一域的不同会话(认为用户名/密码)。

    Using containers, you can open in separate containers different sessions in the same browser. Each session does not know about the other ones.

    使用容器,可以在同一浏览器中的不同会话中的单独容器中打开。 每个会话都不了解其他会话。

    That is, I can be logged in with different users in the same domain in the same browser! This is pretty handy.

    也就是说,我可以在同一浏览器中以同一域中的不同用户身份登录! 这很方便。

    As another example, for a developer workflow, this means you can be logged in and website as different users in the same browser at the same time.

    再举一个例子,对于开发人员工作流程,这意味着您可以同时在同一浏览器中以不同用户的身份登录网站。

    快来多帐户容器 (Come Multi-account containers)

    In the comments’ back-n-forth, @citizen428 mentioned a very useful add-on: Multi-Account Containers!

    在评论的后面, @ citizen428提到了一个非常有用的附加组件: Multi-Account Containers

    This add-on automatically opens domains you choose in separate containers.

    此加载项自动在单独的容器中打开您选择的域。

    So, for example, you can automatically always open all of *.google.com’s universe in a separate container. Google’s cookies, sessions, etc, will be kept separate from any other domain you open (as if you were using a separate browser).

    因此,例如,您可以始终自动在单独的容器中打开* .google.com的所有Universe。 Google的Cookie,会话等将与您打开的任何其他域(例如,使用单独的浏览器)保持独立。

    最后成分:每个领域的一次性,临时容器 (Last ingredient: disposable, temporary containers for every domain)

    All other domains that you don’t configure to always open in a particular container will open in the same container as the parent tab.

    您未配置为始终在特定容器中打开的所有其他域将在与父选项卡相同的容器中打开。

    However, there is a nifty add-on that I’m testing. It is called Temporary Containers.

    但是,我正在测试一个漂亮的附加组件。 它称为临时容器

    This one is not yet “recommended by Mozilla”, but it is very promising and Mozilla should definitely have a closer look at it. And if you’re still reading, probably you should too.

    尚未“被Mozilla推荐”,但它非常有前途,Mozilla绝对应该对其进行仔细研究。 如果您仍在阅读,也许您也应该阅读。

    With Temporary Containers, all tabs that are not configured to open in a specified container (yes, it is compatible with Multi-Account Containers!) will open in a temporary container. From their wiki:

    使用临时容器,所有未配置为在指定容器中打开的选项卡(是的,它与多帐户容器兼容!)将在临时容器中打开。 从他们的维基

    Automatically reopen Tabs in new Temporary Containers when

    在新的临时容器中自动重新打开标签页

    - Opening a new Tab

    -打开一个新标签页

    - A Tab tries to load a Link in the Default Container

    -标签试图将链接加载到默认容器中

    - An external Program opens a Link in the Browser

    -外部程序在浏览器中打开链接

    In combination with Multi-Account Containers

    与多帐户容器结合使用

    - Reopens Confirm Page if in Default Container so you can choose between Temporary Container and Permanent Container

    -如果在默认容器中,则重新打开“确认页面”,以便您可以在“临时容器”和“永久容器”之间进行选择

    To achieve this, all you have to do is to configure the add-on to open new domains in temporary containers.

    为此,您所要做的就是将加载项配置为在临时容器中打开新域。

    Image for post
    Option to open different domaing in a new temporary container.
    选择在新的临时容器中打开其他域。

    无开销:临时容器会自动删除 (No overhead: temporary containers are automatically deleted)

    Image for post
    Temporary containers are automatically deleted.
    临时容器将自动删除。

    Concerned about the overhead that too many containers may have? Worry not!

    是否担心太多容器可能产生的开销? 不用担心!

    There is a reason why the extension is called “temporary” containers. These temporary containers are deleted by default 15m after the last tab in the temporary container is closed. But the timeout can be manually changed.

    将扩展名称为“临时”容器是有原因的。 在关闭临时容器中的最后一个标签后,默认情况下,这些临时容器会删除15m。 但是超时可以手动更改。

    结论 (Conclusion)

    These 3 Firefox add-ons have really improved my workflow while browsing.

    这3个Firefox插件确实改善了我浏览时的工作流程。

    1. Open a sea of tabs opened vertically in a tree-style fashion, instead of being in an upper, basically unreadable row as mostly every browser’s default: Tree Style Tabs

      打开的,而不是上,基本上无法读取行中被作为主要每一个浏览器的默认树风格时尚垂直打开的选项卡的海洋,: 树样式的选项卡

    2. Open particular domains in separate containers: Multi-Account Containers

      在单独的容器中打开特定域: 多帐户容器

    3. Open all other domains in temporary, disposable, containers: Temporary Containers

      在临时的一次性容器中打开所有其他域: 临时容器

    I’m open and interested in hearing your opinion about this. How is your workflow different? Do you have recommendations?

    我很开放,很想听听您对此的看法。 您的工作流程有何不同? 你有建议吗?

    翻译自: https://medium.com/swlh/to-avoid-being-tracked-browse-in-multiverses-a96f0d613c5a

    多元逻辑回归与多元回归区别

    展开全文
  • Python机器学习的练习系列共有八个部分:在Python机器学习的练习第3部分中,我们实现了简单的和正则化的逻辑回归。但我们的解决方法有一个限制—它只适用于二进制分类。在本文中,我们将在之前的练习中扩展我们的...

    Python机器学习的练习系列共有八个部分:

    在Python机器学习的练习第3部分中,我们实现了简单的和正则化的逻辑回归。但我们的解决方法有一个限制—它只适用于二进制分类。在本文中,我们将在之前的练习中扩展我们的解决方案,以处理多级分类问题。

    在语法上快速标注,为了显示语句的输出,我在代码块中附加了一个“>”,以表明它是运行先前语句的结果。如果结果很长(超过1-2行),那么我就把它粘贴在代码块的另一个单独的块中。希望可以清楚的说明哪些语句是输入,哪些是输出。

    此练习中的任务是使用逻辑回归来识别手写数字(0-9)。首先加载数据集。与前面的示例不同,我们的数据文件是MATLAB的本体格式,不能被pandas自动识别,所以把它加载在Python中需要使用SciPy utility。

    import numpy as np

    import pandas as pd

    import matplotlib.pyplot as plt

    from scipy.io import loadmat

    %matplotlib inline

    data = loadmat('data/ex3data1.mat')

    data

    {'X': array([[ 0., 0., 0., ..., 0., 0., 0.],

    [ 0., 0., 0., ..., 0., 0., 0.],

    [ 0., 0., 0., ..., 0., 0., 0.],

    ...,

    [ 0., 0., 0., ..., 0., 0., 0.],

    [ 0., 0., 0., ..., 0., 0., 0.],

    [ 0., 0., 0., ..., 0., 0., 0.]]),

    '__globals__': [],

    '__header__': 'MATLAB 5.0 MAT-file, Platform: GLNXA64, Created on: Sun Oct 16 13:09:09 2011',

    '__version__': '1.0',

    'y': array([[10],

    [10],

    [10],

    ...,

    [ 9],

    [ 9],

    [ 9]], dtype=uint8)}

    快速检查加载到储存器中的矩阵的形状

    data['X'].shape, data['y'].shape

    > ((5000L, 400L), (5000L, 1L))

    我们已经加载了我们的数据。图像在martix X 被表现为400维的向量。这400个“特征”是原始20×20图像中每个像素的灰度强度。类标签在向量y中表示图像中数字的数字类。下面的图片给出了一些数字的例子。每个带有白色手写数字的灰色框代表我们数据集中400维的行。

    我们的第一个任务是修改逻辑回归的实现以完全向量化(即没有“for”循环),这是因为矢量化代码除了简洁扼要,还能够利用线性代数优化,并且比迭代代码快得多。我们在练习二中的成本函数实现已经向量化。所以我们在这里重复使用相同的实现。请注意,我们正在跳到最终的正则化版本。

    def sigmoid(z):

    return 1 / (1 + np.exp(-z))

    def cost(theta, X, y, learningRate):

    theta = np.matrix(theta)

    X = np.matrix(X)

    y = np.matrix(y)

    first = np.multiply(-y, np.log(sigmoid(X * theta.T)))

    second = np.multiply((1 - y), np.log(1 - sigmoid(X * theta.T)))

    reg = (learningRate / 2 * len(X)) * np.sum(np.power(theta[:,1:theta.shape[1]], 2))

    return np.sum(first - second) / (len(X)) + reg

    这个成本函数与我们在先前练习中创建的函数是相同的,如果你不确定我们如何做到这一点,在运行之前查看以前的文章。

    接下来,我们需要计算梯度的函数。我们已经在前面的练习中定义了它,我们在更新步骤中需要去掉“for”循环。这是可供参考的原始代码:

    def gradient_with_loop(theta, X, y, learningRate):

    theta = np.matrix(theta)

    X = np.matrix(X)

    y = np.matrix(y)

    parameters = int(theta.ravel().shape[1])

    grad = np.zeros(parameters)

    error = sigmoid(X * theta.T) - y

    for i in range(parameters):

    term = np.multiply(error, X[:,i])

    if (i == 0):

    grad[i] = np.sum(term) / len(X)

    else:

    grad[i] = (np.sum(term) / len(X)) + ((learningRate / len(X)) * theta[:,i])

    return grad

    梯度函数详细的阐述了如何改变一个参数,以获得一个比之前好的答案。如果你不熟悉线性代数,这一系列运作背后的数学是很难理解的。

    现在我们需要创建一个不使用任何循环的梯度函数的版本。在我们的新版本中,我们将去掉“for”循环,并使用线性代数(除了截距参数,它需要单独计算)计算每个参数的梯度。

    还要注意,我们将数据结构转换为NumPy矩阵。这样做是为了使代码看起来更像Octave,而不是数组,这是因为矩阵自动遵循矩阵运算规则与element-wise运算。我们在下面的例子中使用矩阵。

    def gradient(theta, X, y, learningRate):

    theta = np.matrix(theta)

    X = np.matrix(X)

    y = np.matrix(y)

    parameters = int(theta.ravel().shape[1])

    error = sigmoid(X * theta.T) - y

    grad = ((X.T * error) / len(X)).T + ((learningRate / len(X)) * theta)

    # intercept gradient is not regularized

    grad[0, 0] = np.sum(np.multiply(error, X[:,0])) / len(X)

    return np.array(grad).ravel()

    现在我们已经定义了成本和梯度函数,接下来创建一个分类器。对于本章练习的任务,我们有10个可能的分类,由于逻辑回归一次只能区分两个类别,我们需要一个方法去处理多类别场景。在这个练习中我们的任务是实现一对多的分类,其中k个不同类的标签导致了k个分类器,每个分类器在“class i”和“not class i”之间做决定。我们将在一个函数中完成分类器的训练,计算10个分类器的最终权重,并将权重返回作为k X(n + 1)数组,其中n是参数数。

    from scipy.optimize import minimize

    def one_vs_all(X, y, num_labels, learning_rate):

    rows = X.shape[0]

    params = X.shape[1]

    # k X (n + 1) array for the parameters of each of the k classifiers

    all_theta = np.zeros((num_labels, params + 1))

    # insert a column of ones at the beginning for the intercept term

    X = np.insert(X, 0, values=np.ones(rows), axis=1)

    # labels are 1-indexed instead of 0-indexed

    for i in range(1, num_labels + 1):

    theta = np.zeros(params + 1)

    y_i = np.array([1 if label == i else 0 for label in y])

    y_i = np.reshape(y_i, (rows, 1))

    # minimize the objective function

    fmin = minimize(fun=cost, x0=theta, args=(X, y_i, learning_rate), method='TNC', jac=gradient)

    all_theta[i-1,:] = fmin.x

    return all_theta

    这里需要注意的几点:首先,我们为theta添加了一个额外的参数(带有一列训练数据)以计算截距项。其次,我们将y从类标签转换为每个分类器的二进制值(要么是I类,要么不是I类)。最后,我们使用SciPy的较新优化API来最小化每个分类器的成本函数。API利用目标函数、初始参数集、优化方法和jacobian(梯度)函数,将优化程序找到的参数分配给参数数组。

    实现向量化代码的一个更具挑战性的部分是正确地写入所有的矩阵交互,所以通过查看正在使用的数组/矩阵的形状来做一些健全性检查是有用的,我们来看看上面的函数中使用的一些数据结构。

    rows = data['X'].shape[0]

    params = data['X'].shape[1]

    all_theta = np.zeros((10, params + 1))

    X = np.insert(data['X'], 0, values=np.ones(rows), axis=1)

    theta = np.zeros(params + 1)

    y_0 = np.array([1 if label == 0 else 0 for label in data['y']])

    y_0 = np.reshape(y_0, (rows, 1))

    X.shape, y_0.shape, theta.shape, all_theta.shape

    > ((5000L, 401L), (5000L, 1L), (401L,), (10L, 401L))

    注意,theta是一维数组,所以当它被转换为计算梯度的代码中的矩阵时,它变成一个(1×401)矩阵。 我们还要检查y中的类标签,以确保它们看起来像我们期望的。

    np.unique(data['y'])

    > array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], dtype=uint8)

    确保函数正常运行,并获得一些合理的输出。

    all_theta = one_vs_all(data['X'], data['y'], 10, 1)

    all_theta

    array([[ -5.79312170e+00, 0.00000000e+00, 0.00000000e+00, ...,

    1.22140973e-02, 2.88611969e-07, 0.00000000e+00],

    [ -4.91685285e+00, 0.00000000e+00, 0.00000000e+00, ...,

    2.40449128e-01, -1.08488270e-02, 0.00000000e+00],

    [ -8.56840371e+00, 0.00000000e+00, 0.00000000e+00, ...,

    -2.59241796e-04, -1.12756844e-06, 0.00000000e+00],

    ...,

    [ -1.32641613e+01, 0.00000000e+00, 0.00000000e+00, ...,

    -5.63659404e+00, 6.50939114e-01, 0.00000000e+00],

    [ -8.55392716e+00, 0.00000000e+00, 0.00000000e+00, ...,

    -2.01206880e-01, 9.61930149e-03, 0.00000000e+00],

    [ -1.29807876e+01, 0.00000000e+00, 0.00000000e+00, ...,

    2.60651472e-04, 4.22693052e-05, 0.00000000e+00]])

    最后一步是使用训练过的分类器预测每个图像的标签。对于这一步骤,对于每个训练实例(使用矢量化代码),我们将计算每个类的类概率,并将输出类标签分配给具有最高概率的类。

    def predict_all(X, all_theta):

    rows = X.shape[0]

    params = X.shape[1]

    num_labels = all_theta.shape[0]

    # same as before, insert ones to match the shape

    X = np.insert(X, 0, values=np.ones(rows), axis=1)

    # convert to matrices

    X = np.matrix(X)

    all_theta = np.matrix(all_theta)

    # compute the class probability for each class on each training instance

    h = sigmoid(X * all_theta.T)

    # create array of the index with the maximum probability

    h_argmax = np.argmax(h, axis=1)

    # because our array was zero-indexed we need to add one for the true label prediction

    h_argmax = h_argmax + 1

    return h_argmax

    现在我们可以使用predict_all函数为每个实例生成类预测,并了解分类器的工作情况。

    y_pred = predict_all(data['X'], all_theta)

    correct = [1 if a == b else 0 for (a, b) in zip(y_pred, data['y'])]

    accuracy = (sum(map(int, correct)) / float(len(correct)))

    print 'accuracy = {0}%'.format(accuracy * 100)

    > accuracy = 97.58%

    接近98%,相当不错,逻辑回归是一个相对简单的方法。

    展开全文
  • 二分类逻辑回归 我们定义ppp为类别为1(二分类0,1)的概率,ln⁡p1−p\ln\frac{p}{1-p}ln1−pp​表示类别为1的概率与类别为0的概率比。 ln⁡p1−p=w0+∑iwixip1−p=exp⁡w0+∑iwixip=exp⁡w0+∑iwixi1+exp⁡w0+∑...

    二分类逻辑回归

    我们定义 p p p为类别为1(二分类0,1)的概率, ln ⁡ p 1 − p \ln\frac{p}{1-p} ln1pp表示类别为1的概率与类别为0的概率比的对数,当 ln ⁡ p 1 − p > 0 \ln\frac{p}{1-p}>0 ln1pp>0,则为类别1。
    ln ⁡ p 1 − p = w 0 + ∑ i w i x i p 1 − p = exp ⁡ w 0 + ∑ i w i x i p = exp ⁡ w 0 + ∑ i w i x i 1 + exp ⁡ w 0 + ∑ i w i x i = 1 1 + exp ⁡ − ( w 0 + ∑ i w i x i ) \ln\frac{p}{1-p}=w_0+\sum_iw_ix_i\\ \frac{p}{1-p}=\exp^{w_0+\sum_iw_ix_i}\\ p=\frac{\exp^{w_0+\sum_iw_ix_i}}{1+\exp^{w_0+\sum_iw_ix_i}}\\ =\frac{1}{1+\exp^-({w_0+\sum_iw_ix_i})} ln1pp=w0+iwixi1pp=expw0+iwixip=1+expw0+iwixiexpw0+iwixi=1+exp(w0+iwixi)1
    可以看到最后的standard logistic function是sigmoid function。

    多分类逻辑回归

    以一个三分类(0,1,2)为例,定义三组二分类逻辑回归的权重 w 0 , w 1 , w 2 w^0, w^1, w^2 w0,w1,w2,则定义每个类别概率
    p ( y = 0 ) = exp ⁡ ∑ i w i 0 x i 0 ∑ j = 0 2 exp ⁡ w i j x i j p ( y = 1 ) = exp ⁡ ∑ i w i 1 x i 1 ∑ j = 0 2 exp ⁡ w i j x i j p ( y = 2 ) = exp ⁡ ∑ i w i 2 x i 2 ∑ j = 0 2 exp ⁡ w i j x i j p(y=0)=\frac{\exp^{\sum_iw_i^0x_i^0}}{\sum_{j=0}^2\exp^{w_i^jx_i^j}}\\ p(y=1)=\frac{\exp^{\sum_iw_i^1x_i^1}}{\sum_{j=0}^2\exp^{w_i^jx_i^j}}\\ p(y=2)=\frac{\exp^{\sum_iw_i^2x_i^2}}{\sum_{j=0}^2\exp^{w_i^jx_i^j}} p(y=0)=j=02expwijxijexpiwi0xi0p(y=1)=j=02expwijxijexpiwi1xi1p(y=2)=j=02expwijxijexpiwi2xi2
    可以看到最后的standard logistic function是softmax function。

    展开全文
  • 第七章 逻辑回归 - 多元逻辑回归

    千次阅读 2020-03-10 21:41:43
    第七章 逻辑回归 - 多元逻辑回归、一对多分类
  • 多元逻辑回归公式推导

    千次阅读 2019-01-17 13:16:03
    《统计学习方法》中关于多元逻辑回归公式推导,写的比较简单,正好前几天有同事对此比较疑惑,因此,在此进行详细推导,有助于大家共同学习。 首先,关于逻辑回归中二分类问题: P(Y=1∣x)=exp(ω⋅x+b)1+exp(ω⋅x+b...
  • 稀疏多元逻辑回归(SMLR)是高光谱监督分类中的重要方法,然而仅仅利用光谱信息的SMLR忽略了影像本身的空间特征,在少量监督样本下的分类精度和算法的鲁棒性仍明显不足;虽然通过引入核技巧,核稀疏多元逻辑回归(KSMLR...
  • 线性逻辑回归 本文用代码实现怎么利用sklearn来进行线性逻辑回归的计算,下面先来看看用到的数据。 这是有两行特征的数据,然后第三行是数据的标签。 python代码 首先导入包和载入数据 写一个画图的函数,把...
  • # todo 重要参数 solver & multi_class # multi_class 输入告知模型,我们要处理分类问题的模型 # 1. 输入 'ovr' 处理二分类,或者让模型使用‘一对多’的形式来处理多分类问题 # 2.'multinomial' 处理多分类,...
  • SKlearn_逻辑回归

    2018-01-11 14:31:43
    机器学习中逻辑回归的讲解,原理和代码说明的比较详细
  • matlab实现逻辑回归

    2018-04-24 10:52:05
    matlab实现逻辑回归,够字数了吗,够字数了吗,够字数了吗
  • 当我们要研究自变量与无序多分类因变量之间的关系时,就需要使用到SPSS软件带有的多元逻辑回归模型,下面我来讲解下如何使用。 一、操作演示 如图1所示,我们在IBM SPSS Statistics中建立一组数据,其中有三个变量...
  • 多元逻辑斯蒂回归,并实现随机梯度下降和L1/L2正则化项。 参照 在此基础上加入L1和L2 Regularization;关于逻辑斯蒂回归中的L1和L2正则化项详见以下两个链接: 并对输入格式进行泛化,例如可以对“Sun Weather=rainy:...
  • sigmoid function: 二项逻辑回归 (binomial logistic regression model): ...多元逻辑回归(multi-nomial logistic regression model):多分类,Y的取之集合为{1,2,...,K} softmax : ...
  • 逻辑回归实现手写数字(mnist)的分类
  • 该代码是主要基于tensorflow框架下的逻辑回归模型,使用经典的梯度下降算法来最小化误差,加了L2正则化以减小过拟合。主要是针对没有测试集的数据,利用五折交叉验证并重复十次来计算AUC值,以评估模型。
  • 可以使用阶梯函数通过逐步过程确定多重逻辑回归。此函数选择模型以最小化AIC,而不是像手册中的SAS示例那样根据p值。另请注意,在此示例中,步骤函数找到了与“ 手册”中的过程不同的模型。 通常建议不要盲目地遵循...
  • 多元线性回归 定义:回归分析中,含有两个或者两个以上自变量,称为多元回归,若自变量系数为1,则此回归为多元线性回归。...逻辑回归(分类问题的处理) 求解步骤:1)确定回归函数 (通常用Sigm...
  • 自行推导公式多元线性回归的编程一、导入文本店铺面积和营业额的关系图车站距离和营业额的关系图二、计算下图三、计算R² 一、导入文本 import pandas as pd import numpy as np import matplotlib.pyplot as plt ...
  • 线性回归,前面用Python从底层一步一个脚印用两种方法实现了回归拟合。在这个高级语言层出不穷的年代,这样做显然不明智,所以我考虑用优秀的数据分析工具——R语言(不敢说最...
  • 1.0.逻辑回归解决多元分类 1)题目: 在本次练习中,你将使用逻辑回归和神经网络来识别手写数字(从0到9)。今天,自动手写数字识别被广泛使用,从识别信封上的邮政编码到识别银行支票上的金额。这个练习将向您展示...
  • 文章目录一、 Softmax函数与多元逻辑回归二、广告时间 一、 Softmax函数与多元逻辑回归 为了之后更深入地讨论神经网络,本节将介绍在这个领域里很重要的softmax函数,它常被用来定义神经网络的损失函数(针对分类...
  • 主要介绍了PyTorch线性回归和逻辑回归实战示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 多元逻辑回归 - 小技巧(一)

    千次阅读 2018-07-16 17:45:37
    在做多元逻辑回归进行分类问题时,经常需要将某一个分类转化成vector,或者反过来的操作。比如一共有四种分类,那么第二种分类的vector就是:[0;1;0;0], 除了第二个元素为1外,其它的都为0. 所以问题为:给定一个...
  • https://blog.csdn.net/weixin_39739342/article/details/93379653 完整的数据文件及py文件
  • C++实现回归算法, 包含线性回归和逻辑回归, 代码干净, 整洁, 有注释, 具有良好的封装性, 可直接迁移使用
  • 可以使用阶梯函数通过逐步过程确定多重逻辑回归。此函数选择模型以最小化AIC。如何进行多重逻辑回归可以使用阶梯函数通过逐步过程确定多重逻辑回归。此函数选择模型以最小化AIC。通常建议不要盲目地遵循逐步程序,...
  • matlab实现的多分类逻辑回归

    热门讨论 2015-06-22 08:50:21
    matlab实现的多分类逻辑回归,用于手写数字识别

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,901
精华内容 5,160
关键字:

什么是多元逻辑回归