• 机器学习
  • 感知机对偶代码报错,提示 AttributeError: 'Perceptron' object has no attribute '_dual_fit'

参考的链接出处
https://nbviewer.org/github/zhulei227/ML_Notes/blob/master/notebooks/04_%E7%BA%BF%E6%80%A7%E6%A8%A1%E5%9E%8B_%E6%84%9F%E7%9F%A5%E6%9C%BA.ipynb
对偶形式的代码 根据提示,修改为作者意图的代码,但是报错,哪位大佬给看看 应该怎么修改,感谢感谢,不要借用什么Gram矩阵,就根据作者的意思进行修改,该怎么改?
这是我根据作者意图的代码
class Perceptron(object):
def init(self, epochs=10, eta=None, mode=None):
self.mode = mode
self.w = None
self.epochs = epochs
self.eta = eta

def init_params(self, n_features):
    """
    初始化参数
    :return:
    """
    self.w = np.random.random(size=(n_features + 1, 1))

def fit(self, x, y):
	if self.mode=='dual':
		self._dual_fit(x,y,epochs,eta)
	else:
    """
    :param x: ndarray格式数据: m x n
    :param y: ndarray格式数据: m x 1
    :return:
    """
		# 设置学习率
		if self.eta is None:
			self.eta = max(1e-2, 1.0 / np.sqrt(x.shape[0]))
		y = y.reshape(-1, 1)
		y[y == 0] = -1
		# 初始化参数w,b
		n_samples, n_features = x.shape
		self.init_params(n_features)
		x = np.c_[x, np.ones(shape=(n_samples,))]
		x_y = np.c_[x, y]

		for _ in range(self.epochs):
			error_sum = 0
			np.random.shuffle(x_y)
			for index in range(0, n_samples):
				x_i = x_y[index, :-1]
				y_i = x_y[index, -1:]
				# 更新错分点的参数
				if (x_i.dot(self.w) * y_i)[0] < 0:
					dw = (-x_i * y_i).reshape(-1, 1)
					self.w = self.w - self.eta * dw
					error_sum += 1
			if error_sum == 0:
				break
	def _dual_fit(self, x, y):
		"""
		模型训练的对偶形式
		:param x:
		:param y:
		:return:
		"""
		y = y.reshape(-1, 1)
		y[y == 0] = -1

		n_samples, n_features = x.shape

		# 初始化参数
		self.alpha = np.zeros(shape=(n_samples, 1))

		x = np.c_[x, np.ones(shape=(n_samples,))]

		for _ in range(self.epochs):
			error_sum = 0
			indices = list(range(0, n_samples))
			np.random.shuffle(indices)
			for index in indices:
				x_i = x[index, :]
				y_i = y[index]
				# 更新错分点的参数,(注意需要有等号,因为初始化的alpha全为0)
				if (x_i.dot(x.T.dot(self.alpha * y)) * y_i)[0] <= 0:
					self.alpha[index] += self.eta
					error_sum += 1
			if error_sum == 0:
				break
		# 更新回w
		self.w = x.T.dot(alpha * y)

def get_params(self):
    """
    输出原始的系数
    :return: w
    """

    return self.w

def predict(self, x):
    """
    :param x:ndarray格式数据: m x n
    :return: m x 1
    """
    n_samples = x.shape[0]
    x = np.c_[x, np.ones(shape=(n_samples,))]
    return (x.dot(self.w) > 0).astype(int)

def predict_proba(self, x):
    """
    :param x:ndarray格式数据: m x n
    :return: m x 1
    """
    n_samples = x.shape[0]
    x = np.c_[x, np.ones(shape=(n_samples,))]
    return utils.sigmoid(x.dot(self.w))

def plot_decision_boundary(self, x, y):
    """
    绘制前两个维度的决策边界
    :param x:
    :param y:
    :return:
    """
    weights = self.get_params()
    w1 = weights[0][0]
    w2 = weights[1][0]
    bias = weights[-1][0]
    x1 = np.arange(np.min(x), np.max(x), 0.1)
    x2 = -w1 / w2 * x1 - bias / w2
    plt.scatter(x[:, 0], x[:, 1], c=y, s=50)
    plt.plot(x1, x2, 'r')
    plt.show()

python?这是缩进敏感的吧?你的 def _dual_fit的部分已经缩进到def fit的部分里面了,并且还可能是先使用到_dual_fit然后才会到_dual_fit的定义,这样真的可以吗?