逻辑回归python梯度下降_(二十五)案例实战:Python实现逻辑回归与梯度下降策略-python数据分析与机器学习实战(学习笔记)...

文章原创,最近更新:2018-05-25

课程内容:Python实现逻辑回归与梯度下降策略

我们将建立一个逻辑回归模型来预测一个学生是否被大学录取。假设你是一个大学系的管理员,你想根据两次考试的结果来决定每个申请人的录取机会。你有以前的申请人的历史数据,你可以用它作为逻辑回归的训练集。对于每一个培训例子,你有两个考试的申请人的分数和录取决定。为了做到这一点,我们将建立一个分类模型,根据考试成绩估计入学概率。

首先读取这个文件"LogiReg_data.txt"的数据前5行,看一下数据是长什么样子的,具体代码如下:(备注:Admitted是代表是否录取的意思)

import pandas as pd

pdData=pd.read_csv("LogiReg_data.txt",header=None,names=['Exam 1', 'Exam 2', 'Admitted'])

print(pdData.head())

输出结果如下:

Exam 1 Exam 2 Admitted

0 34.623660 78.024693 0

1 30.286711 43.894998 0

2 35.847409 72.902198 0

3 60.182599 86.308552 1

4 79.032736 75.344376 1

对数据有个大致的了解之后,求出这个数据的维度,如下:

import pandas as pd

pdData=pd.read_csv("LogiReg_data.txt",header=None,names=['Exam 1', 'Exam 2', 'Admitted'])

print(pdData.shape)

输出结果如下:

(100, 3)

分别用0,1表示正例和负例.'Exam 1'以及'Exam 2'分别录取的人数的散点图

案例代码如下:

import pandas as pd

import matplotlib.pyplot as plt

pdData=pd.read_csv("LogiReg_data.txt",header=None,names=['Exam 1', 'Exam 2', 'Admitted'])

pdData.head()

print(pdData.shape)

positive=pdData[pdData["Admitted"]==1]

negative=pdData[pdData["Admitted"]==0]

fig, ax = plt.subplots(figsize=(10,5))

ax.scatter(positive['Exam 1'], positive['Exam 2'], s=30, c='b', marker='o', label='Admitted')

ax.scatter(negative['Exam 1'], negative['Exam 2'], s=30, c='r', marker='x', label='Not Admitted')

ax.legend()

ax.set_xlabel('Exam 1 Score')

ax.set_ylabel('Exam 2 Score')

输出结果如下:

蓝色的点代表是录取的,未被录取的是红色的.对两种颜色的点是否可以进画一条决策边界呢?

数据现在也有了,算法之前也推倒过了,怎么用python将逻辑回归实现出来?

首先要了解一下逻辑回归:

目标:建立分类器(求解出三个参数 θ0、θ1、θ2 )

备注:θ1对应'Exam 1'成绩,θ2对应'Exam 2'

设定阈值,根据阈值判断录取结果

备注:阈值指的是最终得到的概率值.将概率值转化成一个类别.一般是>0.5是被录取了,<0.5未被录取.

要完成的模块:

sigmoid : 映射到概率的函数

model : 返回预测结果值

cost : 根据参数计算损失

gradient : 计算每个参数的梯度方向

descent : 进行参数更新

accuracy: 计算精度

sigmoid 函数:

g:ℝ→[0,1] (值域是0到1)

g(0)=0.5 (当x=0时,y=0.5)

g(−∞)=0 (当x趋于负无穷时,y=0)

g(+∞)=1 (当x趋于正无穷时,y=1)

如果不知道sigmoid 函数长什么样子,可以看看如下的案例代码

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

def sigmoid(z):

return 1/(1+np.exp(-z))

nums=np.arange(-10,10,step=1)

fig,ax=plt.subplots(figsize=(12,4))

ax.plot(nums,sigmoid(nums),"r")

输出结果如下:

当构造一个回归模型的时候,要把数据当中插入一列,让那一列的值都等于1.要把数值计算转化成矩阵的运算.根据理论让代码实现出来,

备注:

知识点1:

np.dot()这个是矩阵的乘法,然后将数据传入到sigmoid(z),相当于以下截图的过程.

知识点2:

pdData.insert(0, 'Ones', 1)

具体用法如下:

numpy.insert(arr,obj,value,axis=None)

arr:为插入目标列的位置

obj:插入为目标列的名称

value:为想要插入列的数值

axis:为插入的维度

例如:

import pandas as pd

