对率回归
闲来无事,学习了一下西瓜书线性回归模型,顺带做了下后边的题,其中对率回归是一种分类方法,西瓜书课后题3.3正好是一个二分类问题,先讲解下对率回归。其实对西瓜的二分类问题对率回归无非有三个参数,两个权重一个bias,参数量很小,主要目的就是训练这三个参数,有训练就要有目标函数,这里采用Logistic函数重新计算了一下权重偏差乘以西瓜属性后的0-1之间的值,以0.5为间隔区别好瓜坏瓜,很好理解,这个题需要写的就有最优化的处理过程,即梯度下降和牛顿迭代,这里采用梯度下降法,梯度下降法的内容在代码中都有标明,如有不理解欢迎评论探讨,如本人有问题欢迎批评指正。
代码
去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片
.
import numpy as np
'''
代码共分为多个部分,应包括数据读取、sigmoid函数、计算准确率
梯度下降函数
'''
#对数几率函数
def LogisticFunction(z):
return 1/(1+np.exp(-z))
def LoadData():
dataSet = np.array([
[0.697, 0.460, 1],
[0.774, 0.376, 1],
[0.634, 0.264, 1],
[0.608, 0.318, 1],
[0.556, 0.215, 1],
[0.403, 0.237, 1],
[0.481, 0.149, 1],
[0.437, 0.211, 1],
[0.666, 0.091, 0],
[0.243, 0.267, 0],
[0.245, 0.057, 0],
[0.343, 0.099, 0],
[0.639, 0.161, 0],
[0.657, 0.198, 0],
[0.360, 0.370, 0],
[0.593, 0.042, 0],
[0.719, 0.103, 0]
])
dataArr = dataSet[:,0:2]
dataArr = np.insert(dataArr,2, 1, axis=1)
labelArr = dataSet[:,2]
return dataArr,labelArr
def CalculateAccuracy(dataArr, labelArr, beta):
predictArr = []
accuracy=0
length, width= dataArr.shape
preArr = LogisticFunction(np.dot(dataArr, beta))
preArr[preArr > 0.5] = 1
preArr[preArr <= 0.5] = 0
for i in range(len(preArr)):
if preArr[i]==labelArr[i]:
accuracy += 1
accuracy = accuracy/len(labelArr)
return accuracy
#梯度下降函数
def GradDescent(dataArr, labelArr, alpha, T):
#dataArr为原始数据
#labelArr为标签数据
#alpha为学习率
#T为迭代次数
m, n = dataArr.shape
labelArr = labelArr.reshape(-1, 1)
errList = []
#生成书中的beta,beta包含两个权重和一个bias,最终为一列向量
beta = np.ones((n, 1))
for t in range(T):
# py0 = p(y=1|x) with shape (m,1)
#计算的时p(y=1|x)的值
py1 = LogisticFunction(np.dot(dataArr, beta))
#对似然项求导后的函数
dBetaMat = -dataArr * (labelArr - py1)
# shape (1,n)
#导数相加
dBeta = np.sum(dBetaMat, axis=0, keepdims=True)
#减去学习率乘以倒数以更新权重和bias
beta -= alpha * dBeta.T
print(CalculateAccuracy(dataArr, labelArr, beta))
# test code
return beta
def predict(beta, attribute1, attribute2, attribute3):
attribute = np.array([attribute1, attribute2, attribute3])
predict = np.dot(attribute, beta)
if predict>=0.5:
predict = 1
else:
predict = 0
return predict
def main():
dataArr, labelArr = LoadData()
beta = GradDescent(dataArr, labelArr, 0.001, 500)
print(beta)
print(LogisticFunction(np.dot(dataArr, beta)))
if __name__ == '__main__':
main()