lab2
This commit is contained in:
parent
1cd312ba98
commit
a90d980837
63
kozlov_alexey_lab_2/README.md
Normal file
63
kozlov_alexey_lab_2/README.md
Normal file
@ -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 являются наиболее значимыми для всех моделей.
|
76
kozlov_alexey_lab_2/RandomizedLasso.py
Normal file
76
kozlov_alexey_lab_2/RandomizedLasso.py
Normal file
@ -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)
|
62
kozlov_alexey_lab_2/lab2.py
Normal file
62
kozlov_alexey_lab_2/lab2.py
Normal file
@ -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()
|
BIN
kozlov_alexey_lab_2/results.png
Normal file
BIN
kozlov_alexey_lab_2/results.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
Loading…
Reference in New Issue
Block a user