从0开始实现逻辑回归算法(LogicRegression)

从0开始实现逻辑回归算法(LogicRegression)

逻辑回归(LR)算法是一个比较常见的二元分类算法,通常只预测正例的概率,如给定一个样本x,预测出来的结果为0.4,那么表示方法就是p(y=1|x)=0.4,也就是说在给定样本x的情况下,通过LR预测出来正例的概率为0.4,反之,为负例的概率为0.6,即p(y=0|x)=0.6。

逻辑回归的数学表示为Y_hat=sigmoid(X*W+b),函数原型和线性模型很相似,实质上LR本质上是一个线性模型,可以从广义线性模型和伯努利分布进行推导这个模型,本文就不做推导了。其实有一个问题一直摆在很多初学者的面前,为啥公式是这个样子的,为啥不是其它的。其实,机器学习的目标是什么,是找到一个参数,我们输入样本,输出结果。那么最简单的表示是通过一个式子来表示我们的这个过程。理论上,总有一个公式来拟合我们的数据,比如牛顿定律F=ma,其实也可以理解为一个模型,参数为a,质量m为样本,那么受到的力为F,F就是我们的目标。LR这个公式也可以这么理解。

想要实现LR并不难,主要要理解cost function和梯度的算法。如果用tensorflow这类的框架,甚至不用求梯度,只用给出cost function即可。下面我将给出LR的实现代码,这个代码是可以正常工作的,main函数就是用iris数据集进行的测试。

from sklearn import datasets
from sklearn import metrics

import matplotlib.pyplot as plt
import numpy as np


def softmax(X):
    return (np.exp(X) / (np.exp(X).sum(axis=0)))


def sigmod(X):
    return (1) / (1 + np.exp(-X))


def score(W, b, X_test, Y_test):
    m = X_test.shape[0]
    Y_ = predict(W, b, X_test)
    Y2 = np.array([1 if i > 0.5 else 0 for i in Y_]).reshape(m, 1)
    accuracy = metrics.accuracy_score(Y_test, Y2)
    return accuracy


def cost_gradient_descent(X, Y, W, b, learning_rate, lamda):
    Z = np.dot(X, W) + b
    Y_ = sigmod(Z)
    m = X.shape[0]

    Y2 = np.array([1 if i > 0.5 else 0 for i in Y_]).reshape(m, 1)
    accuracy = metrics.accuracy_score(Y, Y2)

#     J = -(Y.T.dot(np.log(Y_)) + (1 - Y).T.dot(np.log(1 - Y_))).sum() / m
#
#     W = W - (learning_rate *
#              (1 / m) * (X.T.dot(Y_ - Y)) + 0)

    J = -(Y.T.dot(np.log(Y_)) + (1 - Y).T.dot(np.log(1 - Y_))).sum() / \
        m + lamda * (np.square(W).sum(axis=0)) * (1 / (2 * m))

    W = W - (learning_rate *
             (1 / m) * (X.T.dot(Y_ - Y)) + (1 / m) * W * lamda)
    b = b - learning_rate * (1 / m) * ((Y_ - Y).sum(axis=0))
#     b = b - (learning_rate * (1 / m)
#              * ((Y_ - Y).sum(axis=0)) + (1 / m) * b * lamda)
    # b一般不进行正则化
    return J, W, b, accuracy


def predict(W, b, X):
    Z = np.dot(X, W) + b
    Y_ = sigmod(Z)
    m = X.shape[0]
    Y2 = np.array([1 if i > 0.5 else 0 for i in Y_]).reshape(m, 1)
    return Y2


def train(X, Y, iter_num=1000):
    # define parameter
    m = X.shape[0]
    n = X.shape[1]
    W = np.ones((n, 1))
    b = 0
    learning_rate = 0.01
    lamda = 0.01
    i = 0
    J = []
    Accuracy = []
    while i < iter_num:
        i = i + 1
        j, W, b, accuracy = cost_gradient_descent(
            X, Y, W, b, learning_rate, lamda)
        J.append(j)
        Accuracy.append(accuracy)
        print("step:", i, "cost:", j, "accuracy:", accuracy)
    print(W)
    print(b)
    plt.plot(J)
    plt.plot(Accuracy)
    plt.show()
    return W, b


def main():
    # construct data
    iris = datasets.load_iris()
    X, Y = iris.data, iris.target.reshape(150, 1)
    X = X[Y[:, 0] < 2]
    Y = Y[Y[:, 0] < 2]
    train(X, Y, 100)


def test():
    X = np.array([[1, 0.5], [1, 1.5], [2, 1], [3, 1]])
    m = (X.shape[0])
    n = (X.shape[1])
    Y = np.array([0, 0, 1, 0]).reshape(m, 1)
    print((Y.shape))
    print(train(X, Y, 1000))

if __name__ == '__main__':
    main()
#     test()


运行代码将输出如下:在64次迭代的时候就收敛了。代码里面实现了参数的L2正则化。

step: 62 cost: [ 0.33512973] accuracy: 0.97
step: 63 cost: [ 0.32701202] accuracy: 0.98
step: 64 cost: [ 0.31998367] accuracy: 1.0
step: 65 cost: [ 0.31388857] accuracy: 1.0

此代码是可用代码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,326评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,228评论 1 304
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,979评论 0 252
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,489评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,894评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,900评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,075评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,803评论 0 205
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,565评论 1 249
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,778评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,255评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,582评论 3 261
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,254评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,151评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,952评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,035评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,839评论 2 277

推荐阅读更多精彩内容