Merge pull request 'alexandrov_dmitrii_lab_2' (#15) from alexandrov_dmitrii_lab_2 into main

Reviewed-on: http://student.git.athene.tech/Alexey/IIS_2023_1/pulls/15
This commit is contained in:
Alexey 2023-10-08 13:47:15 +04:00
commit 7ce7f86d4b
2 changed files with 132 additions and 0 deletions

View File

@ -0,0 +1,82 @@
from sklearn.linear_model import LinearRegression, RandomizedLasso
from sklearn.feature_selection import RFE
from sklearn.preprocessing import MinMaxScaler
from matplotlib import pyplot as plt
import numpy as np
import random as rand
figure = plt.figure(1, figsize=(16, 9))
axis = figure.subplots(1, 4)
col = 0
y = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
def rank_to_dict(ranks, names, n_features):
ranks = np.abs(ranks)
minmax = MinMaxScaler()
ranks = minmax.fit_transform(np.array(ranks).reshape(n_features, 1)).ravel()
ranks = map(lambda x: round(x, 2), ranks)
return dict(zip(names, ranks))
def createView(key, val):
global figure
global axis
global col
global y
axis[col].bar(y, list(val.values()), label=key)
axis[col].set_title(key)
col = col + 1
def start():
np.random.seed(rand.randint(0, 50))
size = 750
n_features = 14
X = np.random.uniform(0, 1, (size, n_features))
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))
lr = LinearRegression()
rl = RandomizedLasso()
rfe = RFE(estimator=LinearRegression(), n_features_to_select=1)
lr.fit(X, Y)
rl.fit(X, Y)
rfe.fit(X, Y)
names = ["x%s" % i for i in range(1, n_features + 1)]
rfe_res = rfe.ranking_
for i in range(rfe_res.size):
rfe_res[i] = 14 - rfe_res[i]
ranks = {"Linear regression": rank_to_dict(lr.coef_, names, n_features),
"Random lasso": rank_to_dict(rl.scores_, names, n_features),
"RFE": rank_to_dict(rfe_res, names, n_features)}
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)
ranks["Mean"] = mean
for key, value in ranks.items():
createView(key, value)
ranks[key] = sorted(value.items(), key=lambda y: y[1], reverse=True)
for key, value in ranks.items():
print(key)
print(value)
start()
plt.show()

View File

@ -0,0 +1,50 @@
### Задание
Выполнить ранжирование признаков с помощью указанных по варианту моделей. Отобразить получившиеся значения\оценки каждого признака каждым методом\моделью и среднюю оценку. Провести анализ получившихся результатов. Определить, какие четыре признака оказались самыми важными по среднему значению.
Вариант 1.
Модели:
* Линейная регрессия (LinearRegression)
* Случайное Лассо (RandomizedLasso)
* Рекурсивное сокращение признаков (Recursive Feature Elimination RFE)
### Запуск программы
Программа работает на Python 3.7, поскольку только в нём можно подключить нужную версию библиотеки scikit-learn, которая ещё содержит RandomizedLasso.
Файл lab2.py содержит и запускает программу, аргументов и настройки ~~вроде~~ не требует.
### Описание программы
Файл lab2.py содержит непосредственно программу.
Программа создаёт набор данных с 10 признаками для последующего их ранжирования, и обрабатывает тремя моделями по варианту.
Программа строит столбчатые диаграммы, которые показывают как распределились оценки важности признаков, и выводит в консоль отсортированные по убыванию важности признаки.
Таким образом можно легко определить наиважнейшие признаки.
### Результаты тестирования
По результатам тестирования, можно сказать следующее:
* линейная регрессия показывает хорошие результаты, выделяет все 9 значимых признаков.
* случайное лассо справляется хуже других моделей, иногда выделяя шумовые признаки в значимые, а значимые - в шумовые.
* рекурсивное сокращение признаков показывает хорошие результаты, правильно правильно выделяя 9 самых значимых признаков.
* хотя линейная регрессия и рекурсивное сокращение признаков правильно выделяют значимые признаки, саму значимость они оценивают по-разному.
* среднее значение позволяет c хорошей уверенностью определять истинные значимые признаки.
Итого. Если необходимо просто ранжирование, достаточно взять модель RFE, однако, если необходимо анализировать признаки по коэффициентам, имея меру (коэффициенты), то брать нужно линейную регрессию. Случайное лассо лучше не надо.
Пример консольных результатов:
>Linear regression
>[('x1', 1.0), ('x4', 0.69), ('x2', 0.61), ('x11', 0.59), ('x3', 0.51), ('x13', 0.48), ('x5', 0.19), ('x12', 0.19), ('x14', 0.12), ('x8', 0.03), ('x6', 0.02), ('x10', 0.01), ('x7', 0.0), ('x9', 0.0)]
>Random lasso
>[('x5', 1.0), ('x4', 0.76), ('x2', 0.74), ('x1', 0.72), ('x14', 0.44), ('x12', 0.32), ('x11', 0.28), ('x8', 0.22), ('x6', 0.17), ('x3', 0.08), ('x7', 0.02), ('x13', 0.02), ('x9', 0.01), ('x10', 0.0)]
>RFE
>[('x4', 1.0), ('x1', 0.92), ('x11', 0.85), ('x2', 0.77), ('x3', 0.69), ('x13', 0.62), ('x5', 0.54), ('x12', 0.46), ('x14', 0.38), ('x8', 0.31), ('x6', 0.23), ('x10', 0.15), ('x7', 0.08), ('x9', 0.0)]
>Mean
>[('x1', 0.88), ('x4', 0.82), ('x2', 0.71), ('x5', 0.58), ('x11', 0.57), ('x3', 0.43), ('x13', 0.37), ('x12', 0.32), ('x14', 0.31), ('x8', 0.19), ('x6', 0.14), ('x10', 0.05), ('x7', 0.03), ('x9', 0.0)]
По данным результатам можно заключить, что наиболее влиятельные признаки по убыванию: x1, x4, x2, x5.