pdData=pd.read_csv("LogiReg_data.txt",header=None,names=['Exam 1', 'Exam 2', 'Admitted'])

pdData.insert(0, 'Ones', 1)

print(pdData.head())

输出结果如下:

One Exam 1 Exam 2 Admitted

0 1 34.623660 78.024693 0

1 1 30.286711 43.894998 0

2 1 35.847409 72.902198 0

3 1 60.182599 86.308552 1

4 1 79.032736 75.344376 1

知识点3:

pd.as_matrix()将frame转换为其Numpy数组表示。

建立一个4*2的矩阵,利用shape可输出矩阵的维度,即行数和列数。shape[0]和shape[1]分别代表多少行?和多少列?结果如图.

知识点4:

theta是当前的一个参数,虽然参数没有一个具体的值,但是也需要给参数进行占位.通常情况下,指定一个结构的时候,虽然里面的值我们不关心,但是必须有这样的位置给它创建出来.通常情况下用0进行填充,比如这里用到了theta=np.zeros([1,3]),创建了1行3列填充数据为0的矩阵.相当于构造了3个θ0、θ1、θ2参数.

构造完之后,不知道准不准?那应该怎么办呢?

首先查看x前5行对应的值是对的?

import numpy as np

import pandas as pd

pdData=pd.read_csv("LogiReg_data.txt",header=None,names=['Exam 1', 'Exam 2', 'Admitted'])

pdData.insert(0, 'Ones', 1)

orig_data=pdData.as_matrix()

cols=orig_data.shape[1]

x=orig_data[:,0:cols-1]#1-倒数第1列的数据

y=orig_data[:,cols-1:cols]#倒数第1列的数据

theta=np.zeros([1,3])#1行三列的矩阵全部填充为0

print(x[:5])

输出结果如下:

[[ 1. 34.62365962 78.02469282]

[ 1. 30.28671077 43.89499752]

[ 1. 35.84740877 72.90219803]

[ 1. 60.18259939 86.3085521 ]

[ 1. 79.03273605 75.34437644]]

输出的结果是与截图相一致的

再看看y的前5列是否有问题?

import numpy as np

import pandas as pd

pdData.insert(0, 'Ones', 1)

orig_data=pdData.as_matrix()

cols=orig_data.shape[1]

x=orig_data[:,0:cols-1]#1-倒数第1列的数据

y=orig_data[:,cols-1:cols]#倒数第1列的数据

theta=np.zeros([1,3])#1行三列的矩阵全部填充为0

print(y[:5])

输出结果如下:

[[ 0.]

[ 0.]

[ 0.]

[ 1.]

[ 1.]]

从输出的结果来看是没有问题的.

在看看theta是否有问题?

pdData.insert(0, 'Ones', 1)

orig_data=pdData.as_matrix()

cols=orig_data.shape[1]

x=orig_data[:,0:cols-1]#1-倒数第1列的数据

y=orig_data[:,cols-1:cols]#倒数第1列的数据

theta=np.zeros([1,3])#1行三列的矩阵全部填充为0

print(theta)

输出结果如下:

[[ 0. 0. 0.]]

检查完之后,在分别打印x.shape,y.shape,theta.shape的维度

pdData.insert(0, 'Ones', 1)

orig_data=pdData.as_matrix()

cols=orig_data.shape[1]

x=orig_data[:,0:cols-1]#1-倒数第1列的数据

y=orig_data[:,cols-1:cols]#倒数第1列的数据

theta=np.zeros([1,3])#1行三列的矩阵全部填充为0

print(x.shape,y.shape,theta.shape)

输出结果如下:

(100, 3) (100, 1) (1, 3)

从输出的结果来看,这三个矩阵的维度也是没有任何问题的.

接下来对数据进行组合,并得到最终的结果.

首先先定义损失函数:

将对数似然函数去负号

求平均损失

这个损失函数是怎么来的,是根据以下截图的应用梯度上升最大值得来的:(-1/n的过程分步骤,先对数似然函数去负号,再除以1/n)

这个函数用python代码怎么表达cost()这个损失函数呢?并计算这个损失函数?

import numpy as np

import pandas as pd

pdData=pd.read_csv("LogiReg_data.txt",header=None,names=['Exam 1', 'Exam 2', 'Admitted'])

def sigmoid(z):

return 1/(1+np.exp(-z))

def model(X,theta):

return sigmoid(np.dot(X,theta.T))

def cost(x,y,theta):

left=np.multiply(-y,np.log(model(x,theta)))

right=np.multiply(1-y,np.log(1-model(x,theta)))

