Выделить матрицу признаков и целевую переменную из загруженных данных
Верно ли я нахожу матрицу признаков и целевую переменную из датасета?
Вот, что у меня получается:
import numpy as np
import pandas as pd
data = pd.read_csv('data.csv')
from sklearn.linear_model import LinearRegression
linear_regression = LinearRegression()
model = linear_regression.fit(data, data.target)
weight_data = pd.DataFrame(list(zip(data[0:100], model.coef_)))
weight_data.columns = ['f', 'target']
print(weight_data)
f target
0 f1 -4.823780e-15
1 f2 -5.995204e-15
2 f3 -1.371125e-14
3 f4 2.832478e-15
4 f5 3.999419e-15
.. ... ...
96 f97 2.167819e-14
97 f98 -8.83538@e-15
98 f99 1.346628e-14
99 f160 -1.384255e-14
100 target 9.999620e-01
[101 rows x 2 columns]
Ответы (2 шт):
Верно ли я нахожу матрицу признаков и целевую переменную из датасета
Нет, у вас логическая ошибка - в обучающей выборке присутствует целевая переменная. Вследствие чего модель может "идеально" подобрать веса коэффициент ов - 1.0 для столбца с целевой переменной и нули для всех остальных столбцов. В итоге мы получим 100% точность для обучающей выборки.
Разделите обучающую выборку на входную матрицу и целевую переменную. Кроме этого следует разделить всю выборку на две части - на обучающий и тестовый наборы. Модель при обучении не должна видеть данных из тестового набора данных. Иначе вы не сможете адекватно оценить точность модели для новых данных, т.е. для тех, которые модель не видела во время обучения:
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
data.drop(columns="target"),
data["target"],
test_size=0.2,
random_state=42)
Я сразу приведу более правильный код, а потом объясню, что и как:
import numpy as np
import seaborn as sns
from sklearn.preprocessing import MinMaxScaler
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt
data = pd.read_csv('data.csv')
scaler = MinMaxScaler()
linear_regression = LinearRegression()
X = data.drop(columns='target')
X = scaler.fit_transform(X)
y = data.target
model = linear_regression.fit(X, y)
weight_data = pd.DataFrame(zip(data.columns, model.coef_))
weight_data.columns = ['f', 'coeff']
weight_data = weight_data[weight_data.coeff.abs() > 0.01]
weight_data = weight_data.sort_values('coeff', ascending=False)
print(weight_data)
sns.barplot(x='coeff', y='f', data=weight_data);
plt.title('Коэффициенты/важность признаков');
Вывод:
f coeff
53 f54 489.356736
83 f84 370.082114
32 f33 367.383082
22 f23 285.648451
7 f8 239.417430
68 f69 179.345713
37 f38 112.168497
28 f29 107.357792
91 f92 77.969137
46 f47 12.506650
Итак, что тут важно:
- из матрицы признаков нужно убирать
target, если вы его оставите, то понятно, что лучше всегоtargetкоррелирует сам с собой, а остальное так - случайные флуктуации, что у вас и получилось - коэффициент уtargetполучился0.9999..., т.е. почти1, регрессия предсказалаtargetпо нему же самому - если вы хотите посчитать реальную важность признаков, то данные нужно масштабировать, иначе коэффициенты регрессии вам покажут не совсем то, что вы, возможно ожидаете, например, если у вас есть всего два признака и один признак имеет среднее
1000, а другой0.001и при этом оба одинаково важны для вычисленияtarget, то у первого будет коэффициент0.0005, а у второго500, и как вы эти два числа будете сравнивать/воспринимать? а вот после масштабирования в один диапазон значений, например[0, 1]оба признака будут иметь коэффициент0.5и всё будет понятно - это два одинаково важных признака
На ваших данных у меня получилось c LinearRegression, что есть 10 более-менее важных признаков, а остальные имеют очень малую значимость, это просто шум.
И это я ещё не использовал регуляризацию и кросс-валидацию. А надо бы.
P.S. С ElasticNetCV вообще другие фичи получаются важными и как-то по-другому картина выглядит, в общем, похоже, данные не так просты, и их ещё нужно изучать. Но основные ошибки вам в общем уже указали. Дальше нужно делать кросс-валидацию, смотреть насколько точно модель предсказывает, пробовать другие модели, делать визуализацию как признаков, так и их корреляции... В общем, это работа творческая.
