逻辑回归分类Iris数据集

逻辑回归原理

       逻辑回归的本质就是线性回归的一种。名称虽然是逻辑回归,但却是解决二分类问题的一种最常用方法之一。在工业界和SVM算法都是相当经典的二分类算法。

       下图是手推的逻辑回归相关概念的集合。
逻辑回归分类Iris数据集_第1张图片
       首先,线性回归所解决的问题,就是在已有的数据集基础下,使用线性函数为样本的预测函数,并通过将损失函数最小化的方法,寻找到该数据集最具有代表性的一个线性方程。 而逻辑回归是在线性函数的基础上叠加上了一个非线性函数,将线性问题转化成了非线性问题。并且使用的这个非线性函数具有二分类的良好特性。从而进行了数据的分类操作。(sigmoid, tanh等,都是良好的分类函数。) 如左上角的图所示,直线的分类方法通过分类函数映射到了一个非线性函数上,该非线性函数能直接反应二分类问题的解。

       逻辑回归里通常使用sigmoid函数是因为sigmoid函数有简单的一阶导数形式。以及良好的归一化性能。

       公式推导的就是求最大似然函数的过程。将概率相乘求对数,然后求解该方程的梯度方向,并用梯度下降法迭代求解极值。所得到的的解,就是该训练集处的分类概率最大化的值。也就是该训练集下可能的最优解之一。

逻辑回归代码实现

       将sigmoid函数和costfunction函数先列出。(虽然costfunction在运算中不参与,但可以打印出来观察梯度下降的方向是否正确。)

# define sigmoid function
def sigmoid(z):
    return 1/(1+np.exp(-z))


# define cost function
def costfunction(X, y, w):
    cost = 0
    X = np.array(X)
    y = np.array(y)
    w = np.array(w)
    size = y.shape[0]
    for i in range(size):
        if y[i] == 1:
            cost -= np.log(sigmoid(np.dot(X[i], w.T)))
        else:
            cost -= np.log(1 - sigmoid(np.dot(X[i], w.T)))
    return cost / size

       使用批量梯度下降法进行迭代。

# Batch gradient decent function
def BGD(X, y, w=1, alpha=0.8, n_iter=10000, eta=0.05):

    # make x,y,w array and calculate the size of the data set.
    X = np.array(X)
    y = np.array(y)
    w = np.ones(x.shape[1]+1) * w
    size = y.shape[0]

    # add one column for bias
    X = np.column_stack((X, np.ones(size).T))

    # do iteration
    for i in range(n_iter):
        temp = costfunction(X, y, w)
        w = w - alpha * (np.dot((sigmoid(np.dot(X, w.T)).reshape(size, 1) - y).T, X)) / size
        if i % 100 == 0:
            print('Loss is: ', costfunction(X,y,w), w)
    return w

       读取iris数据集并将数据分为训练集和测试集。

    # read data
    df = pd.read_csv("iris.data", header=None)
    x = df.iloc[0:100, [0,1,2,3]].values
    y = df.iloc[0:100, [4]].values

    # turn y into [1,-1] sets, Positive one means setosa , Negative one means versicolor
    y = np.where(y == 'Iris-setosa', 1, 0)

    # training set
    x_train = np.append(x[0:40], x[50:90]).reshape(80, 4)
    y_train = np.append(y[0:40], y[50:90]).reshape(80, 1)

    # test set
    x_test = np.append(x[40:50], x[90:100]).reshape(20, 4)
    y_test = np.append(y[40:50], y[90:100]).reshape(20, 1)

       计算并打印结果。

    # see if trained vector works for test set
    vecw = BGD(x_train, y_train)
    x_test = np.column_stack((x_test, np.ones(20).T))
    y_test_cal = sigmoid(np.dot(x_test, vecw.T))
    y_test_cal = np.where(y_test_cal >= 0.5, 1, 0)
    print(y_test_cal.T, y_test.T)

    if (y_test_cal.T == y_test.T).all():
        print('Perfectly matched')
    else:
        print('Test set doesnt matches trained vector')

       结果运行如下。
逻辑回归分类Iris数据集_第2张图片
       可以看到,第一列的损失函数的值一直在下降。后面的数组为权值加偏置的更新。
       最后的结果左右两个0,1数组完美的契合。达到了需要预测的期望。

       至此,简单的逻辑回归就完成了。

       谢谢。

你可能感兴趣的:(ML)