from sklearn.linear_model import Lasso, LinearRegression from sklearn.feature_selection import RFE, f_regression from sklearn.preprocessing import MinMaxScaler import numpy as np import pandas as pd from operator import itemgetter #Генерируем исходные данные np.random.seed(0) size = 750 X = np.random.uniform(0, 1, (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, (size,4)) #Создаем и тренируем модели lasso = Lasso(alpha=.05) lasso.fit(X, Y) # lr = LinearRegression() lr.fit(X, Y) rfe = RFE(lr) rfe.fit(X, Y) # f, pval = f_regression(X, Y, center=True) # Функция для преобразования оценок признаков в словарь def rank_to_dict(ranks, names): ranks = np.abs(ranks) minmax = MinMaxScaler() ranks = minmax.fit_transform(np.array(ranks).reshape(14, 1)).ravel() ranks = map(lambda x: round(x, 2), ranks) return dict(zip(names, ranks)) # Функция нахождения средних оценок по признакам def average_ranks(ranks): avg_ranks = {} for key, value in ranks.items(): for item in value.items(): if (item[0] not in avg_ranks): avg_ranks[item[0]] = 0 avg_ranks[item[0]] += item[1] for key, value in avg_ranks.items(): res = value / len(ranks) avg_ranks[key] = round(res, 2) avg_ranks = sorted(avg_ranks.items(), key=itemgetter(1), reverse=True) return avg_ranks #Создаем список с именами признаков names = ["x%s" % i for i in range(1, 15)] ranks = dict() #Применяем функцию к моделям ranks["Lasso"] = rank_to_dict(lasso.coef_, names) ranks["RFE"] = rank_to_dict(rfe.ranking_, names) ranks["F_reg"] = rank_to_dict(f, names) #Т.к. в RFE ранг "1" = признак важный, а если больше "1" - то менее важный #поменяем оценки на противоположные record_key = 'RFE' for key, value in ranks[record_key].items(): ranks[record_key][key] = 1 - value # Вывод оценок каждого признака table_ranks = pd.DataFrame.from_dict(ranks, orient='columns') print("Оценки важности признаков по моделям: Лассо, Рекурсивное сокращение признаков, Линейная корреляция:") print(table_ranks) # Вывод средних оценок каждого признака table_avg_ranks = pd.DataFrame.from_records(average_ranks(ranks)) print("Средние оценки важности признаков") print(table_avg_ranks.to_string(index=False, header=False))