IIS_2023_1/gordeeva_anna_lab_2/lab2.py
2023-10-14 14:26:32 +04:00

98 lines
4.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.

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)