Как всегда, перед обучением модели нужно подготовить данные. Для этого закодируйте категориальные признаки в датасете. Похоже, масштабирование в этот раз не понадобится: кажется, большинство признаков и так лежат в одном диапазоне…

Чтобы отделить количественные признаки от категориальных, используйте метод датафрейма select_dtypes(). У него есть две основные настройки:

  • include='number' — отобрать только количественные признаки с типами данных int и float;
  • exclude=’number’ — исключить количественные признаки, то есть отобрать все остальные.

После отделения разных типов признаков с помощью select_dtypes() нужно конвертировать столбцы в списки с помощью tolist().

Подготовка данных занимает много места, но при этом её достаточно сделать один раз. Поэтому в этой и в следующих темах в задачах с объёмным кодом мы будем помещать подготовку в функцию prepare_data().

В теме про kNN вы увидите её содержимое один раз, а далее она будет незаметно для вас находится в скрытой части кода — в скрытом прекоде. Если в код будут внесены какие-то изменения или подготовка включает необычные шаги — вы об этом узнаете. Ознакомиться с кодом для подготовки можно в условии задач, где впервые выполнены какие-то действия.

import pandas as pd

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OneHotEncoder
from sklearn.metrics import accuracy_score

# создание константы RANDOM_STATE
RANDOM_STATE = 42

def prepare_data(fname):
	# добавляем данные из CSV-файла в датафрейм pandas, делим датасет на выборки
	df = pd.read_csv(fname)
	X = df.drop(columns='music_genre')
	y = df.music_genre
	
	X_train, X_test, y_train, y_test = train_test_split(
	    X, 
	    y, 
	    random_state=RANDOM_STATE
	)
	
	# создайте списки с количественными и категориальными признаками
	cat_col_names = X_train.select_dtypes(exclude='number').columns.tolist()
	num_col_names = X_train.select_dtypes(include='number').columns.tolist()
	
	# выберите класс OneHotEncoder() для кодирования 
	# задайте sparse значение False, избегайте дамми-ловушки
	ohe = OneHotEncoder(sparse=False, drop='first')
	
	# обучите и преобразуйте категориальные признаки из тренировочной и тестовой выборок 
	# для тренировочной выборки выполните действия одной командой
	X_train_ohe = ohe.fit_transform(X_train[cat_col_names])
	X_test_ohe = ohe.transform(X_test[cat_col_names])
	
	# сохраняем в переменной encoder_col_names список названий новых столбцов 
	encoder_col_names = ohe.get_feature_names()
	
	# создаём датафрейм из закодированных данных
	# передаём названия столбцов из переменной encoder_col_names
	X_train_ohe = pd.DataFrame(X_train_ohe, columns=encoder_col_names)
	X_test_ohe = pd.DataFrame(X_test_ohe, columns=encoder_col_names)
	
	# обнуляем индексы строк перед объединением количественных и категориальных 
	# признаков в датафрейм
	X_train = X_train.reset_index()
	X_test = X_test.reset_index()
    
	# объедините количественные и категориальные признаки для тренировочного
	# и тестового датасетов
	X_train = pd.concat([X_train[num_col_names], X_train_ohe], axis=1)
	X_test = pd.concat([X_test[num_col_names], X_test_ohe], axis=1)
    
	return X_train, X_test, y_train, y_test

# выполняем подготовку данных функцией
X_train, X_test, y_train, y_test = prepare_data('music_genre_2_classes_balanced_v2_exp.csv')

# выведите размерность тренировочного датасета — количество строк и столбцов
print(X_train.shape)

Результат
(6743, 22)