上一篇写了用python实现感知机算法,但都是用多个函数实现,今天打算将其封装为类,把分类器的参数w和b作为属性,其它函数作为方法,其中参数w和b的更新通过递归函数实现。由于赋予了属性w和b,所以在更新参数的函数中不再将w和b作为参数和返回值,在运行时,提示该函数未定义。下面贴出源码讨论。
函数定义 | 方法定义 |
def updateP(X,labels,(w,b),r): Y = np.dot(X,w)+b #求出预测值 Y2 = Y*labels errIndex = np.where(Y2<=0)[0] #求出yi(w*xi+b)<=0的索引 if np.size(errIndex)==0: return (w,b) else: x = X[errIndex[0]] y = labels[errIndex[0]] w = w+np.dot(x,y)*r b = b+r*y return updateP(X,labels,(w,b),r) | def updateP(self,featureMatrix,labels): labesPredict = np.dot(featureMatrix,self.w)+self.b Y = labesPredict*labels #预测值和实际类别是否一致 errIndex = np.where(Y<=0)[0] if np.size(errIndex)==0: pass else: x = featureMatrix.loc[errIndex[0],:] y = labels[errIndex[0]] self.w = self.w+np.dot(x,y)*self.r self.b = self.b+self.r*y return updateP(featureMatrix,labels) |
错误提示如下:
C:\Users\jh>python D:\julie\test.py
NameError: global name 'updateP' is not defined
提示函数未定义原因??
1:以为是递归函数没有返回值, if np.size(errIndex)==0:pass,或是返回值没有作为下次函数调用的输入参数, return updateP(featureMatrix,labels) ,故将方法修改为如下:
def updateP(self,featureMatrix,labels,w,b):
labesPredict = np.dot(featureMatrix,self.w)+self.b #求出预测值
Y = labesPredict*labels #预测值和实际类别是否一致
errIndex = np.where(Y<=0)[0] #求出yi(w*xi+b)<=0的索引,包括等于0的意思是最后并没有样本落在超平面上
if np.size(errIndex)==0:
#pass
return w,b
else:
x = featureMatrix.loc[errIndex[0],:]
y = labels[errIndex[0]]
w = w+np.dot(x,y)*self.r
b = b+self.r*y
return updateP(featureMatrix,labels,w,b)
运行后依然报错:NameError: global name 'updateP' is not defined
2: 以为是类中不能用递归函数,可是用如下小程序运行正常
class Cumula(object):
def CumulaSum(self,n):
if n == 0 :
return 0
else:
return self.CumulaSum(n-1)+n
发现是少写了self,即在类中定义函数时,若函数体中有对函数本身或该类中其他函数的引用都要加上前缀self.,如同引用属性一样,告诉解释器引用的函数属于该类本身。
3.附加一点,window下能正常安装pudb,但无法正常使用。