return np.sum(left-right)/(len(x))

pdData.insert(0, 'Ones', 1)

orig_data=pdData.as_matrix()

cols=orig_data.shape[1]

x=orig_data[:,0:cols-1]#1-倒数第1列的数据

y=orig_data[:,cols-1:cols]#倒数第1列的数据

theta=np.zeros([1,3])#1行三列的矩阵全部填充为0

print(cost(x,y,theta))

输出结果如下:

0.69314718056

接下来,怎么计算梯度函数?

梯度函数是以下截图

就是求偏导,求导的过程就是以下截图的内容

构造theta参数的时候,构造的是3个参数θ0、θ1、θ2参数,算出来的梯度算几个呀?构造的时候构造了3个θ0、θ1、θ2参数,那这三个参数求解的时候,应该求出几个梯度呀?显然也是三个.具体相关知识点如下:

1)在python代码中,定义grad为梯度,用np.zeros(theta.shape)中的zeros函数进行占位.梯度应与theta.shape的维度是一致的.

2)这里的error=yi−hθ(xi),跟表达式有点相反了,原因是把负号提到里面去了.

3)np.ravel()将多维数组降为一维,返回的是视图,修改时会影响原始矩阵 .

案例代码如下:

import numpy as np

a = np.array([[1 , 2] , [3 , 4]])

c=a.ravel()

print(c)

c[0]=10

print(c)

输出结果如下:

[1 2 3 4]

[10 2 3 4]

梯度函数怎么用python表达呢?

def gradient(x, y, theta):

grad = np.zeros(theta.shape)

error = (model(x, theta)- y).ravel()

for j in range(len(theta.ravel())): #for each parmeter

term = np.multiply(error, x[:,j])

grad[0, j] = np.sum(term) / len(x)

return grad

比较3种不同梯度下降的方法,具体梯度下降的方法如下截图:

第一种策略

是按照迭代次数进行停止,因为进行模型优化的时候,可以进行迭代,在不断进行迭代的过程中,无论是多少次,最终都需要停下来.这里就设置了3种停止的策略.

比如设置迭代次数是2000次,一旦达到次数,每次进行优化,每次进行参数更新,就进行计数.迭代次数跟什么挂钩呢?就是更新一次参数就是完成了一次迭代.再更新一次参数,就是再完成了一次迭代.根据迭代次数,指定成一个值,达到了这样的一个值,就完成了更新.

第二种策略

是看一下损失函数的目标函数的变化,在迭代的过程中,可以知道迭代之前的目标函数,迭代完之后的目标函数,如果这两个目标函数差异非常小,几乎没有变化,迭代就可以停止下来.

第三种策略

根据梯度,如果前后两次迭代梯度的值差不多,几乎没啥变化,那么迭代也是可以停止下来的.

以上就是三种不同的梯度下降方法,不同的方法进行比较,看一下这三种算法得到的结果怎么样?不仅要看这三种停止策略,还要结合不同梯度下降,比如小批量的梯度下降/随机梯度下降/批量梯度下降.

首先定义一个函数,针对不同的三种停止策略,具体如下:

STOP_ITER = 0

STOP_COST = 1

STOP_GRAD = 2

def stopCriterion(type, value, threshold):

#设定三种不同的停止策略

if type == STOP_ITER: return value > threshold

elif type == STOP_COST: return abs(value[-1]-value[-2]) < threshold

elif type == STOP_GRAD: return np.linalg.norm(value) < threshold

在做迭代更新的时候,首先对数据进行洗牌,洗牌是因为现在的数据看起来是有规律的,因为数据是我们自己进行收集的,收集的过程中可能按照某种顺序.比如身高排序,比如先收集男生的再收集女生的.

为了使模型的泛化能力更强,第一步先把数据进行打乱,做一个乱序的数据,通常把这种做法叫做洗牌,也叫shuffle操作,numpy有提供这样的操作.

通过numpy中的random模块,也就是随机模块,有shuffle函数,将数据传进去就可以进行洗牌.洗牌之后,把数据重新的指定好,然后再重新指定对应的x,y.

import numpy.random

#洗牌

def shuffleData(data):

np.random.shuffle(data)

cols = data.shape[1]

x = data[:, 0:cols-1]

y = data[:, cols-1:]

return x, y

之前有说过,不同梯度下降,所消耗的时间也是不一样的.这里还要看一下时间对结果的影响.这里通过定义descent函数进行.

