我为鸢尾花数据集编写了3类分类(共有3个类别),并使用了3个感知器。我在感知器学习上遇到了问题,感知器仅对第一类学习正确,第二类和第三类的权重相同,我不知道哪里出了问题。第一类的感知器总是能正确学习并分类。第一个感知器的目标是0,第二个是1,第三个是2。当我交换位置,让第一个学习时,目标为2的感知器会正常工作,第一个总是工作得很好,而接下来的两个表现很差。训练数据的设置有问题。
附注:这是我的第一个Python应用程序。
import matplotlib.pyplot as pltimport numpy as npfrom sklearn.model_selection import train_test_splitfrom sklearn import datasetsclass Perceptron(object):def __init__(self, eta=0.01, n_iter=10): self.eta = eta self.n_iter = n_iterdef fit(self, X, y): self.w_ = np.zeros(1+ X.shape[1]) self.errors_ = [] for _ in range(self.n_iter): errors = 0 for xi, target in zip(X,y): update = self.eta * (target - self.predict(xi)) self.w_[1:] += update *xi self.w_[0] += update errors += int(update != 0.0) self.errors_.append(errors) print(self.w_) return selfdef net_input(self, X): return np.dot(X, self.w_[1:]) + self.w_[0]def predict(self, X): return np.where(self.net_input(X) >= 0.0, 1, -1)def main():iris = datasets.load_iris()X = iris.data[:, [2, 3]]y = iris.targetX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1, stratify=y)X_train_01_subset = X_trainy_train_01_subset = y_trainy_train_01_subset[(y_train_01_subset == 0)] = -1y_train_01_subset[(y_train_01_subset == 1)] = -1y_train_01_subset[(y_train_01_subset == 2)] = 0ppn01 = Perceptron(eta=0.1, n_iter=10)ppn01.fit(X_train_01_subset, y_train_01_subset)X_train_02_subset = X_trainy_train_02_subset = y_trainy_train_02_subset[(y_train_02_subset == 1)] = 1y_train_02_subset[(y_train_02_subset == 0)] = -1y_train_02_subset[(y_train_02_subset == 2)] = -1ppn02 = Perceptron(eta=0.1, n_iter=10)ppn02.fit(X_train_02_subset, y_train_02_subset)X_train_03_subset = X_trainy_train_03_subset = y_trainy_train_03_subset[(y_train_03_subset == 1)] = -1y_train_03_subset[(y_train_03_subset == 0)] = 2y_train_03_subset[(y_train_03_subset == 2)] = -1ppn03 = Perceptron(eta=0.1, n_iter=10) ppn03.fit(X_train_03_subset, y_train_03_subset)
回答:
我在你的代码中注意到了两点:
- 当你将numpy数组赋值给一个新变量时,它们被视为同一个变量,即对新变量的更改会影响初始变量。这意味着当你更改y_train_01_subset、y_train_02_subset和y_train_03_subset的值时,你的代码会更改y_train。这意味着你的代码只会对第一个子集起作用,因为当你到达第二个集合时,y_train将全部是-1。使用
.copy()
来解决这个问题。 - 在你的y_train_03_subset中,你将值等于0设置为2,然后将值等于2设置为-1,所以所有值都将是-1。重新排列这些行。
为了解决这些问题,请替换以下代码:
X_train_01_subset = X_train.copy()y_train_01_subset = y_train.copy()y_train_01_subset[(y_train_01_subset == 0)] = -1y_train_01_subset[(y_train_01_subset == 1)] = -1y_train_01_subset[(y_train_01_subset == 2)] = 0ppn01 = Perceptron(eta=0.1, n_iter=10)ppn01.fit(X_train_01_subset, y_train_01_subset)X_train_02_subset = X_train.copy()y_train_02_subset = y_train.copy()y_train_02_subset[(y_train_02_subset == 1)] = 1y_train_02_subset[(y_train_02_subset == 0)] = -1y_train_02_subset[(y_train_02_subset == 2)] = -1ppn02 = Perceptron(eta=0.1, n_iter=10)ppn02.fit(X_train_02_subset, y_train_02_subset)X_train_03_subset = X_train.copy()y_train_03_subset = y_train.copy()y_train_03_subset[(y_train_03_subset == 1)] = -1y_train_03_subset[(y_train_03_subset == 2)] = -1y_train_03_subset[(y_train_03_subset == 0)] = 2ppn03 = Perceptron(eta=0.1, n_iter=10) ppn03.fit(X_train_03_subset, y_train_03_subset)