我使用 scikit 线性回归,如果我改变特征的顺序,coef 仍然以相同的顺序打印,因此我想知道特征与 coeff 的映射。
#training the model
model_1_features = ['sqft_living', 'bathrooms', 'bedrooms', 'lat', 'long']
model_2_features = model_1_features + ['bed_bath_rooms']
model_3_features = model_2_features + ['bedrooms_squared', 'log_sqft_living', 'lat_plus_long']
model_1 = linear_model.LinearRegression()
model_1.fit(train_data[model_1_features], train_data['price'])
model_2 = linear_model.LinearRegression()
model_2.fit(train_data[model_2_features], train_data['price'])
model_3 = linear_model.LinearRegression()
model_3.fit(train_data[model_3_features], train_data['price'])
# extracting the coef
print model_1.coef_
print model_2.coef_
print model_3.coef_
诀窍在于,在训练模型之后,您就知道系数的顺序:
model_1 = linear_model.LinearRegression()
model_1.fit(train_data[model_1_features], train_data['price'])
print(list(zip(model_1.coef_, model_1_features)))
这将打印系数和正确的特征。 (使用 pandas DataFrame 进行测试)
如果您想稍后重用这些系数,也可以将它们放入字典中:
coef_dict = {}
for coef, feat in zip(model_1.coef_,model_1_features):
coef_dict[feat] = coef
(您可以通过训练两个具有相同特征的模型来亲自测试它,但正如您所说,打乱了特征的顺序。)
import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
regressor = LinearRegression()
regressor.fit(X_train, y_train)
coef_table = pd.DataFrame(list(X_train.columns)).copy()
coef_table.insert(len(coef_table.columns),"Coefs",regressor.coef_.transpose())
@Robin 发布了一个很好的答案,但对我来说,我必须对其进行一项调整才能按照我想要的方式工作,它是指我想要的“coef_”np.array 的维度,即修改为这个: model_1.coef_[0,:],如下:
coef_dict = {}
for coef, feat in zip(model_1.coef_[0,:],model_1_features):
coef_dict[feat] = coef
然后按照我的想象创建了字典,其中包含 {'feature_name' :coefficient_value} 对。
从
scikit-learn
版本 1.0
开始,LinearRegression
估计器具有 feature_names_in_
属性。来自文档:
feature_names_in_ : ndarray of shape (
,)n_features_in_
拟合过程中看到的特征的名称。仅当 X 的特征名称均为字符串时才定义。
1.0版本新增功能。
假设您正在拟合
pandas.DataFrame
(train_data
),您的估算器(model_1
、model_2
和 model_3
)将具有该属性。您可以使用前面答案中列出的任何方法来排列系数,但我赞成这个:
coef_series = pd.Series(
data=model_1.coef_,
index=model_1.feature_names_in_
)
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
# for repeatability
np.random.seed(0)
# random data
Xy = pd.DataFrame(
data=np.random.random((10, 3)),
columns=["x0", "x1", "y"]
)
# separate X and y
X = Xy.drop(columns="y")
y = Xy.y
# initialize estimator
lr = LinearRegression()
# fit to pandas.DataFrame
lr.fit(X, y)
# get coeficients and their respective feature names
coef_series = pd.Series(
data=lr.coef_,
index=lr.feature_names_in_
)
print(coef_series)
x0 0.230524
x1 -0.275611
dtype: float64
这是我在 Jupyter 中用于漂亮打印系数的方法。我不确定我是否明白为什么顺序是一个问题 - 据我所知,系数的顺序应该与您提供的输入数据的顺序相匹配。
请注意,第一行假设您有一个名为 df 的 Pandas 数据框,您最初将数据存储在其中,然后将其转换为 numpy 数组进行回归:
fieldList = np.array(list(df)).reshape(-1,1)
coeffs = np.reshape(np.round(clf.coef_,5),(-1,1))
coeffs=np.concatenate((fieldList,coeffs),axis=1)
print(pd.DataFrame(coeffs,columns=['Field','Coeff']))
借鉴 Robin,但简化语法:
coef_dict = dict(zip(model_1_features, model_1.coef_))
关于 zip 的重要说明:zip 假设其输入的长度相等,因此确认特征和系数的长度匹配尤其重要(在更复杂的模型中可能并非如此)。如果一个输入比另一个输入长,则较长输入的额外索引位置中的值将被截断。请注意以下示例中缺少的 7:
In [1]: [i for i in zip([1, 2, 3], [4, 5, 6, 7])]
Out[1]: [(1, 4), (2, 5), (3, 6)]
pd.DataFrame(data=regression.coef_, index=X_train.columns)
所有这些答案都很棒,但对我个人有用的是这个,因为我需要的功能名称是我的 train_date 数据框的列:
pd.DataFrame(data=model_1.coef_,columns=train_data.columns)
训练模型后,系数值立即存储在变量
model.coef_[0]
中。我们可以迭代列名称并将列名称及其系数值存储在字典中。
model.fit(X_train,y)
# assuming all the columns except last one is used in training
columns = data.iloc[:,-1].columns
coef_dict = {}
for i in range(0,len(columns)):
coef_dict[columns[i]] = model.coef_[0][i]
希望这有帮助!
从 Ian 的答案中添加,如果您还想将截距添加到命名系数列表中,并将其转换为数据帧:
lr = LinearRegression()
lr.fit(X=X, y=y)
res = pd.DataFrame(
{'feature' : np.insert(lr.feature_names_in_, 0, 'intercept'),
'coef' : np.insert(lr.coef_, 0, lr.intercept_)}
)
res
哪个返回:
feature coef
0 intercept 41.617270
1 crim -0.121389
2 zn 0.046963
3 indus 0.013468