data这里指的是数据;theta这里指的是参数;batchSize指定成1,那就是随机梯度下降,指定成总的样本数,那就是批量梯度下降,指定正1到总体之间,那就是小批量梯度下降;thresh指的是策略对应的阈值;alpha指的是学习率.

首先初始化值,i = 0第一次迭代,k = 0第0次batch. x, y = shuffleData(data)对xy进行洗牌.

grad = gradient(x[k:k+batchSize], y[k:k+batchSize], theta)因为有三种不同的梯度下降的方法,每种方法对应数据的个数是不一样的.这里按实际传进来的数据进行计算.

theta = theta - alpha*grad参数更新的过程.

costs.append(cost(x, y, theta))将每一次迭代的损失都画出来.

按什么样的方式进行停止策略.如果到了停止的策略,则就跳出循环,直接返回一个新的结果值,就可以了.

import time

def descent(data, theta, batchSize, stopType, thresh, alpha):

#梯度下降求解

init_time = time.time()

i = 0 # 迭代次数

k = 0 # batch

x, y = shuffleData(data)

grad = np.zeros(theta.shape) # 计算的梯度

costs = [cost(x, y, theta)] # 损失值

while True:

grad = gradient(x[k:k+batchSize], y[k:k+batchSize], theta)

k += batchSize #取batch数量个数据

if k >= n:

k = 0

x, y = shuffleData(data) #重新洗牌

theta = theta - alpha*grad # 参数更新

costs.append(cost(x, y, theta)) # 计算新的损失

i += 1

if stopType == STOP_ITER: value = i

elif stopType == STOP_COST: value = costs

elif stopType == STOP_GRAD: value = grad

if stopCriterion(stopType, value, thresh): break

return theta, i-1, costs, grad, time.time() - init_time

为了使画图的时候知道当前迭代多少次,以及停止策略以及batch的一个结果,就定义了一个功能性的一个函数runExpe().

theta, iter, costs, grad, dur = descent(data, theta, batchSize, stopType, thresh, alpha)先对一个值进行初始化,然后进行求解.这是核心代码.

就是选择梯度下降的方式以及停止策略

这一部分是怎么在图上显示它的名字.是根据传进来的参数,比如是批量梯度下降or随机梯度下降or小批量梯度下降的参数.以下代码时初始化,根据选择传进来的参数,如果数据传进来一个,则是随机梯度下降方式,如果传进来的是总体则是批量梯度下降;如果传进来的是小批量的数据则是小批量梯度下降.

name = "Original" if (data[:,1]>2).sum() > 1 else "Scaled"

name += " data - learning rate: {} - ".format(alpha)

if batchSize==n: strDescType = "Gradient"

elif batchSize==1: strDescType = "Stochastic"

else: strDescType = "Mini-batch ({})".format(batchSize)

name += strDescType + " descent - Stop: "

if stopType == STOP_ITER: strStop = "{} iterations".format(thresh)

elif stopType == STOP_COST: strStop = "costs change < {}".format(thresh)

else: strStop = "gradient norm < {}".format(thresh)

name += strStop

然后下面代码就是画图以及展示得到的一个结果

fig, ax = plt.subplots(figsize=(12,4))

ax.plot(np.arange(len(costs)), costs, 'r')

ax.set_xlabel('Iterations')

ax.set_ylabel('Cost')

ax.set_title(name.upper() + ' - Error vs. Iteration')

完整的runExpe函数定义代码如下:

def runExpe(data, theta, batchSize, stopType, thresh, alpha):

#import pdb; pdb.set_trace();

theta, iter, costs, grad, dur = descent(data, theta, batchSize, stopType, thresh, alpha)

name = "Original" if (data[:,1]>2).sum() > 1 else "Scaled"

name += " data - learning rate: {} - ".format(alpha)

if batchSize==n: strDescType = "Gradient"

elif batchSize==1: strDescType = "Stochastic"

else: strDescType = "Mini-batch ({})".format(batchSize)

name += strDescType + " descent - Stop: "

if stopType == STOP_ITER: strStop = "{} iterations".format(thresh)

elif stopType == STOP_COST: strStop = "costs change < {}".format(thresh)

else: strStop = "gradient norm < {}".format(thresh)

name += strStop

print ("***{}\nTheta: {} - Iter: {} - Last cost: {:03.2f} - Duration: {:03.2f}s".format(

name, theta, iter, costs[-1], dur))

fig, ax = plt.subplots(figsize=(12,4))

ax.plot(np.arange(len(costs)), costs, 'r')

ax.set_xlabel('Iterations')

ax.set_ylabel('Cost')

