python实现逻辑斯蒂回归(Logistic Regression)

介绍

这次我们使用python实现逻辑回归模型。
逻辑回归模型和线性回归几乎是一回事。只是用sigmoid函数将线性模型映射了而已

区别

线性回归

  • 我们用的预测函数是 w*X+b
  • 损失函数是均方误差。
  • 优化算法:梯度下降法

逻辑回归

  • 我们要做的是分类任务,所用的预测函数是 sigmoid(w*X + b)。通过sigmoid函数,我们可以将线性函数的值限制在0-1之间,如果超过0.5的话,就算正例,否则为反例。
  • 损失函数就有点不太一样了,逻辑回归中,因为我们试图预测后验概率P,一般后验概率中的参数估计的方式是极大似然法。所以我们的损失函数是对数似然式。
  • 优化算法:对数似然式是高阶可导凸函数,简单来说就是可以用梯度下降法,牛顿法等方法求解.

code

from sklearn.datasets import load_iris
import numpy as np
import cross_validate


class Logistic_Regression:
    def __init__(self, rate, iters):
        '''
        initialize the hyperparameters
        :param rate: learning rate - decide the speed about your algorithm
        :param iters:  iterations times of gradient descent
        '''
        self.rate = float(rate)
        self.iters = int(iters)

    def sigmoid(self, x):  # sigmoid function
        return 1.0/(1 + np.exp(-x))

    def ob_func(self, theta, x):  # objecti function
        initial_x = np.sum(np.multiply(theta, x))
        return self.sigmoid(initial_x)

    def obs_func(self, theta, x):
        initial_x = np.sum(np.multiply(theta, x), axis=1)
        return self.sigmoid(initial_x)

    def loss(self, n, F, y):
        return (1/n) * (np.sum(y * np.log(F) + (1 - y) * np.log(1 - F)))

    def logistic_regression(self, x, y):
        n_feature = len(x[0])  # the number of feature
        n_sample = len(x)  # the number of train_data
        theta = np.zeros(n_feature)  # initial the parameter

        for i in range(self.iters):
            loss_value = self.loss(n_sample, self.obs_func(theta, x), y)
            print(loss_value)
            for t_x, t_y in zip(x, y):
                    theta = theta - self.rate * (1/n_sample) * (self.ob_func(theta, t_x)-t_y) * t_x

        return theta

    def data_process(self, X):
        '''
        process data to fit the model  - add bias
        :param X: initial data
        :return: processed data
        '''
        bias = np.ones(len(X))
        X = np.column_stack((X, bias))  # merge
        return X

    def fit(self, X, y):  # starting training the model
        X = self.data_process(X)
        self.theta = self.logistic_regression(X, y)
        return self.theta

    def prefict(self, X):  # predicting the data
        X = self.data_process(X)
        y = []
        for i in X:
            result = self.ob_func(self.theta, i)
            if result >0.5:
                result = 1
            else:
                result = 0
            y.append(result)
        return y


if __name__ == '__main__':
    data_x, data_y = load_iris().data[:100], load_iris().target[:100]
    train_x, train_y, text_x, text_y = cross_validate.cross(data_x, data_y)

    clf = Logistic_Regression(0.1, 400)
    clf.fit(train_x, np.array(train_y))
    prediction = clf.prefict(text_x)

    p, _ = cross_validate.accuracy(prediction, text_y)
    print('accuracy is :', p)