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)