Anonymous
ValueError: недопустимые классы, выведенные из уникальных значений `y`.
Сообщение
Anonymous » 21 янв 2025, 06:10
Я пытаюсь обучить классификатор, используя ансамблевое обучение. Я использую StackingClassifier. Он отлично работает, когда я тренирую автономные оценщики (
), но когда я складываю их в стопку, выдается следующая ошибка:
Код: Выделить всё
ValueError: Invalid classes inferred from unique values of `y`. Expected: [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
48 49 50 51 52 53 54 55 56 57], got [ 0 1 2 3 4 5 6 7 8 9 10 11 13 14 15 16 17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
49 50 51 52 53 54 55 56 57 58]
Существует 60 возможных классов, и возможно, что поезд и образцы могут не содержать данных для определенного класса. Мой код гарантирует, что в тестовом наборе данных не будет невидимой метки. Я не знаю, почему ожидаемый массив заканчивается на 57. Что бы там ни было, это правильно. Основная функция выглядит следующим образом:
Код: Выделить всё
def main():
parser = argparse.ArgumentParser(description="Training with CNN")
parser.add_argument("--inp_path", type=str, required=True, help="input path")
parser.add_argument("--csv_files", type=str, required=True, help="input csv file names")
parser.add_argument("--csv_path", type=str, required=True, help="input csv file path")
parser.add_argument("--ir_path", type=str, required=True, help="input IR files")
args = parser.parse_args()
csv_files = args.csv_files.split(",")
data = read_csv(args.inp_path, csv_files, args.csv_path)
data = load_data(data, args.inp_path, args.ir_path)
# building a token dictionary
data, token_dict = preprocess_ir_data(data)
train_data = data[(data['size'].isin(['S', 'M', 'L'])) & (data['source'].str.contains('RF'))]
test_data = data[(data['size'].isin(['XXL', 'XL'])) & (data['source'].str.contains('EZ'))]
valid_labels = train_data['class'].unique()
# Ensuring no unseen class in test data
test_data = test_data[test_data['class'].isin(valid_labels)]
# Combine train and test for global class mapping
data = pd.concat([train_data, test_data], ignore_index=True)
unique_classes = set(valid_labels)
class_mapping = {cls: idx for idx, cls in enumerate(unique_classes)}
train_data['class'] = train_data['class'].map(class_mapping)
test_data['class'] = test_data['class'].map(class_mapping)
num_classes = len(class_mapping)
X_train = train_data['text']
y_train = train_data['class']
X_test = test_data['text']
y_test = test_data['class']
y_train = torch.eye(num_classes)[list(y_train)]
y_test = torch.eye(num_classes)[list(y_test)]
max_length = 4096
def pad_sequences(data):
return pad_sequence(
[
torch.tensor(seq[:max_length], dtype=torch.long) if len(seq) > max_length else torch.cat(
(torch.tensor(seq, dtype=torch.long), torch.zeros(max_length - len(seq), dtype=torch.long))
)
for seq in data
],
batch_first=True
)
X_train = pad_sequences(X_train)
X_test = pad_sequences(X_test)
train_dataset = TensorDataset(X_train, y_train)
test_dataset = TensorDataset(X_test, y_test)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)
pre_trained_cnn = CNNModel(len(token_dict), num_classes)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(f"Using device: {device}")
train_model(pre_trained_cnn, train_loader, device=device)
aux_inputs = torch.tensor(data[['p4', 'p5']].values, dtype=torch.float)
feature_extractor = FeatureExtractor(pre_trained_cnn)
feature_extractor.eval()
with torch.no_grad():
extracted_features_train = feature_extractor(X_train, aux_inputs[:len(X_train)])
extracted_features_test = feature_extractor(X_test, aux_inputs[len(X_train):])
X_train_np = extracted_features_train.numpy()
X_test_np = extracted_features_test.numpy()
y_train_np = y_train.argmax(dim=1).numpy()
y_test_np = y_test.argmax(dim=1).numpy()
print(set(y_test_np))
rf = RandomForestClassifier(random_state=42)
rf.fit(X_train_np, y_train_np)
y_pred_rf = rf.predict(X_test_np)
print("RandomForest Accuracy:", accuracy_score(y_test_np, y_pred_rf))
xgb = XGBClassifier(use_label_encoder=False, eval_metric='logloss')
xgb.fit(X_train_np, y_train_np)
y_pred_xgb = xgb.predict(X_test_np)
print("XGBoost Accuracy:", accuracy_score(y_test_np, y_pred_xgb))
base_classifiers = [
('xgboost', XGBClassifier(use_label_encoder=False, eval_metric='logloss')),
('random_forest', RandomForestClassifier(random_state=42))
]
X_train_np = np.array(X_train_np)
X_test_np = np.array(X_test_np)
meta_classifier = AdaBoostClassifier(random_state=42)
stacking_clf = StackingClassifier(estimators=base_classifiers, final_estimator=meta_classifier, cv=5)
stacking_clf.fit(list(X_train_np), list(y_train_np))
y_pred_ensemble = stacking_clf.predict(X_test_np)
print("Ensemble Accuracy:", accuracy_score(y_test_np, y_pred_ensemble))
Этот код хорошо работает для другого набора данных, содержащего только два класса.
Подробнее здесь:
https://stackoverflow.com/questions/793 ... alues-of-y
1737429041
Anonymous
Я пытаюсь обучить классификатор, используя ансамблевое обучение. Я использую StackingClassifier. Он отлично работает, когда я тренирую автономные оценщики ([code]XGBoost, RandomForest[/code]), но когда я складываю их в стопку, выдается следующая ошибка: [code]ValueError: Invalid classes inferred from unique values of `y`. Expected: [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57], got [ 0 1 2 3 4 5 6 7 8 9 10 11 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58] [/code] Существует 60 возможных классов, и возможно, что поезд и образцы могут не содержать данных для определенного класса. Мой код гарантирует, что в тестовом наборе данных не будет невидимой метки. Я не знаю, почему ожидаемый массив заканчивается на 57. Что бы там ни было, это правильно. Основная функция выглядит следующим образом: [code]def main(): parser = argparse.ArgumentParser(description="Training with CNN") parser.add_argument("--inp_path", type=str, required=True, help="input path") parser.add_argument("--csv_files", type=str, required=True, help="input csv file names") parser.add_argument("--csv_path", type=str, required=True, help="input csv file path") parser.add_argument("--ir_path", type=str, required=True, help="input IR files") args = parser.parse_args() csv_files = args.csv_files.split(",") data = read_csv(args.inp_path, csv_files, args.csv_path) data = load_data(data, args.inp_path, args.ir_path) # building a token dictionary data, token_dict = preprocess_ir_data(data) train_data = data[(data['size'].isin(['S', 'M', 'L'])) & (data['source'].str.contains('RF'))] test_data = data[(data['size'].isin(['XXL', 'XL'])) & (data['source'].str.contains('EZ'))] valid_labels = train_data['class'].unique() # Ensuring no unseen class in test data test_data = test_data[test_data['class'].isin(valid_labels)] # Combine train and test for global class mapping data = pd.concat([train_data, test_data], ignore_index=True) unique_classes = set(valid_labels) class_mapping = {cls: idx for idx, cls in enumerate(unique_classes)} train_data['class'] = train_data['class'].map(class_mapping) test_data['class'] = test_data['class'].map(class_mapping) num_classes = len(class_mapping) X_train = train_data['text'] y_train = train_data['class'] X_test = test_data['text'] y_test = test_data['class'] y_train = torch.eye(num_classes)[list(y_train)] y_test = torch.eye(num_classes)[list(y_test)] max_length = 4096 def pad_sequences(data): return pad_sequence( [ torch.tensor(seq[:max_length], dtype=torch.long) if len(seq) > max_length else torch.cat( (torch.tensor(seq, dtype=torch.long), torch.zeros(max_length - len(seq), dtype=torch.long)) ) for seq in data ], batch_first=True ) X_train = pad_sequences(X_train) X_test = pad_sequences(X_test) train_dataset = TensorDataset(X_train, y_train) test_dataset = TensorDataset(X_test, y_test) train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True) test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False) pre_trained_cnn = CNNModel(len(token_dict), num_classes) device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') print(f"Using device: {device}") train_model(pre_trained_cnn, train_loader, device=device) aux_inputs = torch.tensor(data[['p4', 'p5']].values, dtype=torch.float) feature_extractor = FeatureExtractor(pre_trained_cnn) feature_extractor.eval() with torch.no_grad(): extracted_features_train = feature_extractor(X_train, aux_inputs[:len(X_train)]) extracted_features_test = feature_extractor(X_test, aux_inputs[len(X_train):]) X_train_np = extracted_features_train.numpy() X_test_np = extracted_features_test.numpy() y_train_np = y_train.argmax(dim=1).numpy() y_test_np = y_test.argmax(dim=1).numpy() print(set(y_test_np)) rf = RandomForestClassifier(random_state=42) rf.fit(X_train_np, y_train_np) y_pred_rf = rf.predict(X_test_np) print("RandomForest Accuracy:", accuracy_score(y_test_np, y_pred_rf)) xgb = XGBClassifier(use_label_encoder=False, eval_metric='logloss') xgb.fit(X_train_np, y_train_np) y_pred_xgb = xgb.predict(X_test_np) print("XGBoost Accuracy:", accuracy_score(y_test_np, y_pred_xgb)) base_classifiers = [ ('xgboost', XGBClassifier(use_label_encoder=False, eval_metric='logloss')), ('random_forest', RandomForestClassifier(random_state=42)) ] X_train_np = np.array(X_train_np) X_test_np = np.array(X_test_np) meta_classifier = AdaBoostClassifier(random_state=42) stacking_clf = StackingClassifier(estimators=base_classifiers, final_estimator=meta_classifier, cv=5) stacking_clf.fit(list(X_train_np), list(y_train_np)) y_pred_ensemble = stacking_clf.predict(X_test_np) print("Ensemble Accuracy:", accuracy_score(y_test_np, y_pred_ensemble)) [/code] Этот код хорошо работает для другого набора данных, содержащего только два класса. Подробнее здесь: [url]https://stackoverflow.com/questions/79373104/valueerror-invalid-classes-inferred-from-unique-values-of-y[/url]