98 lines
4.1 KiB
Python
98 lines
4.1 KiB
Python
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)
|
||
|