{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from numpy import *\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 训练算法 使用梯度上升找到最佳参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 使用 Logistic 回归在简单数据集上的分类\n",
    "\n",
    "# 解析数据\n",
    "def loadDataSet(file_name):\n",
    "    '''\n",
    "    Desc: \n",
    "        加载并解析数据\n",
    "    Args:\n",
    "        file_name -- 文件名称,要解析的文件所在磁盘位置\n",
    "    Returns:\n",
    "        dataMat -- 原始数据的特征\n",
    "        labelMat -- 原始数据的标签,也就是每条样本对应的类别\n",
    "    '''\n",
    "    # dataMat为原始数据, labelMat为原始数据的标签\n",
    "    dataMat = []; labelMat = []\n",
    "    fr = open(file_name)\n",
    "    for line in fr.readlines():\n",
    "        lineArr = line.strip().split()\n",
    "        # 为了方便计算,我们将 X0 的值设为 1.0 ,也就是在每一行的开头添加一个 1.0 作为 X0\n",
    "        dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])\n",
    "        labelMat.append(int(lineArr[2]))\n",
    "    return dataMat,labelMat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# sigmoid跳跃函数\n",
    "def sigmoid(inX):\n",
    "    return 1.0/(1+exp(-inX))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 正常的处理方案\n",
    "# 两个参数:第一个参数==> dataMatIn 是一个2维NumPy数组,每列分别代表每个不同的特征,每行则代表每个训练样本。\n",
    "# 第二个参数==> classLabels 是类别标签,它是一个 1*100 的行向量。为了便于矩阵计算,需要将该行向量转换为列向量,做法是将原向量转置,再将它赋值给labelMat。\n",
    "def gradAscent(dataMatIn, classLabels):\n",
    "    '''\n",
    "    Desc:\n",
    "        正常的梯度上升法\n",
    "    Args:\n",
    "        dataMatIn -- 输入的 数据的特征 List\n",
    "        classLabels -- 输入的数据的类别标签\n",
    "    Returns:\n",
    "        array(weights) -- 得到的最佳回归系数\n",
    "    '''\n",
    "\n",
    "    # 转化为矩阵[[1,1,2],[1,1,2]....]\n",
    "    dataMatrix = mat(dataMatIn)             # 转换为 NumPy 矩阵\n",
    "    # 转化为矩阵[[0,1,0,1,0,1.....]],并转制[[0],[1],[0].....]\n",
    "    # transpose() 行列转置函数\n",
    "    # 将行向量转化为列向量   =>  矩阵的转置\n",
    "    labelMat = mat(classLabels).transpose() # 首先将数组转换为 NumPy 矩阵,然后再将行向量转置为列向量\n",
    "    # m->数据量,样本数 n->特征数\n",
    "    m,n = shape(dataMatrix)\n",
    "    # print m, n, '__'*10, shape(dataMatrix.transpose()), '__'*100\n",
    "    # alpha代表向目标移动的步长\n",
    "    alpha = 0.001\n",
    "    # 迭代次数\n",
    "    maxCycles = 500\n",
    "    # 生成一个长度和特征数相同的矩阵,此处n为3 -> [[1],[1],[1]]\n",
    "    # weights 代表回归系数, 此处的 ones((n,1)) 创建一个长度和特征数相同的矩阵,其中的数全部都是 1\n",
    "    weights = ones((n,1))\n",
    "    for k in range(maxCycles):              #heavy on matrix operations\n",
    "        # m*3 的矩阵 * 3*1 的单位矩阵 = m*1的矩阵\n",
    "        # 那么乘上单位矩阵的意义,就代表:通过公式得到的理论值\n",
    "        # 参考地址: 矩阵乘法的本质是什么? https://www.zhihu.com/question/21351965/answer/31050145\n",
    "        # print 'dataMatrix====', dataMatrix \n",
    "        # print 'weights====', weights\n",
    "        # n*3   *  3*1  = n*1\n",
    "        h = sigmoid(dataMatrix*weights)     # 矩阵乘法\n",
    "        # print 'hhhhhhh====', h\n",
    "        # labelMat是实际值\n",
    "        error = (labelMat - h)              # 向量相减\n",
    "        # 0.001* (3*m)*(m*1) 表示在每一个列上的一个误差情况,最后得出 x1,x2,xn的系数的偏移量\n",
    "        weights = weights + alpha * dataMatrix.transpose() * error # 矩阵乘法,最后得到回归系数\n",
    "    return array(weights)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 4.12414349],\n",
       "       [ 0.48007329],\n",
       "       [-0.6168482 ]])"
      ]
     },
     "execution_count": 104,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataArr, labelMat = loadDataSet(\"testSet.txt\")\n",
    "dataArr = mat(dataArr)\n",
    "#labelMat = mat(labelMat)\n",
    "\n",
    "\n",
    "gradAscent(dataArr, labelMat)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 分析数据:画出决策边界"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 可视化展示\n",
    "def plotBestFit(weights):\n",
    "    '''\n",
    "        Desc:\n",
    "            将我们得到的数据可视化展示出来\n",
    "        Args:\n",
    "            dataArr:样本数据的特征\n",
    "            labelMat:样本数据的类别标签,即目标变量\n",
    "            weights:回归系数\n",
    "        Returns:\n",
    "            None\n",
    "    '''\n",
    "    \n",
    "    n = shape(dataArr)[0]\n",
    "    xcord1 = []; ycord1 = []\n",
    "    xcord2 = []; ycord2 = []\n",
    "    for i in range(n):\n",
    "        if int(labelMat[i])== 1:\n",
    "            xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2])\n",
    "        else:\n",
    "            xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2])\n",
    "    fig = plt.figure()\n",
    "    ax = fig.add_subplot(111)\n",
    "    ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')\n",
    "    ax.scatter(xcord2, ycord2, s=30, c='green')\n",
    "    x = arange(-3.0, 3.0, 0.1)\n",
    "    \"\"\"\n",
    "    y的由来,卧槽,是不是没看懂?\n",
    "    首先理论上是这个样子的。\n",
    "    dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])\n",
    "    w0*x0+w1*x1+w2*x2=f(x)\n",
    "    x0最开始就设置为1叻, x2就是我们画图的y值,而f(x)被我们磨合误差给算到w0,w1,w2身上去了\n",
    "    所以: w0+w1*x+w2*y=0 => y = (-w0-w1*x)/w2   \n",
    "    \"\"\"\n",
    "    y = (-weights[0]-weights[1]*x)/weights[2]\n",
    "    ax.plot(x, y)\n",
    "    plt.xlabel('X'); plt.ylabel('Y')\n",
    "    plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nIiISyP8HcwUy4u5S5ZgAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1152134e0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "weights = gradAscent(dataArr, labelMat)\n",
    "plotBestFit(weights)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "### 训练算法:随机梯度上升"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 随机梯度上升\n",
    "# 梯度上升优化算法在每次更新数据集时都需要遍历整个数据集,计算复杂都较高\n",
    "# 随机梯度上升一次只用一个样本点来更新回归系数\n",
    "def stocGradAscent0(dataMatrix, classLabels):\n",
    "    '''\n",
    "    Desc:\n",
    "        随机梯度上升,只使用一个样本点来更新回归系数\n",
    "    Args:\n",
    "        dataMatrix -- 输入数据的数据特征(除去最后一列)\n",
    "        classLabels -- 输入数据的类别标签(最后一列数据)\n",
    "    Returns:\n",
    "        weights -- 得到的最佳回归系数\n",
    "    '''\n",
    "    m,n = shape(dataMatrix)\n",
    "    alpha = 0.01\n",
    "    # n*1的矩阵\n",
    "    # 函数ones创建一个全1的数组\n",
    "    weights = ones(n)   # 初始化长度为n的数组,元素全部为 1\n",
    "    for i in range(m):\n",
    "        # sum(dataMatrix[i]*weights)为了求 f(x)的值, f(x)=a1*x1+b2*x2+..+nn*xn,此处求出的 h 是一个具体的数值,而不是一个矩阵\n",
    "        h = sigmoid(sum(dataMatrix[i]*weights))\n",
    "        # print 'dataMatrix[i]===', dataMatrix[i]\n",
    "        # 计算真实类别与预测类别之间的差值,然后按照该差值调整回归系数\n",
    "        error = classLabels[i] - h\n",
    "        # 0.01*(1*1)*(1*n)\n",
    "     #   print (weights, \"*\"*10 , dataMatrix[i], \"*\"*10 , error)\n",
    "        weights = weights + alpha * error * dataMatrix[i]\n",
    "    return weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x114ffbc18>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "weights = stocGradAscent0(array(dataArr), labelMat)\n",
    "plotBestFit(weights)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 随机梯度上升算法(随机化)\n",
    "def stocGradAscent1(dataMatrix, classLabels, numIter=150):\n",
    "    '''\n",
    "    Desc:\n",
    "        改进版的随机梯度上升,使用随机的一个样本来更新回归系数\n",
    "    Args:\n",
    "        dataMatrix -- 输入数据的数据特征(除去最后一列数据)\n",
    "        classLabels -- 输入数据的类别标签(最后一列数据)\n",
    "        numIter=150 --  迭代次数\n",
    "    Returns:\n",
    "        weights -- 得到的最佳回归系数\n",
    "    '''\n",
    "    m,n = shape(dataMatrix)\n",
    "    weights = ones(n)   # 创建与列数相同的矩阵的系数矩阵,所有的元素都是1\n",
    "    # 随机梯度, 循环150,观察是否收敛\n",
    "    for j in range(numIter):\n",
    "        # [0, 1, 2 .. m-1]\n",
    "        dataIndex = list(range(m))\n",
    "        for i in range(m):\n",
    "            # i和j的不断增大,导致alpha的值不断减少,但是不为0\n",
    "            alpha = 4/(1.0+j+i)+0.0001    # alpha 会随着迭代不断减小,但永远不会减小到0,因为后边还有一个常数项0.0001\n",
    "            # 随机产生一个 0~len()之间的一个值\n",
    "            # random.uniform(x, y) 方法将随机生成下一个实数,它在[x,y]范围内,x是这个范围内的最小值,y是这个范围内的最大值。\n",
    "            randIndex = int(random.uniform(0,len(dataIndex)))\n",
    "            # sum(dataMatrix[i]*weights)为了求 f(x)的值, f(x)=a1*x1+b2*x2+..+nn*xn\n",
    "            h = sigmoid(sum(dataMatrix[randIndex]*weights))\n",
    "            error = classLabels[randIndex] - h\n",
    "            # print weights, '__h=%s' % h, '__'*20, alpha, '__'*20, error, '__'*20, dataMatrix[randIndex]\n",
    "            weights = weights + alpha * error * dataMatrix[randIndex]\n",
    "            del(dataIndex[randIndex])\n",
    "    return weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nRK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1147b46a0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "weights = stocGradAscent1(array(dataArr), labelMat)\n",
    "plotBestFit(weights)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nCUSJQ0REAvn/wVhSp8/dqrUAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1151934e0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "weights = stocGradAscent1(array(dataArr), labelMat, 500)\n",
    "plotBestFit(weights)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 示例 从疝气病症预测病马的死亡率"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 分类函数,根据回归系数和特征向量来计算 Sigmoid的值\n",
    "def classifyVector(inX, weights):\n",
    "    '''\n",
    "    Desc: \n",
    "        最终的分类函数,根据回归系数和特征向量来计算 Sigmoid 的值,大于0.5函数返回1,否则返回0\n",
    "    Args:\n",
    "        inX -- 特征向量,features\n",
    "        weights -- 根据梯度下降/随机梯度下降 计算得到的回归系数\n",
    "    Returns:\n",
    "        如果 prob 计算大于 0.5 函数返回 1\n",
    "        否则返回 0\n",
    "    '''\n",
    "    prob = sigmoid(sum(inX*weights))\n",
    "    if prob > 0.5: return 1.0\n",
    "    else: return 0.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 打开测试集和训练集,并对数据进行格式化处理\n",
    "def colicTest():\n",
    "    '''\n",
    "    Desc:\n",
    "        打开测试集和训练集,并对数据进行格式化处理\n",
    "    Args:\n",
    "        None\n",
    "    Returns:\n",
    "        errorRate -- 分类错误率\n",
    "    '''\n",
    "    frTrain = open('horseColicTraining.txt')\n",
    "    frTest = open('horseColicTest.txt')\n",
    "    trainingSet = []\n",
    "    trainingLabels = []\n",
    "    # 解析训练数据集中的数据特征和Labels\n",
    "    # trainingSet 中存储训练数据集的特征,trainingLabels 存储训练数据集的样本对应的分类标签\n",
    "    for line in frTrain.readlines():\n",
    "        currLine = line.strip().split('\\t')\n",
    "        lineArr = []\n",
    "        for i in range(21):\n",
    "            lineArr.append(float(currLine[i]))\n",
    "        trainingSet.append(lineArr)\n",
    "        trainingLabels.append(float(currLine[21]))\n",
    "    # 使用 改进后的 随机梯度下降算法 求得在此数据集上的最佳回归系数 trainWeights\n",
    "    trainWeights = stocGradAscent1(array(trainingSet), trainingLabels, 500)\n",
    "    errorCount = 0\n",
    "    numTestVec = 0.0\n",
    "    # 读取 测试数据集 进行测试,计算分类错误的样本条数和最终的错误率\n",
    "    for line in frTest.readlines():\n",
    "        numTestVec += 1.0\n",
    "        currLine = line.strip().split('\\t')\n",
    "        lineArr = []\n",
    "        for i in range(21):\n",
    "            lineArr.append(float(currLine[i]))\n",
    "        if int(classifyVector(array(lineArr), trainWeights)) != int(currLine[21]):\n",
    "            errorCount += 1\n",
    "    errorRate = (float(errorCount) / numTestVec)\n",
    "    print (\"the error rate of this test is: %f\" % errorRate)\n",
    "    return errorRate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 121,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 调用 colicTest() 10次并求结果的平均值\n",
    "def multiTest():\n",
    "    numTests = 10\n",
    "    errorSum = 0.0\n",
    "    for k in range(numTests):\n",
    "        errorSum += colicTest()\n",
    "    print (\"after %d iterations the average error rate is: %f\" % (numTests, errorSum/float(numTests)) )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/kyzhang/anaconda/lib/python3.6/site-packages/ipykernel_launcher.py:3: RuntimeWarning: overflow encountered in exp\n",
      "  This is separate from the ipykernel package so we can avoid doing imports until\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "the error rate of this test is: 0.313433\n",
      "the error rate of this test is: 0.298507\n",
      "the error rate of this test is: 0.417910\n",
      "the error rate of this test is: 0.373134\n",
      "the error rate of this test is: 0.268657\n",
      "the error rate of this test is: 0.283582\n",
      "the error rate of this test is: 0.328358\n",
      "the error rate of this test is: 0.343284\n",
      "the error rate of this test is: 0.402985\n",
      "the error rate of this test is: 0.373134\n",
      "after 10 iterations the average error rate is: 0.340299\n"
     ]
    }
   ],
   "source": [
    "multiTest()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}