机器学习-Logistic回归

来源:互联网 发布:mac启动盘重装系统 编辑:程序博客网 时间:2024/06/07 16:51

一 开发环境:win7 64 位 + Pycharm5.0 + python3.4.4


二 工具包:numpy + matplotlib (对于microsoft visual c++ 10.0 is required错误,我是通过下载microsoft visual c++ 10.0解决的)


三 参考书籍:机器学习实战

Logistic回归:

优点:计算代价不高,易于理解和实现;

缺点:容易欠拟合,分类精度可能不高;

适用数据类型:数值型和标称型数据;

一般流程:

1)收集数据:可以使用任何方法;

2)数据准备:需要数值型,以结构化数据格式最佳;

3)分析数据:可以使用任何方法;

4)训练算法:大部分时间将用于训练,训练的目的是为了找到最佳的分类回归系数;

5)测试算法:训练完成后将很快进行分类;

四 程序清单:

# 初始化数据集def loadDataSet():   dataMat = []   labelMat = []   fr = open('testSet.txt')   for line in fr.readlines():      lineArr = line.strip().split()      dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])      labelMat.append(int(lineArr[2]))   return dataMat, labelMat
# sigmoid函数;intX:输入向量与特征参数向量乘积相加的和向量def sigmoid(intX):   # 使用的是numpy中的exp方法   # 使用math中exp方法抛出TypeError: only length-1 arrays can be converted to Python scalars   # print(-intX, ':', exp(-intX))   return 1.0/(1 + exp(-intX))

1.梯度上升法:

# 梯度向上优化算法;dataMatIn:输入向量;classLabels:类别标签向量def gradAscent(dataMatIn, classLabels):   dataMatrix = mat(dataMatIn)   labelMat = mat(classLabels).transpose()   m, n = shape(dataMatrix)   alpha = 0.001   maxCycle = 500   weights = ones((n, 1))   for k in range(maxCycle):  # maxCycle次矩阵乘法运算      h = sigmoid(dataMatrix*weights)      error = (labelMat - h)      weights = weights + alpha * dataMatrix.transpose() * error   return weights
2.随机梯度上升算法:

# 随机梯度上升算法def stocGradAscent0(dataMatrix, classLabels):   m, n = shape(dataMatrix)   alpha = 0.01   weights = ones(n)   for i in range(m):  # m次      h = sigmoid(sum(dataMatrix[i] * weights))      error = classLabels[i] - h      weights = weights + alpha * error * dataMatrix[i]   return weights
3.改进的随机梯度上升算法

# 改进的随机梯度上升算法def stocGradAscent1(dataMatrix, classLabels, numIter=150):   m, n = shape(dataMatrix)   weigths = ones(n)   dataIndex = list(range(m))   for j in range(numIter):  # numIter * m      dataIndex = list(range(m))      for i in range(m):         alpha = 4/(1.0 + j + i) + 0.01         # 在每次迭代的时候都会调整,缓解数据波动或是高频波动         # 随着迭代次数增加alpha不断减小,但不会为0,确保多次别迭代后数据仍有一定的影响         randIndex = int(random.uniform(0, len(dataIndex)))         #  通过随机选取样本更新回归系数,减少周期性的波动         h = sigmoid(sum(dataMatrix[randIndex] * weigths))         error = classLabels[randIndex] - h         weigths = weigths + alpha *error * dataMatrix[randIndex]         del(dataIndex[randIndex])   return weigths
4.对于testSet.txt画出决策边界

# 画出数据集和Logistic回归最佳拟合直线的函数;weights:最佳参数向量def poltBestFit(weights):   dataMat, labelMat = loadDataSet()   dataArr = array(dataMat)   n = shape(dataArr)[0]   xcord1 = []   ycord1 = []   xcord2 = []   ycord2 = []   for i in range(n):  # 将类别为1的点x坐标和y坐标分别添加到xcord1和ycord1      if int(labelMat[i]) == 1:         xcord1.append(dataArr[i, 1])         ycord1.append(dataArr[i, 2])      else:   # 将类别为0的点x坐标和y坐标分别添加到xcord2和ycord2         xcord2.append(dataArr[i, 1])         ycord2.append(dataArr[i, 2])   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='blue')   x = arange(-3.0, 3.0, 0.1)  # x取值范围在-3.0到3.0   print('0:', weights[0])   print('1:', weights[1])   print('2:', weights[2])   y = (-weights[0] - weights[1] * x)/weights[2]  # y关于x的表达式   ax.plot(x, y)   plt.xlabel('X1')  # 设置横轴标注   plt.ylabel('X2')  # 设置纵轴标注   plt.show()

                                                            下图为随机梯度算法在上述数据集上的执行结果


                                                  下图为改进的随机梯度上升算法在上述数据集上的执行结果


                                                               下图为梯度上升算法在上述数据集500次迭代后的执行结果


5.应用:从疝气病症预测病马的死亡率

#  分类函数def classifyVector(intX, weigths):   prob = sigmoid(sum(intX * weigths))   if prob > 0.5:      return 1.0   else:      return 0.0
# 测试函数def colicTest():   frTrain = open('horseColicTraining.txt')   frTest = open('horseColicTest.txt')   trainingSet = []   trainingLabels = []   for line in frTrain.readlines():      currLine = line.strip().split('\t')      lineArr = []      for i in range(21):         lineArr.append(float(currLine[i]))      trainingSet.append(lineArr)      trainingLabels.append(float(currLine[21]))   startTime = time.clock()   trainWeigths = stocGradAscent1(array(trainingSet), trainingLabels)   # trainWeigths = stocGradAscent0(array(trainingSet), trainingLabels)   # trainWeigths = gradAscent(trainingSet, trainingLabels)   endTime = time.clock()   errorCount = 0   numTestVec = 0.0   for line in frTest.readlines():      numTestVec += 1.0      currLine = line.strip().split('\t')      lineArr = []      for i in range(21):         lineArr.append(float(currLine[i]))      if int(classifyVector(array(lineArr), trainWeigths)) != int(currLine[21]):         errorCount += 1   errorRate = (float(errorCount)/numTestVec)   print('the error rate of this is:{}'.format(errorRate), ' Running time:', (endTime - startTime), 's')   return errorRate
def multiTest():   numTests = 10   errorSum = 0.0   for k in range(numTests):      errorSum += colicTest()   print('after {} iterations the average error rate is:{}'.format(numTests, errorSum/float(numTests)))
                                                                               改进随机梯度算法-1次迭代


                                                                            改进随机梯度算法-150次迭代


                                                                        改进随机梯度算法-500次迭代


                                                使用随机梯度上升算法进行疝气病症预测病马死亡率结果


                                                              使用梯度上升算法进行疝气病症预测病马死亡率结果


五 数据集和源码:

http://pan.baidu.com/s/1mgRrnZy

0 0
原创粉丝点击