ax.set_title(name.upper() + ' - Error vs. Iteration')

return theta

当n值指定为100的时候,相当于整体对于梯度下降,为什么呢?因为我的数据样本就100个.

传进来的数据是按照迭代次数进行停止的,指定迭代次数的参数是thresh=5000.学习率是alpha=0.000001.

n=100

runExpe(orig_data, theta, n, STOP_ITER, thresh=5000, alpha=0.000001)

以下是正常模型收敛的一个图的样子:

x轴是我的迭代次数,y轴是我的目标函数,随着迭代,目标函数进行一个收敛.5000次之后最终得到一个结果.共用了0.18s,完成了一个整体的迭代,速度还是比较快的,因为数据量比较小.

完整的代码如下:

import numpy as np

import pandas as pd

import time

import matplotlib.pyplot as plt

pdData=pd.read_csv("LogiReg_data.txt",header=None,names=['Exam 1', 'Exam 2', 'Admitted'])

def sigmoid(z):

return 1/(1+np.exp(-z))

def model(x,theta):

return sigmoid(np.dot(x,theta.T))

def cost(x,y,theta):

left=np.multiply(-y,np.log(model(x,theta)))

right=np.multiply(1-y,np.log(1-model(x,theta)))

return np.sum(left-right)/(len(x))

def gradient(x,y,theta):

grad=np.zeros(theta.shape)

error=(model(x,theta)-y).ravel()

for j in range(len(theta.ravel())):

term=np.multiply(error,x[:,j])

grad[0,j]=np.sum(term)/len(x)

return grad[0,j]

STOP_ITER = 0

STOP_COST = 1

STOP_GRAD = 2

def stopCriterion(type, value, threshold):

#设定三种不同的停止策略

if type == STOP_ITER: return value > threshold

elif type == STOP_COST: return abs(value[-1]-value[-2]) < threshold

elif type == STOP_GRAD: return np.linalg.norm(value) < threshold

def shuffleData(data):

np.random.shuffle(data)

cols = data.shape[1]

x = data[:, 0:cols-1]

y = data[:, cols-1:]

return x, y

def descent(data, theta, batchSize, stopType, thresh, alpha):

#梯度下降求解

init_time = time.time()

i = 0 # 迭代次数

k = 0 # batch

x, y = shuffleData(data)

grad = np.zeros(theta.shape) # 计算的梯度

costs = [cost(x, y, theta)] # 损失值

while True:

grad = gradient(x[k:k+batchSize], y[k:k+batchSize], theta)

k += batchSize #取batch数量个数据

if k >= n:

k = 0

x, y = shuffleData(data) #重新洗牌

theta = theta - alpha*grad # 参数更新

costs.append(cost(x, y, theta)) # 计算新的损失

i += 1

if stopType == STOP_ITER: value = i

elif stopType == STOP_COST: value = costs

elif stopType == STOP_GRAD: value = grad

if stopCriterion(stopType, value, thresh): break

return theta, i-1, costs, grad, time.time() - init_time

def runExpe(data, theta, batchSize, stopType, thresh, alpha):

#import pdb; pdb.set_trace();

theta, iter, costs, grad, dur = descent(data, theta, batchSize, stopType, thresh, alpha)

name = "Original" if (data[:,1]>2).sum() > 1 else "Scaled"

name += " data - learning rate: {} - ".format(alpha)

if batchSize==n: strDescType = "Gradient"

elif batchSize==1: strDescType = "Stochastic"

else: strDescType = "Mini-batch ({})".format(batchSize)

name += strDescType + " descent - Stop: "

if stopType == STOP_ITER: strStop = "{} iterations".format(thresh)

elif stopType == STOP_COST: strStop = "costs change < {}".format(thresh)

else: strStop = "gradient norm < {}".format(thresh)

name += strStop

print ("***{}\nTheta: {} - Iter: {} - Last cost: {:03.2f} - Duration: {:03.2f}s".format(

name, theta, iter, costs[-1], dur))

fig, ax = plt.subplots(figsize=(12,4))

ax.plot(np.arange(len(costs)), costs, 'r')

ax.set_xlabel('Iterations')

ax.set_ylabel('Cost')

ax.set_title(name.upper() + ' - Error vs. Iteration')

return theta

pdData.insert(0, 'Ones', 1)

orig_data=pdData.as_matrix()

cols=orig_data.shape[1]

x=orig_data[:,0:cols-1]#1-倒数第1列的数据

y=orig_data[:,cols-1:cols]#倒数第1列的数据

