Merge pull request 'gordeeva_anna_lab_2' (#42) from gordeeva_anna_lab_2 into main
Reviewed-on: http://student.git.athene.tech/Alexey/IIS_2023_1/pulls/42
This commit is contained in:
commit
41e0e8598f
BIN
gordeeva_anna_lab_2/Lasso_screen.png
Normal file
BIN
gordeeva_anna_lab_2/Lasso_screen.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 61 KiB |
BIN
gordeeva_anna_lab_2/RFE_screen.png
Normal file
BIN
gordeeva_anna_lab_2/RFE_screen.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 43 KiB |
BIN
gordeeva_anna_lab_2/RandLasso_screen.png
Normal file
BIN
gordeeva_anna_lab_2/RandLasso_screen.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 43 KiB |
97
gordeeva_anna_lab_2/lab2.py
Normal file
97
gordeeva_anna_lab_2/lab2.py
Normal file
@ -0,0 +1,97 @@
|
||||
import streamlit as st
|
||||
import numpy as np
|
||||
from sklearn.linear_model import Lasso
|
||||
from sklearn.preprocessing import MinMaxScaler
|
||||
from sklearn.linear_model import LassoCV
|
||||
from sklearn.feature_selection import SelectFromModel
|
||||
from sklearn.feature_selection import RFE
|
||||
|
||||
st.header("Лабораторная работа 2. Вариант 7. Лассо, случайное лассо, рекурсивное сокращение признаков")
|
||||
|
||||
# генерируем исходные данные: 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))
|
||||
|
||||
|
||||
# Создание списка пар в формате: номер признака - средняя оценка
|
||||
names = ["x%s" % i for i in range(1, 15)] # Список имен признаков
|
||||
|
||||
def random_lasso(X, Y, n_subsets=100):
|
||||
n_samples, n_features = X.shape
|
||||
selected_features = np.zeros(n_features)
|
||||
|
||||
for _ in range(n_subsets):
|
||||
# Создаем случайное подмножество признаков
|
||||
subset_indices = np.random.choice(n_features, int(n_features * 0.7), replace=False)
|
||||
X_subset = X[:, subset_indices]
|
||||
|
||||
# Создаем LassoCV модель
|
||||
lasso_cv = LassoCV(alphas=[0.05])
|
||||
|
||||
# Обучаем модель на подмножестве признаков
|
||||
lasso_cv.fit(X_subset, Y)
|
||||
|
||||
# Определяем, какие признаки были выбраны
|
||||
selected_features[subset_indices] += (lasso_cv.coef_ != 0)
|
||||
|
||||
# Вычисляем, какие признаки были выбраны чаще всего
|
||||
most_selected_features = np.where(selected_features > n_subsets / 2)[0]
|
||||
|
||||
return most_selected_features
|
||||
|
||||
def rank_to_dict(ranks, name):
|
||||
ranks = np.abs(ranks)
|
||||
minmax = MinMaxScaler()
|
||||
ranks = minmax.fit_transform(np.array(ranks).reshape(-1, 1)).ravel()
|
||||
ranks = list(map(lambda x: round(x, 2), ranks))
|
||||
ranked_features = list(zip(name, ranks))
|
||||
return ranked_features
|
||||
|
||||
def mean_rank(ranks):
|
||||
total = sum(rank for _, rank in ranks)
|
||||
return total / len(ranks)
|
||||
|
||||
# Переключатели
|
||||
lasso_check = st.checkbox("Лассо")
|
||||
random_lasso_check = st.checkbox("Случайное лассо")
|
||||
RFE_check = st.checkbox("Рекурсивное сокращение признаков")
|
||||
|
||||
# Результаты
|
||||
if lasso_check:
|
||||
model_lasso = Lasso(alpha=.05)
|
||||
model_lasso.fit(X, Y)
|
||||
rank = rank_to_dict(model_lasso.coef_, names)
|
||||
mean = mean_rank(rank)
|
||||
st.write("Получившиеся оценки для каждого признака")
|
||||
st.table(rank)
|
||||
st.write("Средняя оценка: ", mean)
|
||||
|
||||
if random_lasso_check:
|
||||
selected_features = random_lasso(X, Y)
|
||||
X_subset = X[:, selected_features]
|
||||
lasso_cv = LassoCV(alphas=[0.05])
|
||||
lasso_cv.fit(X_subset, Y)
|
||||
rank = rank_to_dict(lasso_cv.coef_, [names[i] for i in selected_features])
|
||||
mean = mean_rank(rank)
|
||||
st.write("Получившиеся оценки")
|
||||
st.table(rank)
|
||||
st.write("Средняя оценка: ", mean)
|
||||
|
||||
if RFE_check:
|
||||
model_lasso = Lasso(alpha=0.05)
|
||||
rfe = RFE(model_lasso, n_features_to_select=4)
|
||||
rfe.fit(X, Y)
|
||||
selected_feature_indices = rfe.support_
|
||||
selected_feature_names = [name for i, name in enumerate(names) if selected_feature_indices[i]]
|
||||
rank = rank_to_dict(rfe.ranking_, selected_feature_names)
|
||||
mean = mean_rank(rank)
|
||||
st.write("Получившиеся оценки")
|
||||
st.table(rank)
|
||||
st.write("Средняя оценка: ", mean)
|
||||
|
56
gordeeva_anna_lab_2/readme.md
Normal file
56
gordeeva_anna_lab_2/readme.md
Normal file
@ -0,0 +1,56 @@
|
||||
## Задание
|
||||
Модели:
|
||||
* Лассо (Lasso)
|
||||
* Случайное лассо (RandomizedLasso)
|
||||
* Рекурсивное сокращение признаков (Recursive Feature Elimination – RFE)
|
||||
|
||||
## В чем различие каждой модели
|
||||
|
||||
Лассо (Lasso) автоматически отбирает наиболее важные признаки и уменьшает влияние менее важных.
|
||||
|
||||
Случайное лассо (RandomizedLasso) случайным образом выбирает подмножества признаков из исходных данных и применяет Лассо к каждому из них. Затем он объединяет результаты и определяет, какие признаки были выбраны чаще всего.
|
||||
|
||||
Рекурсивное сокращение признаков (Recursive Feature Elimination – RFE) оценивает важность каждого признака. Затем он удаляет наименее важный признак и повторяет процесс, пока не останется желаемое количество признаков.
|
||||
|
||||
|
||||
## Библиотеки
|
||||
Streamlit. Предоставляет простой способ создания веб-приложений для визуализации данных.
|
||||
|
||||
Numpy. Предоставляет возможность работать с массивами и матрицами.
|
||||
|
||||
Sklearn. Предоставляет инструменты и алгоритмы, которые упрощают задачи, связанные с машинным обучением.
|
||||
|
||||
## Функционал
|
||||
* Генерация исходных данных из 750 строк-наблюдений и 14 столбцов-признаков
|
||||
* Создание и обучение таких моделей, как лассо, случайное лассо и рекурсивное сокращение признаков.
|
||||
* Вывод получившихся оценок для признаков и средней оценки.
|
||||
|
||||
## Запуск
|
||||
Перед запуском необходимо запустить виртуальную среду venv. Так как я использую streamlit, то для запуска необходимо в терминал прописать следующую строку:
|
||||
```
|
||||
streamlit run lab1.py
|
||||
```
|
||||
Приложение развернется на локальном сервере и автоматически откроется в браузере.
|
||||
|
||||
## Скриншоты работы программы
|
||||
Лассо (Lasso)
|
||||
|
||||
![Alt text](Lasso_screen.png "Optional Title")
|
||||
|
||||
Случайное лассо (RandomizedLasso)
|
||||
|
||||
![Alt text](RandLasso_screen.png "Optional Title")
|
||||
|
||||
Рекурсивное сокращение признаков (Recursive Feature Elimination – RFE)
|
||||
|
||||
![Alt text](RFE_screen.png "Optional Title")
|
||||
|
||||
## Вывод
|
||||
Модель лассо выводит все 14 признаков, наиболее важными признаками оказались под индексом
|
||||
1, 2, 4 и 5. Самый важный признак под номером 4. Средняя оценка по всем признакам 0.19.
|
||||
|
||||
Модель случайное лассо выводит наиболее важные признаки, такими признаками являются 1, 2, 4 и 5. Средняя оценка же по этим признакам равна 0.53. Она выше, так как мы исключаем маловажные признаки.
|
||||
|
||||
Модель рекурсивного сокращения признаков выводит 4 признака, так как я указала именно вывод 4 признаков в коде программы. Таким образом, модель отсекает маловажные признаки. Самым важным признаком оказался под номером 4. Средняя оценка: 0.25.
|
||||
|
||||
Как итог, можно сказать, что наиболее важными признаками являются 1, 2, 4 и 5. А самым важным из них является признак под номером 4.
|
Loading…
Reference in New Issue
Block a user