from sklearn.linear_model import Lasso
from sklearn.ensemble import RandomForestRegressor
from sklearn.feature_selection import f_regression
from sklearn.preprocessing import MinMaxScaler
import numpy as np

np.random.seed(0)
size = 750
#входные данные.
X = np.random.uniform(0, 1, (size, 14))

#Генерируется целевая переменная Y на основе математической функции от входных данных X.
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))

names = ["x%s" % i for i in range(1,15)]
#Создается пустой словарь для хранения рангов признаков
ranks = {}

#Создается экземпляр модели лассо-регрессии
lasso = Lasso(alpha=.05)
#Модель подгоняется под входные данные X и целевую переменную Y
lasso.fit(X, Y)
ranks["Lasso"] = dict(zip(names, lasso.coef_))

rf = RandomForestRegressor(n_estimators=100, random_state=0)
rf.fit(X, Y)
ranks["Random Forest"] = dict(zip(names, rf.feature_importances_))

f, _ = f_regression(X, Y, center=True)
ranks["f_regression"] = dict(zip(names, f))

def rank_to_dict(ranks, names):
    ranks = np.abs(ranks)
    minmax = MinMaxScaler()
    #масштабирование рангов с помощью MinMaxScaler
    ranks = minmax.fit_transform(np.array(ranks).reshape(-1, 1)).ravel()
    ranks = map(lambda x: round(x, 2), ranks)
    return dict(zip(names, 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]

sorted_mean = sorted(mean.items(), key=lambda x: x[1], reverse=True)
result = {}
for item in sorted_mean:
    result[item[0]] = item[1]
    print(f'{item[0]}: {item[1]}')
