吴恩达《机器学习》课后测试Ex2:逻辑回归(详细Python 代码注解)基于吴恩达
参考
Part1
在第⼀部分,我们将要构建⼀个逻辑回归模型来预测,某个学⽣是否被⼤学录取。
设想你是⼤学相关部分的管理者,想通过申请学⽣两次测试的评分,来决定他们是否被录取。现在你拥有之前申请学⽣的可以⽤于训练逻辑回归的训练样本集。对于每⼀个训练样本,你有他们两次测试的评分和最后是被录取的结果。为了完成这个预测任务,我们准备构建⼀个可以基于两次测试评分来评估录取可能性的分类模型。
sigmoid 函数
做⼀个快速的检查,来确保它可以⼯作。代价函数
first 和second 都是⼀个矩阵。
计算梯度注意,我们实际上没有在这个函数中执⾏梯度下降,我们仅仅在计算⼀个梯度步长。梯度下降
可以参考Ex1中的代码。import  numpy as  np import  pandas as  pd import  matplotlib .pyplot as  plt import  scipy .optimize as  opt    # ⽤于⾼级优化
1
2
3
4h x =
θ()1+e −θX T 1# 实现sigmoid 函数def  sigmoid (z ):    return  1 / (1 + np .exp (-z ))
1
2
3# 仅⽤于测试sigmoid 函数运⾏def  sig_test ():    nums = np .arange (-10, 10, step =1)  # 以-10为起点,10为终点,步长为1的列表    fig , ax = plt .subplots (figsize =(12, 8))  # 以其他关键字参数**fig_kw 来创建图    ax .plot (nums , sigmoid (nums ), 'r')    plt .show ()
1
2
3
4
5
6
7J θ=()−[y log h x +1−y log 1−h x ]
m 1i =1∑m
(i )(θ((i )))((i ))(θ((i )))def  cost (theta , X , y ):    theta = np .matrix (theta )  # 将theta 转换为矩阵    X = np .matrix (X )  # 将X 转换为矩阵    y = np .matrix (y )  # 将y 转换为矩阵    first = np .multiply (-y , np .log (sigmoid (X * theta .T )))  # 公式第⼀项  np.multiply 将数组或矩阵对应位置相乘。    second = np .multiply ((1 - y ), np .log (1 - sigmoid (X * theta .T )))  # 公式第⼆项    return  np .sum (first - second ) / (len (X ))1
2
3
4
5
6
7J θ∂θj ∂
()
这次,我们不⾃⼰写代码实现梯度下降,我们会调⽤⼀个已有的库。这就是说,我们不⽤⾃⼰定义迭代次数和步长,功能会直接告诉我们最优解。Andrew NG在课程中⽤的是Octave的“fminunc”函数,由于我们使⽤Python,我们可以⽤scipy.optimize.fmin_tnc做同样的事情。这⾥的error 就是,,X[:, j]则是,所以term 为,即为代价函数偏导数。可参考笔记反向传
播详解。评价逻辑回归模型的预测
predictA :预测学⽣是否录取。如果⼀个学⽣exam1得分45,exam2得分85,那么他录取的概率应为0.776
predictB :看模型在训练集上的正确率怎样。给出数据以及参数后,predictB的函数会返回“1”或者“0”。然后再把这个predict函数⽤于训练集上,看准确率怎样。这⾥注意 * 和@的区别,* 星乘表⽰矩阵内各对应位置相乘,@等价于.dot()点乘表⽰求矩阵内积。
逻辑回归代码
linspace函数python此处代码是连续的,中途输出和⼀些说明单独拿出来了。# 实现梯度计算(并没有更新θ),没有梯度下降def  gradient (theta , X , y ):    theta = np .matrix (theta )  # 将theta 转换为矩阵    X = np .matrix (X )  # 将X 转换为矩阵    y = np .matrix (y )  # 将y 转换为矩阵    temp = np .matrix (np .zeros (theta .shape ))  # np.zeros(theta.shape)=[0.,0.],然后将temp 变为矩阵[0.,0.]    parameters = int (theta .ravel ().shape [1])    # theta.ravel():将多维数组theta 降为⼀维,.shape[1]是统计这个⼀维数组有多少个元素。parameters 表⽰参数    grad = np .zeros (parameters )    error = sigmoid (X * theta .T ) - y    for  i in  range (parameters ):        term = np .multiply (error , X [:, i ])  # 将误差与训练数据相乘,得到偏导数        grad [i ] = np .sum (term ) / len (X )    return  grad
1
2
3
4
5
6
7
8
9
10
11
12
13
14δ=a −y =∂z ∂C a =g (z )′=∂w ∂z a =∂w ∂C ∂w ∂z ∂z ∂C def  predictA (theta , X ):    return  sigmoid (X @ theta )def  predictB (theta , X ):    probability = sigmoid (X * theta .T )    return  [1 if  x >= 0.5 else  0 for  x in  probability ]      #⼤于0.5的数取值为1,⼩于0.5的为0
1
2
3
4
5
6
7
此处输出如下:def  ex2_1():    # 从检查数据开始    data1 = pd .read_csv ('', names =['te
xt1', 'text2', 'admitted'])    print (data1.head ())    print (data1.describe ())    # 查看数据的基本情况,包括:count ⾮空值数、mean 平均值、std 标准差、max 、min 、(25%、50%、75%)分位数        # 让我们创建两个分数的散点图,并使⽤颜⾊编码来可视化,正的(被接纳)或负的(未被接纳)    positive = data1[data1['admitted'].isin ([1])]  # isin()为筛选函数,令positive 为数据集中为1的数组    negative = data1[data1['admitted'].isin ([0])]  # isin ()为筛选函数,令positive 为数据集中为0的数组    fig , ax = plt .subplots (figsize =(12, 8))  # 以其他关键字参数**fig_kw 来创建图    # figsize=(a,b):figsize 设置图形的⼤⼩,b 为图形的宽,b 为图形的⾼,单位为英⼨    ax .scatter (positive ['text1'], positive ['text2'], s =50, c ='b', marker ='o', label ='admitted')    # x 为Exam 1,y 为Exam 2,散点⼤⼩s 设置为50,颜⾊参数c 为蓝⾊,散点形状参数marker 为圈,以关键字参数**kwargs 来设置标记参数labele 是Admitted    ax .scatter (negative ['text1'], negative ['text2'], s =50, c ='r', marker ='x', label ='not admitted')    # x 为Exam 1,y 为Exam 2,散点⼤⼩s 设置为50,颜⾊参数c 为红⾊,散点形状参数marker 为叉,以关键字参数**kwargs 来设置标记参数labele 是Not Admitted
ax .legend ()  # legend 为显⽰图例函数    ax .set_xlabel ('text 1 Score')  # 设置x 轴变量    ax .set_ylabel ('text 2 Score')  # 设置y 轴变量    plt .show ()1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20      text1      text2  admitted 0  34.623660  78.024693        01  30.286711  43.894998        02  35.847409  72.902198        03  60.182599  86.308552        14  79.032736  75.344376        1
1
2
3
4
5
6            text1      text2    admitted count  100.000000  100.000000  100.000000mean    65.644274  66.221998    0.600000std    19.458222  18.582783    0.492366min      30.058822  30.603263    0.00000025%    50.919511  48.179205    0.00000050%    67.032988  67.682381    1.00000075%    80.212529  79.360605    1.000000max      99.827858  98.869436    1.000000
1
2
3
4
5
6
7
8
9
输出如下:# 代码接上    # 初始化X ,y ,theta    data1.insert (0, 'Ones', 1)  # 在第0列插⼊表头为“ONE”的列,数值为1    cols = data1.shape [1]  # 获取表格df 的列数    X = data1.iloc [:, 0:cols - 1]  # 除最后⼀列外,取其他列的所有⾏,即X 为O 和⼈⼝组成的列表    y = data1.iloc [:, cols - 1:cols ]  # 取最后⼀列的所有⾏,即y 为利润    X = np .array (X .values )  # 将X 的各个值转换为数组    y = np .array (y .values )  # 将y 的各个值转换为数组    theta = np .zeros (3)  # 初始化theta 数组为(0,0,0)    # 检查矩阵的维度    print (X .shape , theta .shape , y .shape )    # ⽤初始θ计算代价    print (cost (theta , X , y ))    # 看看梯度计算结果    print (gradient (theta , X , y ))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16(100, 3) (3,) (100, 1)0.6931471805599453[ -0.1        -12.00921659 -11.26284221]
1
2
3
4# 代码接上    # ⽤SciPy's truncated newton (TNC )实现寻最优参数。    result = opt .fmin_tnc (func =cost , x0=theta , fprime =gradient , args =(X , y ))    print (result )    # 看看在这个结论下代价函数计算结果是什么个样⼦    print (cost (result [0], X , y ))  # result[0]:取数组result 中的第⼀个元素
1
2
3
4
5
6
7
result 返回值说明:数组:返回优化问题⽬标值;nfeval整数:function evaluations的数⽬;rc。
在进⾏优化的时候,每当⽬标优化函数被调⽤⼀次,就算⼀个function evaluation。在⼀次迭代过程中会有多次function evaluation,这个参数不等同于迭代次数,⽽往往⼤于迭代次数。
输出结果如下:
这条线便是判定边界(decision boundary)。
输出图像:(array ([-25.16131863,  0.20623159,  0.20147149]), 36, 0)0.20349770158947458
1
2
3# 代码接上    # 画出决策曲线    plotting_x1 = np .linspace (30, 100, 100)    plotting_h1 = (- result [0][0] - result [0][1] * plotting_x1) / result [0][2]    # theta^T*x=0为判定边界,x0theta0+x1theta1+x2theta2=0可得:x2=(-x0theta0-x1theta1)/theta2    fig , ax = plt .subplots (figsize =(12, 8))    ax .plot (plotting_x1, plotting_h1, 'y', label ='Prediction')    ax .scatter (positive ['text1'], positive ['text2'], s =50, c ='b', marker ='o', label ='Admitted')    ax .scatter (negative ['text1'], negative ['text2'], s =50, c ='r', marker ='x', label ='Not Admitted')    ax .legend ()    ax .set_xlabel ('Exam 1 Score')    ax .set_ylabel ('Exam 2 Score')    plt .show ()
1
2
3
4
5
6
7
8
9
10
11
12
13
14θx =T 0

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。