Merge pull request 'sergeev_evgenii_lab_2_is_done' (#94) from sergeev_evgenii_lab_2 into main

Reviewed-on: http://student.git.athene.tech/Alexey/IIS_2023_1/pulls/94
This commit is contained in:
Alexey 2023-10-27 11:17:36 +04:00
commit c7060e6719
2 changed files with 159 additions and 0 deletions

View File

@ -0,0 +1,112 @@
from sklearn.feature_selection import RFE
from sklearn.linear_model import Ridge, Lasso, LinearRegression
from sklearn.preprocessing import MinMaxScaler
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
n_features = 10
n = 800
# Создаем группу графиков 4 на 3
figure = plt.figure(1, figsize=(16, 9))
# Создаем 4 графика
axis = figure.subplots(1, 4)
# Генерируем исходные данные: 750 строк-наблюдений и 10 столбцов-признаков
np.random.seed(0)
size = n
X = np.random.uniform(0, 1, (size, n_features))
# Задаем функцию-выход: регрессионную проблему Фридмана
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[:, n_features-4:] = X[:, :4] + np.random.normal(0, .025, (size, 4))
# Функция для преобразования вывода оценок к словарю
def rank_to_dict(r, tags):
r = np.abs(r)
minmax = MinMaxScaler()
r = minmax.fit_transform(np.array(r).reshape(n_features, 1)).ravel()
r = map(lambda x: round(x, 2), r)
return dict(zip(tags, r))
# Добавляет данные на графики
def add_scatter(k, v, i):
# График данных по каждой модели
pred = lambda x: "x" + str(x + 1)
axis[i].bar(list(pred(i) for i in range(n_features)), list(v.values()), label=k)
axis[i].set_title(k)
# Гребневая модель
ridge = Ridge()
ridge.fit(X, Y)
# Случайное Лассо
lasso = Lasso(alpha=.05)
lasso.fit(X, Y)
# Рекурсивное сокращение признаков
# Создаю классификатор для оценки важности признаков
rfe = RFE(estimator=LinearRegression(),
n_features_to_select=4) # сюда еще можно засунуть n_features_to_select=n - сохраняем
# определенное количество признаков
rfe.fit(X, Y)
# Создаем вывод
names = ["x%s" % i for i in range(1, n_features + 1)]
rfe_res = rfe.ranking_
# Приводим значения RFE модели к диапазону (0, 1)
for i in range(rfe_res.size):
rfe_res[i] = n_features - rfe_res[i]
ranks = {"Ridge": rank_to_dict(ridge.coef_, names), "Lasso": rank_to_dict(lasso.coef_, names),
"RFE": rank_to_dict(rfe.ranking_, names)}
# Создаем пустой список для данных
mean = {}
# «Бежим» по списку ranks
for key, value in ranks.items():
# «Пробегаемся» по списку значений ranks, которые являются парой имя:оценка
for item in value.items():
# имя будет ключом для нашего mean
# если элемента с текущим ключем в mean нет - добавляем
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 = dict(sorted(mean.items(), key=lambda y: y[1], reverse=True))
ranks["Mean"] = mean
for key, value in ranks.items():
ranks[key] = dict(sorted(value.items(), key=lambda y: y[1], reverse=True))
# Создаем DataFrame из результатов ранжирования
df = pd.DataFrame(ranks)
# Выводим результаты на экран
print("Ранжирование признаков:")
print(df)
# Визуализируем результаты
i = 0
for key, value in ranks.items():
add_scatter(key, value, i)
i += 1
plt.show()

View File

@ -0,0 +1,47 @@
# Лабораторная работа 2. Ранжирование признаков
## Задание
Выполнить ранжирование признаков с помощью указанных по варианту моделей.
Отобразить получившиеся значения\оценки каждого признака каждым методом\моделью и среднюю оценку.
Провести анализ получившихся результатов. Определить, какие четыре признака оказались самыми важными по среднему значению.
Вариант 4 (24).
Модели:
* Гребневая регрессия (Ridge)
* Случайное Лассо (RandomizedLasso)
* Рекурсивное сокращение признаков (Recursive Feature Elimination RFE)
### Запуск программы
Файл lab2.py содержит и запускает программу
### Описание программы
Программа создаёт набор данных с 10 (n_features) признаками для последующего их ранжирования и обрабатывает тремя моделями по варианту.
Программа строит столбчатые диаграммы, которые показывают как распределились оценки важности признаков и выводит в консоль отсортированные по убыванию важности признаки.
Таким образом можно легко определить наиважнейшие признаки.
### Результаты тестирования
По результатам тестирования, можно сказать следующее:
* Гребневая регрессия показывает хорошие результаты, выделяет все 8 значимых признаков.
* Случайное лассо справляется хуже других моделей, выделяет только 4 значимых признака.
* Рекурсивное сокращение признаков показывает хорошие результаты, правильно выделяя 9 значимых признаков.
* Среднее значение позволяет c хорошей уверенностью определять истинные значимые признаки. (x4, x2, x1, x5)
Вывод:
Если вы хотите уменьшить размерность данных и выбрать определенное количество признаков, рассмотрите модель RFE.
Если вам важно сохранить все признаки, но учитывать их важность, модель Ridge может быть подходящей.
Если вам нужно сильно ужать данные и выбрать только наиболее важные признаки, рассмотрите модель Lasso.
Пример консольных результатов:
Ridge Lasso RFE Mean
x4 1.00 1.00 1.00 0.33
x2 0.73 0.68 1.00 0.24
x1 0.65 0.66 1.00 0.22
x5 0.40 0.26 0.50 0.13
x10 0.32 0.00 0.83 0.11
x7 0.24 0.00 0.67 0.08
x8 0.19 0.00 1.00 0.06
x9 0.03 0.00 0.33 0.01
x3 0.00 0.00 0.17 0.00
x6 0.00 0.00 0.00 0.00
По данным результатам можно заключить, что наиболее влиятельные признаки по убыванию: x4, x2, x1, x5.