训练算法:使用梯度上升找到最佳参数、分析数据:画出决策边界

利用Logistic回归进行分类的主要思想是:根据现有数据对分类边界建立回归公式,以此进行分类。

最优化算法:梯度上升法和一个改进的随机梯度上升法

训练算法:使用梯度上升找到最佳参数
.read() 每次读取整个文件,.readlines()自动将文件内容分析成一个行的列表,该列表可以由 Python 的 for… in … 结构进行处理,.readline()每次只读取一行,通常比 .readlines()慢得多。仅当没有足够内存可以一次读取整个文件时,才应该使用.readline()。

Python strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。
str.strip([chars]);chars – 移除字符串头尾指定的字符序列。
返回移除字符串头尾指定的字符生成的新字符串。

str = "00000003210Runoob01230000000"; 
print str.strip( '0' );  # 去除首尾字符 0


str2 = "   Runoob      ";   # 去除首尾空格
print str2.strip();

以上实例输出结果如下:

3210Runoob0123
Runoob

Python split() 通过指定分隔符对字符串进行切片,如果参数 num 有指定值,则仅分隔 num 个子字符串
str.split(str=”“, num=string.count(str)).
str – 分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。
num – 分割次数。
返回分割后的字符串列表。

str = "Line1-abcdef \nLine2-abc \nLine4-abcd";
print str.split( );
print str.split(' ', 1 );

以上实例输出结果如下:

['Line1-abcdef', 'Line2-abc', 'Line4-abcd']
['Line1-abcdef', '\nLine2-abc \nLine4-abcd']
zeros():可以用来构造全零矩阵

>>> zeros(3)
array([ 0.,  0.,  0.])
>>> zeros((3,3))
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])

ones(): 可以用来构造全一矩阵
>>> ones((3,3))
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])

eyes(): 可以用来构造单位矩阵
>>> eye(3)
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])

.shape()
输入参数:类似数组(比如列表,元组)等,或是数组
返回:一个整型数字的元组,元组中的每个元素表示相应的数组每一维的长度

>>> e = eye(3)  
>>> e  
array([[ 1.,  0.,  0.],  
       [ 0.,  1.,  0.],  
       [ 0.,  0.,  1.]])  
>>> e.shape  
(3, 3)  

Logistic回归梯度上升优化算法:

from numpy import *

def loadDataSet():#打开文本文件testSet.txt并逐行读取
    #每行前两个值分别是X1和X2,第三个值是数据对应的类别标签
    dataMat = []; labelMat = []
    fr = open('testSet.txt')#打开文本文件testSet.txt
    for line in fr.readlines():#逐行读取
        lineArr = line.strip().split()
        dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])#存放数据X1和X2
        labelMat.append(int(lineArr[2]))#存放第三个值标签
    return dataMat,labelMat

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

def gradAscent(dataMatIn,classLabels):#dataMatIn是一个2维Numpy数组,每列分别代表每个不同的特征,每行则代表每个训练样本
    dataMatrix = mat(dataMatIn)#mat创建矩阵
    labelMat = mat(classLabels).transpose()#为了方便矩阵进行计算,将原向量进行转置
    m,n = shape(dataMatrix)
    alpha = 0.001
    maxCycles = 500
    weights = ones((n,1))#构建n行1列的全1矩阵
    for k in range(maxCycles):
        h = sigmoid(dataMatrix * weights)
        error = (labelMat - h)#计算真实类别与预测类别的差值,按照差值的方向调整回归系数
        weights = weights + alpha * dataMatrix.transpose() * error
    return weights

求得最优回归系数

>>> import logRegres
>>> from imp import reload
>>> reload(logRegres)
<module 'logRegres' from 'E:\\Python\\logRegres.py'>
>>> dataArr,labelMat=logRegres.loadDataSet()
>>> logRegres.gradAscent(dataArr,labelMat)
matrix([[ 4.12414349],
        [ 0.48007329],
        [-0.6168482 ]])

中间把readlines 写成了readLine
报错ValueError: could not convert string to float: ‘-‘

分析数据:画出决策边界
arange:

>>> np.arange(3)  
  array([0, 1, 2])  
  >>> np.arange(3.0)  
  array([ 0.,  1.,  2.])  
  >>> np.arange(3,7)  
  array([3, 4, 5, 6])  
  >>> np.arange(3,7,2)  
  array([3, 5])  
 y = (-weights[0]-weights[1]*x)/weights[2]#最佳拟合直线

在这里设置了sigmoid函数为0,0是两个分类(类别1和类别0)的分解处,因此,设定0 = w0x0 + w1x1 + w2x2,然后解出X2和X1的关系式。
getA()函数与mat()函数的功能相反,是将一个numpy矩阵转换为数组

画出数据集和Logistic回归最佳拟合直线的函数

def plotBestFit(weights):
    import matplotlib.pyplot as plt
    dataMat,labelMat = loadDataSet()
    dataArr = array(dataMat)
    n = shape(dataArr)[0]#dataArr有几行
    xcord1 = []; ycord1 = []
    xcord2 = []; ycord2 = []
    for i in range(n):
        if int(labelMat[i])==1:
            xcord1.append(dataArr[i,1]);ycord1.append(dataArr[i,2])#1为正样本
        else:
            xcord2.append(dataArr[i,1]);ycord2.append(dataArr[i, 2])#0为负样本
    fig = plt.figure() #创建一个新图形
    ax = fig.add_subplot(111)
    ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')#绘制正样本
    ax.scatter(xcord2, ycord2, s=30, c='green')#绘制负样本
    x = arange(-3.0, 3.0, 0.1)
    y = (-weights[0]-weights[1]*x)/weights[2]#最佳拟合直线
    ax.plot(x,y)
    plt.xlabel('X1');plt.ylabel('X2');
    plt.show()

这里写图片描述
尽管例子简单且数据集很小,这个方法需要大量的计(300次乘法),下一节对算法做改进。

猜你喜欢

转载自blog.csdn.net/qq_42799920/article/details/81360302