IIS_2023_1/istyukov_timofey_lab_2/lab2.py
2024-01-04 22:38:07 +04:00

114 lines
5.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Используя код из пункта «Решение задачи ранжирования признаков»,
выполните ранжирование признаков с помощью указанных по варианту моделей.
Отобразите получившиеся значения\оценки каждого признака каждым методом\моделью и среднюю оценку.
Проведите анализ получившихся результатов. Какие четыре признака оказались самыми важными по среднему значению?
(Названия\индексы признаков и будут ответом на задание)
"""
# 12 вариант
# Лассо (Lasso)
# Рекурсивное сокращение признаков (Recursive Feature Elimination RFE)
# Линейная корреляция (f_regression)
import numpy as np
from sklearn.linear_model import Lasso, LinearRegression
from sklearn.feature_selection import RFE
from sklearn.feature_selection import f_regression
from sklearn.preprocessing import MinMaxScaler
def main():
X, Y = friedman_regression_problem(800)
''' Создание и обучение моделей '''
# Лассо
lasso_model = Lasso(alpha=.05)
lasso_model.fit(X, Y)
# Рекурсивное сокращение признаков
lr = LinearRegression()
lr.fit(X, Y)
rfe_model = RFE(estimator=lr)
rfe_model.fit(X, Y)
# Линейная корреляция
f, p_val = f_regression(X, Y)
# список имён признаков
names = ["x%s" % i for i in range(1, 16)]
# словарь вызова функций моделей
ranks = {}
ranks["Lasso"] = rank_to_dict(lasso_model.coef_, names)
ranks["RFE"] = rank_to_dict(rfe_model.ranking_, names)
ranks["F_reg"] = rank_to_dict(f, names)
# вывод признаков и оценок каждой модели
print_sorted_model(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)
# Сортировка и распечатка списка
mean = sorted(mean.items(), key=lambda item: item[1], reverse=True)
print("\033[92mСредния значения по каждому признаку:\033[00m")
print(mean)
# Генерация набора данных по регрессионной проблеме Фридмана
def friedman_regression_problem(size):
# генерируем исходные данные: 800 строк-наблюдений и 15 столбцов-признаков
np.random.seed(0)
X = np.random.uniform(0, 1, (size, 15))
# Задание функции-выхода (регриссионную проблему Фридмана)
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[:,11:] = X[:,:4] + np.random.normal(0, .025, (size, 4))
return X, Y
# Функция формирования словаря пар "имя_признака: оценка признака"
def rank_to_dict(ranks, names):
ranks = np.abs(ranks) #получение абсолютных значений оценок
r_array = np.array(ranks) #создание массива списка оценок
r_array = r_array.reshape(15, 1) #переформирование строк и столбцов в массиве
minmax = MinMaxScaler() # экземпляр для нормализации данных
ranks = minmax.fit_transform(r_array) #обучение и преобразование данных
ranks = ranks.ravel() #преобразование двумерного массива в одномерный
ranks = map(lambda x: round(x, 2), ranks) #округление каждого элемента массива до сотых
return dict(zip(names, ranks))
# Функция вывода признаков моделей по убыванию значения оценки
def print_sorted_model(ranks):
ranks_copy = dict(ranks)
for key, value in ranks_copy.items():
ranks_copy[key] = sorted(value.items(), key=lambda item: item[1], reverse=True)
for key, value in ranks_copy.items():
print("\033[92m---> {} <---\033[00m" .format(key))
print(value)
print()
if __name__ == "__main__":
main()