95 lines
3.1 KiB
Python
95 lines
3.1 KiB
Python
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)}")
|