Python逻辑回归/Hessian。求除零误差和奇异矩阵误差

Python逻辑回归/Hessian。求除零误差和奇异矩阵误差,python,regression,gradient,logistic-regression,hessian,Python,Regression,Gradient,Logistic Regression,Hessian,代码: 如果我循环超过28次,我会得到一个成本函数的“和”部分被0除的问题,我也会得到一个错误,说矩阵不能求逆,因为它是奇异的。不确定是什么错,按照我教授给出的精确算法。数据集是一个包含80个学生条目的列表,每个条目有两个考试分数,以及该学生是否被大学录取的二进制1或0。首先,您可以从读取文件的行中删除i=0和i+=1。只需将读卡器中的行:替换为i,枚举(读卡器)中的行: 将使i从0开始,每增加一行 然而,我无法在代码中发现任何错误,因此我猜测变量的初始化存在一些问题 特别是:您要求x成为(m,

代码:


如果我循环超过28次,我会得到一个成本函数的“和”部分被0除的问题,我也会得到一个错误,说矩阵不能求逆,因为它是奇异的。不确定是什么错,按照我教授给出的精确算法。数据集是一个包含80个学生条目的列表,每个条目有两个考试分数,以及该学生是否被大学录取的二进制1或0。

首先,您可以从读取文件的行中删除
i=0
i+=1
。只需将读卡器中的行:替换为i,枚举(读卡器)中的行:

将使
i
从0开始,每增加一行

然而,我无法在代码中发现任何错误,因此我猜测变量的初始化存在一些问题


特别是:您要求
x
成为
(m,3)
形状的数组,但您只初始化了两列。此外,您在开始时将
th
作为零矩阵。然后首先计算成本,这意味着首先计算np.dot(x,th)。我担心这与你教授给你的数据无关,因为
th
都是零。这也解释了为什么您总是在同一次迭代中出现错误。

将其用作.csv的示例数据(80个条目,不包括标题):

编辑脚本只是为了添加所需的导入和打印某些输出:

Grade 1,Grade 2,Admit
83,95,1
87,93,1
92,91,1
94,88,0
81,97,0
88.3,92.5,1
88.6,92.4,0
88.9,92.3,0
89.2,92.2,0
89.5,92.1,0
89.8,92,1
90.1,91.9,1
90.4,91.8,1
90.7,91.7,1
91,91.6,0
91.3,91.5,0
91.6,91.4,1
91.9,91.3,0
92.2,91.2,0
92.5,91.1,0
92.8,91,0
93.1,90.9,1
93.4,90.8,1
93.7,90.7,1
94,90.6,0
94.3,90.5,0
94.6,90.4,1
94.9,90.3,0
95.2,90.2,0
95.5,90.1,0
95.8,90,0
96.1,89.9,1
96.4,89.8,1
96.7,89.7,0
97,89.6,0
97.3,89.5,0
97.6,89.4,1
97.9,89.3,1
98.2,89.2,0
98.5,89.1,0
98.8,89,0
99.1,88.9,1
99.4,88.8,1
99.7,88.7,0
100,88.6,0
100.3,88.5,1
100.6,88.4,1
100.9,88.3,0
101.2,88.2,0
101.5,88.1,0
101.8,88,1
102.1,87.9,1
102.4,87.8,0
102.7,87.7,0
103,87.6,0
103.3,87.5,1
103.6,87.4,1
103.9,87.3,0
104.2,87.2,0
104.5,87.1,0
104.8,87,1
105.1,86.9,1
105.4,86.8,0
105.7,86.7,0
106,86.6,1
106.3,86.5,1
106.6,86.4,0
106.9,86.3,0
107.2,86.2,0
107.5,86.1,1
107.8,86,1
108.1,85.9,0
108.4,85.8,0
108.7,85.7,0
109,85.6,1
109.3,85.5,1
109.6,85.4,0
109.9,85.3,0
110.2,85.2,0
110.5,85.1,1

如果您只是复制我的csv数据,并将其用作测试输入,那么它应该可以在命令行(Windows)上正常运行和输出。因此,我所能看到的我所做的和你所做的之间的唯一区别——这可能是错误的原因——是在等级数据文件本身的结构上。

我看到人们大多将th/θ矩阵初始化为零。如果我从1开始,我马上得到一个奇异矩阵误差。我也不知道你说的x矩阵是什么意思。它有3列,第一列是偏差值结尾的所有1。好的,我知道为什么不填充
x
的0列。您可以尝试随机初始化
th
,但这不是问题的解决方案。但是,哪一步会产生反演误差?我可以看到您多次调用hessian函数,您可以忽略该循环中的所有函数调用,只需查看updateTh调用。这就是在第29个循环中产生错误的原因,实际上,其他函数甚至不需要在循环中调用。然而,第29个循环也是一个循环,其中成本函数也将给出一个误差,即除以零的误差。不知何故,我得到的θ矩阵导致了这些问题,但我不知道是什么错,代价函数给出了除以零的误差,是的。但这一职能并没有划分。我很确定会发生以下情况:你调用updateTh,它反过来调用hessian的反转。这就是当你得到一个除以零的除法,当你尝试反转海森曲线时。看第Th函数的那一行,在那里你可以得到除以零的结果。当你把黑森河倒转的时候,不是第一个吗?我打赌是的。然而,这(显然)意味着黑森函数是不可逆的,原因可能有两个:你的教授在愚弄你(对此表示怀疑),或者有一个错误,除非我使用成本函数,并将其专门分离到“result=sum(-y*np.log(pro)-(1-y)*np log(1-pro)),否则被零除的错误绝对不会出现部分反向错误发生在调用updateTh函数时,该函数尝试执行反向操作。我猜这与您的.csv数据文件有关,因为我使用随机等级数据创建了自己的文件,并且您的脚本在使用时运行良好。如果不知道你文件中的数据是如何组织的,或者分数的范围是什么,以及什么决定了最后一列数据的1或0,那么很难说。你是说教授愚弄了他们吗?哈哈。不过我同意代码中似乎没有错误。谢谢,但奇怪的是,我完全可以很好地填充矩阵。我认为输入文件不应该有问题,因为当我测试显示我的matrices@GRquanti不,我绝对不是这个意思,哈哈。我只是想看看csv文件,因为它似乎与我制作的示例一起工作。我觉得奇怪的是,剧本在我这方面完美无瑕。似乎我在测试中遇到了众所周知的困难,因为我无法重现OP的错误。我能想到做的唯一一件事就是请求输入文件,以便能够得到相同的错误结果,并继续尝试解决问题。
Grade 1,Grade 2,Admit
83,95,1
87,93,1
92,91,1
94,88,0
81,97,0
88.3,92.5,1
88.6,92.4,0
88.9,92.3,0
89.2,92.2,0
89.5,92.1,0
89.8,92,1
90.1,91.9,1
90.4,91.8,1
90.7,91.7,1
91,91.6,0
91.3,91.5,0
91.6,91.4,1
91.9,91.3,0
92.2,91.2,0
92.5,91.1,0
92.8,91,0
93.1,90.9,1
93.4,90.8,1
93.7,90.7,1
94,90.6,0
94.3,90.5,0
94.6,90.4,1
94.9,90.3,0
95.2,90.2,0
95.5,90.1,0
95.8,90,0
96.1,89.9,1
96.4,89.8,1
96.7,89.7,0
97,89.6,0
97.3,89.5,0
97.6,89.4,1
97.9,89.3,1
98.2,89.2,0
98.5,89.1,0
98.8,89,0
99.1,88.9,1
99.4,88.8,1
99.7,88.7,0
100,88.6,0
100.3,88.5,1
100.6,88.4,1
100.9,88.3,0
101.2,88.2,0
101.5,88.1,0
101.8,88,1
102.1,87.9,1
102.4,87.8,0
102.7,87.7,0
103,87.6,0
103.3,87.5,1
103.6,87.4,1
103.9,87.3,0
104.2,87.2,0
104.5,87.1,0
104.8,87,1
105.1,86.9,1
105.4,86.8,0
105.7,86.7,0
106,86.6,1
106.3,86.5,1
106.6,86.4,0
106.9,86.3,0
107.2,86.2,0
107.5,86.1,1
107.8,86,1
108.1,85.9,0
108.4,85.8,0
108.7,85.7,0
109,85.6,1
109.3,85.5,1
109.6,85.4,0
109.9,85.3,0
110.2,85.2,0
110.5,85.1,1
import numpy as np
import csv

def sigmoid(x):
    return 1.0/(1+np.exp(-x)) 

def cost(x,y,th):
    pro = sigmoid(np.dot(x,th))
    result = sum(-y * np.log(pro) - (1-y) * np.log(1-pro))   
    result = result/len(x) #len: number of feature rows
    return result

def gradient(x,y,th):
    xTrans = x.transpose()                                      
    sig = sigmoid(np.dot(x,th))                              
    grad = np.dot(xTrans, ( sig - y ))                          
    grad = grad / len(x) #len: number of feature rows  
    return grad
def hessian(x,y,th):
    xTrans = x.transpose()                                      
    sig = sigmoid(np.dot(x,th))                              
    result = (1.0/len(x) * np.dot(xTrans, x) * np.diag(sig) * np.diag(1 - sig) )   
    return result
def updateTh(x,y,th):
    hessianInv = np.linalg.inv(hessian(x,y,th))                         
    grad = gradient(x,y,th)                                  
    th = th - np.dot(hessianInv, grad)                     
    return th

m = 80 #number of x rows
x = np.ones([m,3])
y = np.empty([m,1], dtype = int)
th = np.zeros([3,1])
hessianResult = np.identity(3) #identity 3x3


with open('exam.csv','r') as csvfile:
            i = 0
            reader = csv.reader(csvfile)
            next(reader) #skip header            
            for line in reader:
                x[i][1] = line[0]
                x[i][2] = line[1]
                y[i][0] = line[2]
                i+=1

#m = x.shape[0] #number of x rows
for i in range(40):
    print("Entry #",i,": ",x[i][1],", ",x[i][2],", ",y[i][0], sep = '')
    costResult = cost(x,y,th)
    print(costResult)
    hessianResult = hessian(x,y,th)
    print(hessianResult)
    grad = gradient(x,y,th)
    print(grad)
    th = updateTh(x,y,th)
    print(th)