From a90d9808378c23adae5005f77c61d6048945ee6e Mon Sep 17 00:00:00 2001 From: Nelikey Date: Fri, 12 Jan 2024 11:36:28 +0400 Subject: [PATCH] lab2 --- kozlov_alexey_lab_2/README.md | 63 ++++++++++++++++++++ kozlov_alexey_lab_2/RandomizedLasso.py | 76 +++++++++++++++++++++++++ kozlov_alexey_lab_2/lab2.py | 62 ++++++++++++++++++++ kozlov_alexey_lab_2/results.png | Bin 0 -> 32460 bytes 4 files changed, 201 insertions(+) create mode 100644 kozlov_alexey_lab_2/README.md create mode 100644 kozlov_alexey_lab_2/RandomizedLasso.py create mode 100644 kozlov_alexey_lab_2/lab2.py create mode 100644 kozlov_alexey_lab_2/results.png diff --git a/kozlov_alexey_lab_2/README.md b/kozlov_alexey_lab_2/README.md new file mode 100644 index 0000000..c00bf4b --- /dev/null +++ b/kozlov_alexey_lab_2/README.md @@ -0,0 +1,63 @@ +# Лабораторная работа №2. Ранжирование признаков +## 14 вариант +___ + +### Задание: +Используя код из [1](пункт «Решение задачи ранжирования признаков», стр. 205), выполните ранжирование признаков с помощью указанных по варианту моделей. Отобразите получившиеся значения\оценки каждого признака каждым методом\моделью и среднюю оценку. Проведите анализ получившихся результатов. Какие четыре признака оказались самыми важными по среднему значению? (Названия\индексы признаков и будут ответом на задание). + +### Модели по варианту: +- Случайное Лассо (RandomizedLasso) +- Сокращение признаков cлучайными деревьями (Random Forest Regressor) +- Линейная корреляция (f_regression) + +___ + +### Запуск +- Запустить файл lab2.py + +### Используемые технологии +- Язык программирования **Python** +- Среда разработки **PyCharm** +- Библиотеки: + * sklearn + * matplotlib + * numpy + +### Описание программы +1. Импортирует необходимые модули и классы: + - RandomForestRegressor из sklearn.ensemble для создания модели случайного леса регрессии; + - RandomizedLasso из RandomizedLasso для создания модели случайного Лассо (метода регуляризации линейной регрессии); + - f_regression из sklearn.feature_selection для выполнения линейной корреляции между признаками и целевой переменной; + - MinMaxScaler из sklearn.preprocessing для масштабирования оценок признаков к диапазону [0, 1]; + - numpy для работы с массивами данных. + +2. Определяет функцию generation_data, которая генерирует случайные данные для обучения модели. Для простоты, будут использованы заранее определенные случайные значения. + +3. Определяет функцию rank_to_dict, которая принимает ранговые оценки признаков и преобразует их в словарь с нормализованными значениями от 0 до 1. + +4. Определяет функцию get_estimation, которая вычисляет среднюю оценку по всем моделям и выводит отсортированный список признаков по убыванию оценки. + +5. Определяет функцию print_sorted_data, которая выводит отсортированные оценки признаков для каждой модели. + +6. Определяет функцию main, которая объединяет все шаги: генерацию данных, обучение моделей, расчет оценок признаков и вывод результатов. + +7. Вызывает функцию main для выполнения программы. + +___ +### Пример работы + +![Graphics](results.png) + + +### Вывод +На основе результатов можно сделать следующие выводы: + +1. Признаки x4, x2, x14 и x1 являются самыми важными. Их средние оценки по всем моделям составляют 0.82, 0.8, 0.66 и 0.56 соответственно. + +2. В модели случайного леса регрессии наиболее значимыми признаками являются x14, x2, x4 и x1. Они имеют оценки 1.0, 0.84, 0.77 и 0.74 соответственно. + +3. По результатам линейной корреляции (f-регрессия), самыми важными признаками также являются x4, x14, x2 и x12 с оценками 1.0, 0.97, 0.57 и 0.56 соответственно. + +4. В модели случайного Лассо наиболее значимыми признаками являются x2, x4, x1 и x5. Их оценки составляют 1.0, 0.69, 0.49 и 0.44 соответственно. + +Таким образом, можно сделать вывод, что признаки x4, x2, x14 и x1 являются наиболее значимыми для всех моделей. \ No newline at end of file diff --git a/kozlov_alexey_lab_2/RandomizedLasso.py b/kozlov_alexey_lab_2/RandomizedLasso.py new file mode 100644 index 0000000..8ac9681 --- /dev/null +++ b/kozlov_alexey_lab_2/RandomizedLasso.py @@ -0,0 +1,76 @@ +from sklearn.utils import check_X_y, check_random_state +from sklearn.linear_model import Lasso +from scipy.sparse import issparse +from scipy import sparse + + +def _rescale_data(x, weights): + if issparse(x): + size = weights.shape[0] + weight_dia = sparse.dia_matrix((1 - weights, 0), (size, size)) + x_rescaled = x * weight_dia + else: + x_rescaled = x * (1 - weights) + + return x_rescaled + + +class RandomizedLasso(Lasso): + """ + Randomized version of scikit-learns Lasso class. + + Randomized LASSO is a generalization of the LASSO. The LASSO penalises + the absolute value of the coefficients with a penalty term proportional + to `alpha`, but the randomized LASSO changes the penalty to a randomly + chosen value in the range `[alpha, alpha/weakness]`. + + Parameters + ---------- + weakness : float + Weakness value for randomized LASSO. Must be in (0, 1]. + + See also + -------- + sklearn.linear_model.LogisticRegression : learns logistic regression models + using the same algorithm. + """ + def __init__(self, weakness=0.5, alpha=1.0, fit_intercept=True, + precompute=False, copy_X=True, max_iter=1000, + tol=1e-4, warm_start=False, positive=False, + random_state=None, selection='cyclic'): + self.weakness = weakness + super(RandomizedLasso, self).__init__( + alpha=alpha, fit_intercept=fit_intercept, precompute=precompute, copy_X=copy_X, + max_iter=max_iter, tol=tol, warm_start=warm_start, + positive=positive, random_state=random_state, + selection=selection) + + def fit(self, X, y): + """Fit the model according to the given training data. + + Parameters + ---------- + X : {array-like, sparse matrix}, shape = [n_samples, n_features] + The training input samples. + + y : array-like, shape = [n_samples] + The target values. + """ + if not isinstance(self.weakness, float) or not (0.0 < self.weakness <= 1.0): + raise ValueError('weakness should be a float in (0, 1], got %s' % self.weakness) + + X, y = check_X_y(X, y, accept_sparse=True) + + n_features = X.shape[1] + weakness = 1. - self.weakness + random_state = check_random_state(self.random_state) + + weights = weakness * random_state.randint(0, 1 + 1, size=(n_features,)) + + # TODO: I am afraid this will do double normalization if set to true + #X, y, _, _ = _preprocess_data(X, y, self.fit_intercept, normalize=self.normalize, copy=False, + # sample_weight=None, return_mean=False) + + # TODO: Check if this is a problem if it happens before standardization + X_rescaled = _rescale_data(X, weights) + return super(RandomizedLasso, self).fit(X_rescaled, y) diff --git a/kozlov_alexey_lab_2/lab2.py b/kozlov_alexey_lab_2/lab2.py new file mode 100644 index 0000000..a65bf0b --- /dev/null +++ b/kozlov_alexey_lab_2/lab2.py @@ -0,0 +1,62 @@ +from sklearn.ensemble import RandomForestRegressor +from RandomizedLasso import RandomizedLasso +from sklearn.feature_selection import f_regression +from sklearn.preprocessing import MinMaxScaler +import numpy as np + +names = ["x%s" % i for i in range(1, 15)] +def main(): + x,y = generation_data() + # Сокращение признаков cлучайными деревьями (Random Forest Regressor) + rfr = RandomForestRegressor() + rfr.fit(x, y) + # Модель линейной корреляции + f, _ = f_regression(x, y, center=False) + # Случайное Лассо + randomized_lasso = RandomizedLasso(alpha=.01) + randomized_lasso.fit(x, y) + + ranks = {"Random Forest Regressor": rank_to_dict(rfr.feature_importances_), 'f-Regression': rank_to_dict(f), "Randomize Lasso": rank_to_dict(randomized_lasso.coef_)} + + get_estimation(ranks) + print_sorted_data(ranks) +def generation_data(): + 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)) + return X, Y +def rank_to_dict(ranks): + ranks = np.abs(ranks) + minmax = MinMaxScaler() + ranks = minmax.fit_transform(np.array(ranks).reshape(14, 1)).ravel() + ranks = map(lambda x: round(x, 2), ranks) + return dict(zip(names, ranks)) +def get_estimation(ranks: {}): + mean = {} + for key, value in ranks.items(): + for item in value.items(): + if(item[0] not in mean): + mean[item[0]] = 0 + mean[item[0]] += item[1] + for key, value in mean.items(): + res = value/len(ranks) + mean[key] = round(res, 2) + mean_sorted = sorted(mean.items(), key=lambda item: item[1], reverse=True) + print("Средние значения") + print(mean_sorted) + print("4 самых важных признака по среднему значению") + for item in mean_sorted[:4]: + print('{0} - {1}'.format(item[0], item[1])) +def print_sorted_data(ranks: {}): + print() + for key, value in ranks.items(): + ranks[key] = sorted(value.items(), key=lambda item: item[1], reverse=True) + for key, value in ranks.items(): + print(key) + print(value) + + +main() \ No newline at end of file diff --git a/kozlov_alexey_lab_2/results.png b/kozlov_alexey_lab_2/results.png new file mode 100644 index 0000000000000000000000000000000000000000..b9013491dbfd72ab34668efc2212ae4f5f059497 GIT binary patch literal 32460 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 literal 0 HcmV?d00001