diff --git a/gordeeva_anna_lab_2/Lasso_screen.png b/gordeeva_anna_lab_2/Lasso_screen.png new file mode 100644 index 0000000..38d9d14 Binary files /dev/null and b/gordeeva_anna_lab_2/Lasso_screen.png differ diff --git a/gordeeva_anna_lab_2/RFE_screen.png b/gordeeva_anna_lab_2/RFE_screen.png new file mode 100644 index 0000000..c9eb902 Binary files /dev/null and b/gordeeva_anna_lab_2/RFE_screen.png differ diff --git a/gordeeva_anna_lab_2/RandLasso_screen.png b/gordeeva_anna_lab_2/RandLasso_screen.png new file mode 100644 index 0000000..83ec62f Binary files /dev/null and b/gordeeva_anna_lab_2/RandLasso_screen.png differ diff --git a/gordeeva_anna_lab_2/lab2.py b/gordeeva_anna_lab_2/lab2.py new file mode 100644 index 0000000..d7f83b7 --- /dev/null +++ b/gordeeva_anna_lab_2/lab2.py @@ -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) + diff --git a/gordeeva_anna_lab_2/readme.md b/gordeeva_anna_lab_2/readme.md new file mode 100644 index 0000000..53ffa73 --- /dev/null +++ b/gordeeva_anna_lab_2/readme.md @@ -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. \ No newline at end of file