第三章 逻辑(Logistic)回归 对成绩进行分类

把所有的问题都转换为程序问题,可以通过程序来就问题进行求解了。

这里的模拟问题来之于Coursera 上 Andrew 的机器学习课程,问题是根据学生的两次考试成绩判断该学生是否会被录取。

数据在 这里

数据格式如下:

...
79.0327360507101,75.3443764369103,1
45.08327747668339,56.3163717815305,0
61.10666453684766,96.51142588489624,1
75.02474556738889,46.55401354116538,1
...

前面两列数据位两个科目的成绩,最后一列为是否录取的标志。

为了更加形象的观察这些数据,可以把这些数据绘制图表中。

import matplotlib.pyplot as plt
import pandas as pd


df = pd.read_csv("ex2data1.txt", header=None)
ex_data_0 = df[df[2] == 0].values
ex_data_1 = df[df[2] == 1].values

plt.scatter(ex_data_0[:,0],ex_data_0[:,1], marker='x', c='r')
plt.scatter(ex_data_1[:,0],ex_data_1[:,1], marker='o', c='g')
plt.show()

数据图形如下:

是不是已经容易观察多了,现在只要给你一个数据,放在图片中你可以根据点的位置来进行分类判断了。

现在我们需要把已知的观察数据,作为训练的数据,来训练模型求出模型的参数 $\theta$。

这里对上一节中的训练函数gradAscent做一点稍微的修改,这样我们可以看到训练时候的误差和分类渐渐接近理想的过程,不断的提高迭代的次数,把每一次训练的图片都保存在png 的目录下,可以看到误差慢慢的再减少。

#!/usr/bin/python
#coding=utf-8

"""
start python 项目
"""

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

plt.rcParams['font.sans-serif'] = ['SimHei']

def sigmoid(inX):
    return 1.0/(1+np.exp(-inX))

def gradAscent(dataMatIn, classLabels,maxCycles = 4000):
    dataMatrix = np.mat(dataMatIn)
    labelMat = np.mat(classLabels).transpose()
    m,n = np.shape(dataMatrix)
    alpha = 0.001
    weights = np.ones((n,1))
    error = 0.0
    for k in range(maxCycles):
        h = sigmoid(dataMatrix*weights)
        error = (labelMat - h)
        weights = weights + alpha * dataMatrix.transpose()* error
    return weights,error


df = pd.read_csv("ex2data1.txt", header=None)

# 想一想为什么需要添加一个df.shape[0],1 维全部为1的矩阵
train_data = pd.concat([pd.DataFrame(np.ones((df.shape[0],1))), df], axis=1).values[:,:-1]
train_labels = df.values[:,-1:]
train_labels = train_labels.transpose()[0]
ex_data_0 = df[df[2] == 0].values
ex_data_1 = df[df[2] == 1].values

for i in range(1,10,1):
    plt.figure()

    weights,error = gradAscent(train_data,train_labels,40000*i)
    print '迭代 ' + str(i)
    print 'weights:',weights
    print 'error:',np.sum(np.fabs(error))
    print
    plt.scatter(ex_data_0[:, 0], ex_data_0[:, 1], marker='x', c='r')
    plt.scatter(ex_data_1[:, 0], ex_data_1[:, 1], marker='o', c='g')

    plt.title(u"阿猫学编程 - 迭代 "   + str(i))

    x = np.arange(25, 110, 10)
    y = (-weights[0,0]-weights[1,0]*x)/weights[2,0]
    plt.plot(x, y)
    plt.savefig("png/"+str(i)+".png")

输出的结果如下:

迭代 1
weights: [[-287.60304361]
 [   6.64688566]
 [   5.14028377]]
error: 58.7661212634

迭代 2
weights: [[-440.5765795 ]
 [   3.69480405]
 [   3.40160905]]
error: 10.6292565438

迭代 3
weights: [[-529.23457359]
 [   4.37723902]
 [   2.86035351]]
error: 30.7017745021

迭代 4
weights: [[-583.52707721]
 [   4.54341767]
 [   3.76547293]]
error: 22.8273300804

迭代 5
weights: [[-625.08172275]
 [   4.74699397]
 [   4.48060405]]
error: 18.9823637933

迭代 6
weights: [[-626.48915563]
 [   4.90990087]
 [   4.96692013]]
error: 8.89022955778

迭代 7
weights: [[-612.37844675]
 [   4.77961144]
 [   4.81567921]]
error: 8.44936229379

迭代 8
weights: [[-599.34934139]
 [   4.67820704]
 [   4.62686215]]
error: 8.00111334277

迭代 9
weights: [[-587.1142939 ]
 [   4.54874417]
 [   4.49216541]]
error: 8.10605656988

把目录png 下的图片做成gif 图片,更能看出训练的过程。

转载请标明来之:http://www.bugingcode.com/

更多教程:阿猫学编程


所有评论

写了这么多年博客,收到的优秀评论少之又少。在这个属于 SNS 的时代也并不缺少向作者反馈的渠道。

还没有评论

撰写评论