>这里的自学者。
我正在构建一个预测事件的 Web 应用程序。
让我们考虑这个快速示例。
X = [[0], [1], [2], [3]]
y = [0, 0, 1, 1]
from sklearn.neighbors import KNeighborsClassifier
neigh = KNeighborsClassifier(n_neighbors=3)
neigh.fit(X, y)
print(neigh.predict([[1.1]]))
如何保持neigh
的状态,以便在输入新值(如 neigh.predict([[1.2]])
)时,无需重新训练模型。是否有任何好的做法或提示来开始解决问题?
出于几个原因,您选择了一个有点令人困惑的示例。首先,当你说neigh.predict([[1.2]])
时,你不是在添加新的训练点,你只是在做一个新的预测,所以这根本不需要任何改变。其次,KNN算法并不是真正"训练"的——KNN是一种基于实例的算法,这意味着"训练"相当于将训练数据存储在合适的结构中。因此,这个问题有两个不同的答案。我将首先尝试回答 KNN 问题。
K 最近邻
对于 KNN,添加新的训练数据相当于将新的数据点附加到结构中。但是,scikit-learn
似乎不提供任何此类功能。(这很合理 - 由于 KNN 明确存储了每个训练点,因此您不能无限期地为其提供新的训练点。
如果您没有使用很多训练点,一个简单的列表可能足以满足您的需求!在这种情况下,您可以完全跳过sklearn
,只需将新数据点附加到列表中。要进行预测,请进行线性搜索,保存k
最近的邻居,然后基于简单的"多数投票"进行预测 - 如果五个邻居中有三个或更多是红色的,则返回红色,依此类推。但请记住,您添加的每个训练点都会减慢算法的速度。
如果您需要使用许多训练点,则需要使用更有效的结构进行最近邻搜索,例如 K-D 树。有一个scipy
K-D 树实现应该可以工作。query
方法允许您查找k
最近的邻居。它将比列表更有效,但随着您添加更多训练数据,它仍然会变慢。
在线学习
对您的问题更普遍的答案是,您(自己不知道)正在尝试做一些称为在线学习的事情。在线学习算法允许您在到达时使用单个训练点,并在使用后丢弃它们。为了使这有意义,您需要存储的不是训练点本身(如 KNN 中),而是一组参数,您可以对其进行优化。
这意味着某些算法比其他算法更适合于此。 sklearn
只提供了几种能够在线学习的算法。这些方法都有一个partial_fit
方法,允许您批量传递训练数据。损失'hinge'
或'log'
的SKDClassifier
可能是一个很好的起点。
或者,也许您只想在拟合后保存模型
joblib.dump(neigh, FName)
并在需要时加载它
neigh = joblib.load(FName)
neigh.predict([[1.1]])