Merge pull request 'podkorytova_yulia_lab2 is ready' (#93) from podkorytova_yulia_lab_2 into main

Reviewed-on: http://student.git.athene.tech/Alexey/IIS_2023_1/pulls/93
This commit is contained in:
Alexey 2023-10-27 11:19:01 +04:00
commit dd0d45ef93
7 changed files with 109 additions and 0 deletions

View File

@ -0,0 +1,42 @@
# Лабораторная работа 2. Ранжирование признаков
### Задание на лабораторную:
Используя код из пункта «Решение задачи ранжирования признаков», выполните ранжирование признаков с помощью указанных по варианту моделей. Отобразите получившиеся значения\оценки каждого признака каждым методом\моделью и среднюю оценку. Проведите анализ получившихся результатов. Какие четыре признака оказались самыми важными по среднему значению? (Названия\индексы признаков и будут ответом на задание).
**Вариант 20.** Линейная регрессия (LinearRegression), Гребневая регрессия
(Ridge), Лассо (Lasso), Линейная корреляция (f_regression).
***
### Как запустить лабораторную работу:
Для запуска лабораторной работы необходимо открыть файл `lr2.py`, нажать на ПКМ и в выпадающем списке выбрать опцию "Run".
***
### Технологии:
**NumPy (Numerical Python)** - это библиотека для научных вычислений в Python, которая обеспечивает эффективные вычисления и манипуляции с данными.
**Scikit-learn (Sklearn)** - это библиотека для языка программирования Python, которая предоставляет инструменты для разработки и применения различных алгоритмов машинного обучения, включая классификацию, регрессию, кластеризацию, снижение размерности и многое другое. Scikit-learn также предлагает функции для предобработки данных, оценки моделей и выбора наилучших параметров.
***
### Что делает лабораторная работа:
В лабораторной работе генерируются исходные данные (750 строк-наблюдений и 14 столбцов-признаков), задается зависимость для функции-выхода Y с использованием формулы регрессионной проблемы Фридмана, а также добавляется зависимость между признаками.
Далее создаются 4 модели (линейная регрессия, гребневая регрессия, лассо и линейная корреляция).
Для каждой модели происходит тренировка и оценка рангов признаков с помощью функции *rank_to_dict*.
Средние оценки признаков вычисляются при помощи функции *mean_ranks*.
Результатом работы являются оценки признаков для каждой из 4 моделей и средние оценки признаков, выведенные в консоль.
***
### Пример выходных данных:
**ОЦЕНКИ ПРИЗНАКОВ**
![](linear_regression.jpg)
![](ridge.jpg)
![](lasso.jpg)
![](f_regression.jpg)
**СРЕДНИЕ ОЦЕНКИ ПРИЗНАКОВ**
![](mean.jpg)
***
**Вывод**: результаты показали, что признаки "х4", "х1", "х2" и "х14" - это четыре самых важных признака по среднему значению, при этом признак "х14" был признан ошибочно значимым.
Модель *Лассо* выявила все значимые признаки (х1-х5), не взяв никакого лишнего.
Модель *Линейная регрессия* верно выявила значимость признаков *x1, x2, x3, х4*, но потеряла значимый признак *x5* и ошибочно включила признак *x11* в значимые.
Модель *Гребневая регрессия* верно выявила значимость признаков *x1, x2, x4, х5*, но потеряла значимый признак *x3* и ошибочно включила признак *x14* в значимые.
Модель *Линейная корреляция* верно выявила значимость признаков *x1, x2, x4*, но потеряла значимые признак *x3, х5* и ошибочно включила признаки *x12, х14* в значимые.

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -0,0 +1,67 @@
from sklearn.feature_selection import f_regression
from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.preprocessing import MinMaxScaler
import numpy as np
def rank_to_dict(ranks, names):
ranks = np.abs(ranks)
minmax = MinMaxScaler()
ranks = minmax.fit_transform(np.array(ranks).reshape(14, 1)).ravel()
ranks = map(lambda x: round(x, 2), ranks)
return dict(zip(names, ranks))
def mean_ranks(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)
sorted_mean = sorted(mean.items(), key=lambda x: x[1], reverse=True)
return sorted_mean
# генерируем исходные данные: 750 строк-наблюдений и 14 столбцов-признаков
np.random.seed(0)
size = 750
X = np.random.uniform(0, 1, (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, (size,4))
# создаем модели
linear_regression = LinearRegression()
ridge = Ridge()
lasso = Lasso(alpha=.05)
f, pval = f_regression(X, Y, center=True)
models = [("Линейная регрессия", linear_regression),
("Гребневая регрессия", ridge),
("Лассо", lasso),
("Линейная корреляция", f)]
names = ["x%s" % i for i in range(1,15)] # список содержащий, имена признаков
ranks = {} # словарь для хранения рангов признаков
for (name, model) in models:
if name != "Линейная корреляция":
model.fit(X, Y) # тренируем модель
ranks[name] = rank_to_dict(model.coef_, names) # преобразуем признаки в словарь
else:
ranks[name] = rank_to_dict(model, names)
print("-----ОЦЕНКИ ПРИЗНАКОВ-----")
for key, value in ranks.items():
print(key, ":")
for item in value.items():
print(item[0], "-", item[1])
print()
print("---СРЕДНИЕ ОЦЕНКИ ПРИЗНАКОВ---")
for r in mean_ranks(ranks):
print(r[0], "-", r[1])

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB