antonov_dmitry_lab_2 #22

Merged
Alexey merged 2 commits from antonov_dmitry_lab_2 into main 2023-10-11 20:10:31 +04:00
4 changed files with 4573 additions and 183 deletions

View File

@ -2,8 +2,7 @@
Ранжирование признаков
Используя код из (пункт «Решение задачи ранжирования признаков», стр. 205),
выполните ранжирование признаков с помощью указанных по варианту моделей.
Выполните ранжирование признаков с помощью указанных по варианту моделей.
Отобразите получившиеся значения\оценки каждого признака каждым методом\моделью и среднюю оценку.
Проведите анализ получившихся результатов.
Какие четыре признака оказались самыми важными по среднему значению?
@ -11,94 +10,75 @@
# Вариант 3
Данные: make_classification (n_samples=500, n_features=2,
n_redundant=0, n_informative=2, random_state=rs, n_clusters_per_class=1)
Линейная регрессия (LinearRegression) , Сокращение признаков
Случайными деревьями (Random Forest Regressor), Линейная корреляция
(f_regression)
Я использовал датасет Predict students' dropout and academic success
https://www.kaggle.com/datasets/thedevastator/higher-education-predictors-of-student-retention
Он используется мной по заданию на курсовую работу
# Запуск
Выполнением скрипта файла (вывод в консоль + рисует графики).
Выполнением скрипта файла (вывод в консоль).
# Модели:
1. Линейная регрессия
1. Полиномиальная регрессия (со степенью 3)
1. Гребневая полиномиальная регрессия (со степенью 3, alpha = 1.0)
1. Линейная регрессия (LinearRegression)
1. Сокращение признаков cлучайными деревьями (Random Forest Regressor)
1. Линейная корреляция (f_regression)
# Графики
# Пояснения
<div>
Качество каждой модели может быть оценено на основе среднеквадратичной ошибки (MSE).
Более низкая MSE указывает на лучшее соответствие данным.
Однако выбор модели зависит от набора данных и лежащей в основе взаимосвязи между объектами и целевой переменной.
Выбор наиболее подходящего метода ранжирования объектов зависит от специфики набора данных и требований
к модели.
Линейная регрессия: Линейная регрессия предполагает линейную зависимость между признаками и целевой переменной.
Это хорошо работает, когда взаимосвязь линейна, а шум в наборе данных минимален.
Лучше всего сработала на наборе лун. Хуже всего на кругах.
На линейном наборе показала себя на равне с остальными.
Линейная регрессия - это простой и понятный метод, который может быть использован для предсказания значений.
Он хорошо работает, если зависимость между переменными является линейной.
Однако, если данные содержат сложные нелинейные зависимости, линейная регрессия может
оказаться не очень эффективной.
Полиномиальная и гребневая показали примерно одинаково на всех наборах.
Уменьшение признаков с помощью случайных деревьев (Random Forest Regressor) - это мощный метод,
который способен обрабатывать сложные взаимосвязи в данных, даже если они нелинейные.
Он основан на идее создания ансамбля деревьев решений, каждое из которых дает свой голос за
наиболее подходящий ответ. Случайные леса обычно дают хорошие результаты и являются устойчивыми
к переобучению.
Полиномиальная регрессия (степень=3):
Полиномиальная регрессия обеспечивает более гибкую подгонку за счет полинома более высокого порядка(кубическая кривая).
Она может выявить более сложные взаимосвязи между объектами и целевой переменной.
Она может сработать лучше, чем линейная регрессия, если истинная взаимосвязь нелинейна.
Гребневая регрессия (степень= 3, альфа=1,0):
В случае полиномиальной регрессии с регуляризацией (альфа=1,0) модель добавляет коэффициент регуляризации
для управления сложностью обучения. Регуляризация помогает предотвратить переобучение, когда набор
данных содержит шум или когда он ограничен.
Линейная корреляция или f_regression - это статистический метод, который используется для измерения
степени связи между двумя переменными. Он может помочь определить, есть ли вообще связь между переменными,
но не подходит для ранжирования объектов.
</div>
<p>
<div>Набор лун (moon_dataset)</div>
<img src="screens/myplot1.png" width="650" title="датасет 1">
</p>
<p>
<div>Графики регрессии</div>
<img src="screens/myplot2.png" width="450" title="линейная модель">
<img src="screens/myplot3.png" width="450" title="полиномиальная модель">
<img src="screens/myplot4.png" width="450" title="гребневая модель">
<div>
Линейная MSE: 0.0936
Полиномиальная (degree=3) MSE: 0.0674
Гребневая (degree=3, alpha=1.0) MSE: 0.0682
</div>
</p>
### 4 самых важных признака в среднем:
1. Признак: Curricular units 2nd sem (approved), Оценка: 0.8428
2. Признак: Tuition fees up to date, Оценка: 0.4797
3. Признак: Curricular units 1st sem (approved), Оценка: 0.2986
4. Признак: Curricular units 2nd sem (grade), Оценка: 0.2778
<p>
<div>Набор кругов (circles_dataset)</div>
<img src="screens/myplot5.png" width="650" title="датасет 2">
</p>
<p>
<div>Графики регрессии</div>
<img src="screens/myplot6.png" width="450" title="линейная модель">
<img src="screens/myplot7.png" width="450" title="полиномиальная модель">
<img src="screens/myplot8.png" width="450" title="гребневая модель">
<div>
Линейная MSE: 0.2684
Полиномиальная (degree=3) MSE: 0.1341
Гребневая (degree=3, alpha=1.0) MSE: 0.1312
</div>
</p>
### 4 самых важных для lr_scores линейной регрессии:
1. 0.3917 'Tuition fees up to date'
2. 0.2791 'International'
3. 0.2075 'Curricular units 2nd sem (approved)'
4. 0.1481 'Debtor'
<p>
<div>Набор линейный (linearly_dataset)</div>
<img src="screens/myplot9.png" width="650" title="датасет 3">
</p>
<p>
<div>Графики регрессии</div>
<img src="screens/myplot10.png" width="450" title="линейная модель">
<img src="screens/myplot11.png" width="450" title="полиномиальная модель">
<img src="screens/myplot12.png" width="450" title="гребневая модель">
<div>
Линейная MSE: 0.1101
Полиномиальная (degree=3) MSE: 0.1045
Гребневая (degree=3, alpha=1.0) MSE: 0.1078
</div>
</p>
### 4 самых важных для rf_scores рандом forests:
1. 0.4928 'Curricular units 2nd sem (approved)'
2. 0.061 'Tuition fees up to date'
3. 0.0458 'Curricular units 2nd sem (grade)'
4. 0.0308 'Curricular units 1st sem (grade)'
### 4 самых важных для f_regression:
1. 2822.104 'Curricular units 2nd sem (approved)'
2. 2093.3315 'Curricular units 2nd sem (grade)'
3. 1719.4229 'Curricular units 1st sem (approved)'
4. 1361.6144 'Curricular units 1st sem (grade)'
### Объяснение:
<div>
Итоговая модель подбирается учитывая зависимость в данных,
как правило полиномиальная регрессия справляется лучше, а коэф регуляризации в гребневой регрессии помогает избежать
переобучения.
В общем, выбор между линейной регрессией и случайными лесами зависит от характеристик данных.
Если данные имеют линейную зависимость, то линейная регрессия будет предпочтительнее.
Если данные содержат сложные, возможно нелинейные взаимосвязи, то Random Forest может быть лучшим выбором.
В любом случае, важно провести предварительное исследование данных и тестирование различных моделей,
чтобы выбрать наиболее подходящую.
</div>

File diff suppressed because it is too large Load Diff

View File

@ -1,50 +0,0 @@
import numpy as np
Review

По идее у тебя не должно быть того, что ты что-то удаляешь. Почему удаляется файл?
Это +1 к тому, почему у тебя конфликты

По идее у тебя не должно быть того, что ты что-то удаляешь. Почему удаляется файл? Это +1 к тому, почему у тебя конфликты
from sklearn.datasets import make_regression
from sklearn.feature_selection import RFECV, f_regression
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor
# генерируем исходные данные: 100 строк-наблюдений и 10 столбцов-признаков
X, y = make_regression(n_samples=100, n_features=10, random_state=42)
# линейная модель
linear_reg = LinearRegression()
linear_reg.fit(X, y)
linear_ranking_lr = np.abs(linear_reg.coef_)
# cокращение признаков cлучайными деревьями (Random Forest Regressor)
rf_reg = RandomForestRegressor()
rfecv = RFECV(estimator=rf_reg)
rfecv.fit(X, y)
rfecv_ranking = rfecv.ranking_
# линейная корреляция (f_regression)
f_reg, _ = f_regression(X, y)
linear_corr_ranking = f_reg
# ранжирование признаков и вычисление средней оценки
all_rankings = np.vstack((linear_ranking_lr, rfecv_ranking, linear_corr_ranking))
average_ranking = np.mean(all_rankings, axis=0)
# средние показатели четырех наиболее важных характеристик
most_important_indices = np.argsort(average_ranking)[-4:]
# результаты
print("ранги линейной модели:")
print(linear_ranking_lr)
print("")
print("ранги после сокращения признаков Random Forest:")
print(rfecv_ranking)
print("")
print("ранги линейнейной корреляции (f_regression):")
print(linear_corr_ranking)
print("")
print("ранги по средней оценке:")
print(average_ranking)
print("")
print("4 выделенных главных признака:")
print(most_important_indices)

View File

@ -1,71 +1,106 @@
from operator import itemgetter
from sklearn.feature_selection import f_regression
from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.preprocessing import MinMaxScaler
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor
from sklearn.feature_selection import f_regression
from sklearn.preprocessing import MinMaxScaler
# генерируем исходные данные: 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))
# загрузка dataset
data = pd.read_csv('dataset.csv')
# линейная модель
# разделение dataset на тренировочную и тестовую выборки
X = data.drop(['Target'], axis=1)
y = data['Target']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Тренировка моделей
# Линейная регрессия
lr = LinearRegression()
lr.fit(X, Y)
# гребневая модель
ridge = Ridge(alpha=7)
ridge.fit(X, Y)
# Лассо
lasso = Lasso(alpha=.05)
lasso.fit(X, Y)
lr.fit(X_train, y_train)
names = ["x%s" % i for i in range(1, 15)]
# Сокращение признаков случайными деревьями с помощью Random Forest Regressor
rf = RandomForestRegressor()
rf.fit(X_train, y_train)
# Ранжирование признаков использую каждую модель/метод
# Получение абсолютных значений коэффициентов в качестве оценок важности признаков
lr_scores = abs(lr.coef_)
# Получение оценок важности объектов из модели Random Forest Regressor
rf_scores = rf.feature_importances_
# Отображение итоговых оценок по каждой колонке
feature_names = X.columns.tolist()
# показать оценки рангов по модели линейной регрессии
print("оценки линейной регрессии:")
for feature, score in zip(feature_names, lr_scores):
print(f"{feature}: {round(score, 4)}")
# оценки метода рандомных лесов
print("\nоценки Random Forest:")
for feature, score in zip(feature_names, rf_scores):
print(f"{feature}: {round(score, 4)}")
# вычисление значений оценки для f_regression
f_scores, p_values = f_regression(X, y)
# оценки f_regression
print("\nоценки f_regression:")
for feature, score in zip(feature_names, f_scores):
print(f"{feature}: {round(score, 4)}")
# использую MinMaxScaler для точных средних значений рангов
scaler = MinMaxScaler()
lr_scores_scaled = scaler.fit_transform(lr_scores.reshape(-1, 1)).flatten()
rf_scores_scaled = scaler.fit_transform(rf_scores.reshape(-1, 1)).flatten()
f_scores_scaled = scaler.fit_transform(f_scores.reshape(-1, 1)).flatten()
# вычисление средних оценок для каждого признака
average_scores = {}
for feature in feature_names:
average_scores[feature] = (lr_scores_scaled[feature_names.index(feature)] +
rf_scores_scaled[feature_names.index(feature)] +
f_scores_scaled[feature_names.index(feature)]) / 3
# получаем среднюю оценку признаков
sorted_features = sorted(average_scores.items(), key=lambda x: x[1], reverse=True)
# получаем самых важных признака
top_4_features = sorted_features[:4]
# отображаем 4 самые важные
print("\n4 самых важных признака в среднем:")
for feature, score in top_4_features:
print(f"Признак: {feature}, Оценка: {round(score, 4)}")
def rank_to_dict(ranks, names):
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))
# отображаем самых важных признака для каждого метода/модели
top_lr_indices = np.argsort(lr_scores)[-4:][::-1]
top_rf_indices = np.argsort(rf_scores)[-4:][::-1]
top_f_indices = np.argsort(f_scores)[-4:][::-1]
top_lr_features = [feature_names[i] for i in top_lr_indices]
top_rf_features = [feature_names[i] for i in top_rf_indices]
top_f_features = [feature_names[i] for i in top_f_indices]
ranks = {}
ranks["Linear reg"] = rank_to_dict(lr.coef_, names)
ranks["Ridge"] = rank_to_dict(ridge.coef_, names)
ranks["Lasso"] = rank_to_dict(lasso.coef_, names)
top_lr_features_score = [lr_scores[i] for i in top_lr_indices]
top_rf_features_score = [rf_scores[i] for i in top_rf_indices]
top_f_features_score = [f_scores[i] for i in top_f_indices]
# Создаем пустой список для данных
mean = {}
# «Бежим» по списку ranks
for key, value in ranks.items():
# «Пробегаемся» по списку значений ranks, которые являются парой имя:оценка
for item in value.items():
# имя будет ключом для нашего mean
# если элемента с текущим ключем в mean нет - добавляем
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(mean.items(), key=itemgetter(1), reverse=True)
print("MEAN")
print(mean)
print("\n4 самых важных для lr_scores:")
print(top_lr_features)
for i in top_lr_features_score:
print(round(i, 4))
for key, value in ranks.items():
ranks[key] = sorted(value.items(), key=itemgetter(1), reverse=True)
for key, value in ranks.items():
print(key)
print(value)
print("\n4 самых важных для rf_scores:")
print(top_rf_features)
for i in top_rf_features_score:
print(round(i, 4))
f, pval = f_regression(X, Y, center=True)
print("\n4 самых важных для f_scores:")
print(top_f_features)
for i in top_f_features_score:
print(round(i, 4))