from sklearn.linear_model import LinearRegression from sklearn.feature_selection import RFE, f_regression import numpy as np from sklearn.preprocessing import MinMaxScaler from operator import itemgetter from sklearn.ensemble import RandomForestRegressor def rank_to_dict(ranks, names): ranks = np.abs(ranks) minmax = MinMaxScaler() ranks = minmax.fit_transform(np.array(ranks).reshape(FEATURES_AMOUNT, 1)).ravel() ranks = map(lambda x: round(x, 2), ranks) return dict(zip(names, ranks)) def flip_array(arr): return -1 * arr + np.max(arr) def sort_by_desc(dictionary): return dict(sorted(dictionary.items(), key=itemgetter(1), reverse=True)) def calc_mean(ranks): mean = {} for key, value in ranks.items(): for item in value.items(): if item[0] not in mean: mean[item[0]] = 0 mean[item[0]] += item[1] for key, value in mean.items(): res = value / len(ranks) mean[key] = round(res, 2) return sort_by_desc(mean) # Исходные данные составляют 750 строк-наблюдений и 14 столбцов-признаков FEATURES_SIZE = 750 FEATURES_AMOUNT = 14 # Генерация случайных исходных данных np.random.seed(0) x = np.random.uniform(0, 1, (FEATURES_SIZE, 14)) # Создание функции-выхода (постановка регрессионной проблемы Фридмана) и добавление зависимости признаков y = (10 * np.sin(np.pi * x[:, 0] * x[:, 1]) + 20 * (x[:, 2] - .5) ** 2 + 10 * x[:, 3] + 5 * x[:, 4] ** 5 + np.random.normal(0, 1)) x[:, 10:] = x[:, :4] + np.random.normal(0, .025, (FEATURES_SIZE, 4)) # Создаём модель рекурсивного сокращения признаков на основе линейной модели и обучаем её regression = LinearRegression() regression.fit(x, y) rfe = RFE(regression) rfe.fit(x, y) # Создаём модель сокращения признаков случайными деревьями и обучаем её rfr = RandomForestRegressor() rfr.fit(x, y) # Создаём модель линейной корреляции и обучаем её f, _ = f_regression(x, y, center=False) # Аккумулируем наименования признаков features_names = ["x%s" % i for i in range(1, FEATURES_AMOUNT + 1)] # Собираем отображения значений каждого признака каждой моделью features_ranks = { 'RFE': sort_by_desc(rank_to_dict(flip_array(rfe.ranking_), features_names)), 'RFR': sort_by_desc(rank_to_dict(rfr.feature_importances_, features_names)), 'f_regression': sort_by_desc(rank_to_dict(f, features_names)) } # Подсчитываем среднюю оценку и выводим результаты print(f"Результаты:" f"\n RFE \n{features_ranks['RFE']}" f"\n RFR \n{features_ranks['RFR']}" f"\n f_regression \n {features_ranks['f_regression']}" f"\n Средние значения \n{calc_mean(features_ranks)}")