IIS_2023_1/kurmyza_pavel_lab_2/main.py

95 lines
3.1 KiB
Python
Raw Permalink Normal View History

2023-10-22 19:15:28 +04:00
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)}")