Scikit-Multiflow报错:replace=False时样本量不能大于总体量求解决
问题:skmultiflow AdaptiveRandomForestClassifier 运行报错 ValueError: Cannot take a larger sample than population when 'replace=False'
我尝试运行以下代码,其中x是维度为(2381,)的特征向量,转换为Numpy数组后的y是维度为(1,)的标签。
from skmultiflow.meta import AdaptiveRandomForestClassifier import numpy as np import data np.random.seed(1) def main() -> None: dataset = data.get_full_dataset() metadata = data.get_metadata() training_batch = data.get_windows(dataset, metadata, data.get_initial_training_groups()) streaming_batch = data.get_windows(dataset, metadata, data.get_incremental_learning_groups()) initial_features = np.concatenate([dataset.feature_vectors for group, dataset in training_batch]) initial_labels = np.concatenate([dataset.labels for group, dataset in training_batch]) model = AdaptiveRandomForestClassifier() correct_count = 0 n_samples = 0 for x, y in zip(initial_features, initial_labels): y = np.asarray([y]) y_prediction = model.predict(x) if y_prediction[0] == y: correct_count += 1 model.partial_fit(x, y) n_samples += 1 print(f"Accuracy: {correct_count / n_samples}") if __name__ == "__main__": main()
运行后出现如下错误:
Traceback (most recent call last): File "/home/nathan/Documents/Research/BodmasOnline/main.py", line 31, in <module> main() File "/home/nathan/Documents/Research/BodmasOnline/main.py", line 24, in main model.partial_fit(x, y) File "/home/nathan/Documents/Research/BodmasOnline/venv/lib/python3.10/site-packages/skmultiflow/meta/adaptive_random_forests.py", line 313, in partial_fit self._partial_fit(X[i], y[i], self.classes, weight[i]) File "/home/nathan/Documents/Research/BodmasOnline/venv/lib/python3.10/site-packages/skmultiflow/meta/adaptive_random_forests.py", line 328, in _partial_fit self.ensemble[i].partial_fit(np.asarray([X]), np.asarray([y]), File "/home/nathan/Documents/Research/BodmasOnline/venv/lib/python3.10/site-packages/skmultiflow/meta/adaptive_random_forests.py", line 569, in partial_fit self.classifier.partial_fit(X, y, classes=classes, sample_weight=sample_weight) File "/home/nathan/Documents/Research/BodmasOnline/venv/lib/python3.10/site-packages/skmultiflow/trees/hoeffding_tree.py", line 394, in partial_fit self._partial_fit(X[i], y[i], sample_weight[i]) File "/home/nathan/Documents/Research/BodmasOnline/venv/lib/python3.10/site-packages/skmultiflow/trees/hoeffding_tree.py", line 424, in _partial_fit learning_node.learn_from_instance(X, y, sample_weight, self) File "/home/nathan/Documents/Research/BodmasOnline/venv/lib/python3.10/site-packages/skmultiflow/trees/nodes/random_learning_node_nb_adaptive.py", line 54, in learn_from_instance super().learn_from_instance(X, y, weight, ht) File "/home/nathan/Documents/Research/BodmasOnline/venv/lib/python3.10/site-packages/skmultiflow/trees/nodes/random_learning_node_classification.py", line 58, in learn_from_instance self.list_attributes = self._sample_features(get_dimensions(X)[1]) File "/home/nathan/Documents/Research/BodmasOnline/venv/lib/python3.10/site-packages/skmultiflow/trees/nodes/random_learning_node_classification.py", line 72, in _sample_features return self.random_state.choice( File "mtrand.pyx", line 965, in numpy.random.mtrand.RandomState.choice ValueError: Cannot take a larger sample than population when 'replace=False'
问题原因
- 输入维度错误:
partial_fit和predict期望输入是二维数组(形状为(n_samples, n_features)),但你传入的x是一维数组(2381,),导致模型误判特征数量。 - 特征采样参数冲突:AdaptiveRandomForestClassifier默认按
sqrt(n_features)采样特征,若模型内部逻辑误判特征数(比如把一维数组当成1个特征),会出现采样数超过特征总数的情况,触发报错。 - 未指定类别信息:流式模型需要提前知道类别集合,缺失会导致内部逻辑异常。
解决方案
修改后的代码
from skmultiflow.meta import AdaptiveRandomForestClassifier import numpy as np import data np.random.seed(1) def main() -> None: dataset = data.get_full_dataset() metadata = data.get_metadata() training_batch = data.get_windows(dataset, metadata, data.get_initial_training_groups()) streaming_batch = data.get_windows(dataset, metadata, data.get_incremental_learning_groups()) initial_features = np.concatenate([dataset.feature_vectors for group, dataset in training_batch]) initial_labels = np.concatenate([dataset.labels for group, dataset in training_batch]) # 提前获取所有类别,传入模型初始化 classes = np.unique(initial_labels) # 显式设置特征采样参数,确保采样数不超过特征总数 model = AdaptiveRandomForestClassifier(max_features='sqrt', classes=classes) correct_count = 0 n_samples = 0 for x, y in zip(initial_features, initial_labels): # 将一维特征向量转为二维数组(符合模型输入要求) x_2d = x.reshape(1, -1) y = np.asarray([y]) y_prediction = model.predict(x_2d) # 修正比较逻辑,避免数组与标量直接对比 if y_prediction[0] == y[0]: correct_count += 1 model.partial_fit(x_2d, y) n_samples += 1 print(f"Accuracy: {correct_count / n_samples}") if __name__ == "__main__": main()
关键修改点
- 输入维度转换:将一维的
x通过reshape(1, -1)转为二维数组,确保模型识别正确的特征数量。 - 显式设置模型参数:初始化时指定
max_features='sqrt'(计算后约48个特征,远小于2381),避免采样数超出特征总数;同时传入classes参数,符合流式模型使用规范。 - 修正标签比较逻辑:将
y改为y[0],避免数组与标量的直接对比问题。
内容的提问来源于stack exchange,提问作者Nate Waltz
相关产品推荐
相关产品推荐

