IIS_2023_1/gordeeva_anna_lab_2/lab2.py

98 lines
4.1 KiB
Python
Raw Normal View History

2023-10-14 14:26:32 +04:00
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)