theta=np.zeros([1,3])#1行三列的矩阵全部填充为0

n=100

runExpe(orig_data, theta, n, STOP_ITER, thresh=5000, alpha=0.000001)

停止策略

1)设定迭代次数停止策略:设定迭代次数

如果不认为的指定迭代次数,经过多少次的迭代可以达到阈值.

n=100

runExpe(orig_data, theta, n, STOP_ITER, thresh=5000, alpha=0.000001)

更改为

n=100

runExpe(orig_data, theta, n, STOP_ITER, thresh=0.0000001, alpha=0.001)

输出结果为

之前是迭代次数达到5000次接近0.63,现在的迭代次数达到了11万次接近0.37.只要改变迭代策略的时候,相当于不手动改变迭代次数,而是通过计算机自己计算,能够满足要求就自动停止下来,而自动停止共花了24.47s.

2)根据损失值停止策略:设定阈值 1E-6, 差不多需要110 000次迭代

当梯度值<阈值的时候,进行停止.同样的实验,可以得到我们当前的结果.

runExpe(orig_data, theta, n, STOP_COST, thresh=0.000001, alpha=0.001)

3)根据梯度变化停止:设定阈值 0.05,差不多需要40 000次迭代

runExpe(orig_data, theta, n, STOP_GRAD, thresh=0.05, alpha=0.001)

对比不同的梯度下降方法

1)随机梯度下降

这里的1是当前只迭代一个样本.损失值上上下下,跳转非常厉害.这样的问题应该怎么进行一个改变呢?迭代5000次的效果并不怎么好,但是时间非常快.

runExpe(orig_data, theta, 1, STOP_ITER, thresh=5000, alpha=0.001)

有点爆炸。。。很不稳定,再来试试把学习率调小一些..

runExpe(orig_data, theta, 1, STOP_ITER, thresh=15000, alpha=0.000002)

从输出的结果来看已经接近于收敛状态了.收敛效果比较低是接近于0.63,因此收敛结果也不是很满意.

速度快,但稳定性差,需要很小的学习率

2)小批量梯度下降

原来样本是100,现在改成16.

runExpe(orig_data, theta, 16, STOP_ITER, thresh=15000, alpha=0.001)

学习率比较小,但是也有一些问题,浮动也很大,这个问题应该怎么解决呢?不再把学习率调小一些,而是换一种方案.

浮动仍然比较大,我们来尝试下对数据进行标准化 将数据按其属性(按列进行)减去其均值,然后除以其方差。最后得到的结果是,对每个属性/每列来说所有数据都聚集在0附近,方差值为1.(备注:数据标准化,后面有专题)

from sklearn import preprocessing as pp

scaled_data = orig_data.copy()

scaled_data[:, 1:3] = pp.scale(orig_data[:, 1:3])

n=100

runExpe(scaled_data, theta, n, STOP_ITER, thresh=5000, alpha=0.001)

从输出结果来看,它好多了!原始数据,只能达到达到0.61,而我们得到了0.38个在这里! 所以对数据做预处理是非常重要的.

runExpe(scaled_data, theta, n, STOP_GRAD, thresh=0.02, alpha=0.001)

更多的迭代次数会使得损失下降的更多!

theta = runExpe(scaled_data, theta, 1, STOP_GRAD, thresh=0.002/5, alpha=0.001)

随机梯度下降更快,但是我们需要迭代的次数也需要更多,所以还是用batch的比较合适!!!

runExpe(scaled_data, theta, 16, STOP_GRAD, thresh=0.002*2, alpha=0.001)

对于概率值想得到一个类别值,那怎么样把概率值转换成类别值呢?

比如>0.5认为是≤0.5认为是0,这个概率值是可以自己自定义.

比如这里>0.5认为可以被录取,≤0.5认为这个人不能被录取.

def predict(X, theta):

return [1 if x >= 0.5 else 0 for x in model(X, theta)]

阈值设置之后,就要设置精度,在当前数据当中,认为是自己对了多少个?错了多少个?100个数据当中,一共对了89个,最终的结果是等于89%.通过梯度下降,梯度回归,最终算出精度是等于89%.

scaled_X = scaled_data[:, :3]

y = scaled_data[:, 3]

predictions = predict(scaled_X, theta)

correct = [1 if ((a == 1 and b == 1) or (a == 0 and b == 0)) else 0 for (a, b) in zip(predictions, y)]

accuracy = (sum(map(int, correct)) % len(correct))

print ('accuracy = {0}%'.format(accuracy))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值