diff --git a/kurmyza_pavel_lab_2/README.md b/kurmyza_pavel_lab_2/README.md new file mode 100644 index 0000000..a11ce81 --- /dev/null +++ b/kurmyza_pavel_lab_2/README.md @@ -0,0 +1,59 @@ +# Лабораторная работа №2 + +## ПИбд-41, Курмыза Павел, Вариант 13 + +## Как запустить ЛР + +- Запустить файл main.py + +## Используемые технологии + +- Язык программирования Python +- Библиотеки: sklearn, numpy + +## Что делает программа + +Выполняет ранжирование 14 признаков для регрессионной проблемы Фридмана с помощью моделей: + +- Рекурсивное сокращение признаков (Recursive Feature Elimination – RFE) +- Сокращение признаков Случайными деревьями (Random Forest Regressor) +- Линейная корреляция (f_regression) + +Отображение получившихся результатов: 4 самых важных признака по среднему значению, значения признаков для каждой +модели. + +## Результаты + +### RFE + +{'x1': 1.0, 'x2': 1.0, 'x3': 1.0, 'x4': 1.0, 'x5': 1.0, 'x11': 1.0, 'x13': 1.0, 'x12': 0.86, 'x14': 0.71, 'x8': 0.57, ' +x6': 0.43, 'x10': 0.29, 'x7': 0.14, 'x9': 0.0} + +### RFR + +{'x14': 1.0, 'x2': 0.84, 'x4': 0.77, 'x1': 0.74, 'x11': 0.36, 'x12': 0.35, 'x5': 0.28, 'x3': 0.12, 'x13': 0.12, 'x6': +0.01, 'x7': 0.01, 'x8': 0.01, 'x9': 0.01, 'x10': 0.0} + +### f_regression + +{'x4': 1.0, 'x14': 0.97, 'x2': 0.57, 'x12': 0.56, 'x1': 0.44, 'x11': 0.43, 'x5': 0.17, 'x8': 0.13, 'x7': 0.1, 'x9': +0.08, 'x10': 0.05, 'x6': 0.04, 'x3': 0.01, 'x13': 0.0} + +### Средние значения + +{'x1': 0.33, 'x2': 0.33, 'x3': 0.33, 'x4': 0.33, 'x5': 0.33, 'x11': 0.33, 'x13': 0.33, 'x12': 0.29, 'x14': 0.24, 'x8': +0.19, 'x6': 0.14, 'x10': 0.1, 'x7': 0.05, 'x9': 0.0} + +## Вывод + +По итогу тестирования было выявлено: + +1. Модель рекурсивного сокращения признаков отдала предпочтение многим важным параметрам таким как x1, x2, x3, x4, x5, + x11, x13, x12, x14. +2. Модель сокращения признаков случайными деревьями выявила в качестве важных признаков x14, x2, x4, x1. Несмотря на то, + что признак x3 не был выявлен, его влияние может быть учтено через скоррелированный параметр x14. +3. Метод линейной корреляции (f_regression) сделал наилучшее взвешивание, отдав предпочтение прзинакам x4, x14, x2, x12. + Несмотря на то, что признаки x1 и x3 не были выявлены, их влияние может быть учтено через скоррелированные параметры + x12 и x14. + +Согласно среднему значению, важными признаками являются: x1, x2, x3, x4, x5. \ No newline at end of file diff --git a/kurmyza_pavel_lab_2/main.py b/kurmyza_pavel_lab_2/main.py new file mode 100644 index 0000000..c8108e9 --- /dev/null +++ b/kurmyza_pavel_lab_2/main.py @@ -0,0 +1,94 @@ +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)}")