如何使用 Python 进行线性回归并使用一种热编码进行 Scikit 学习?
How to do linear regression using Python and Scikit learn using one hot encoding?
我正在尝试将线性回归与 python 和 scikitlearn 结合使用来回答问题 "can user session lengths be predicted given user demographic information?"
我正在使用线性回归,因为用户会话长度以毫秒为单位,这是连续的。我对我所有的分类变量进行了热编码,包括性别、国家和年龄范围。
我不确定如何考虑我的一种热编码,或者我是否需要考虑。
输入数据:
我试着在这里阅读:http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html
我了解输入是我的主要内容是是否计算拟合截距、归一化、复制 x(所有布尔值),然后是 n 个作业。
我不确定在决定这些输入时要考虑哪些因素。我还担心我对变量的一种热编码是否会产生影响。
你可以这样做:
from sklearn.preprocessing import OneHotEncoder
from sklearn.linear_model import LinearRegression
# X is a numpy array with your features
# y is the label array
enc = OneHotEncoder(sparse=False)
X_transform = enc.fit_transform(X)
# apply your linear regression as you want
model = LinearRegression()
model.fit(X_transform, y)
print("Mean squared error: %.2f" % np.mean((model.predict(X_transform) - y) ** 2))
请注意,这个例子是我用同一个数据集训练和测试的!这可能会导致您的模型过度拟合。您应该避免拆分数据或进行交叉验证。
我只是想用 sklearn 拟合线性回归,我将其用作其他非线性方法的基准,例如 MLPRegressor,还有线性回归的变体,例如 Ridge、Lasso 和 ElasticNet(请参阅此处了解本组介绍:http://scikit-learn.org/stable/modules/linear_model.html).
按照@silviomoreto(适用于所有其他模型)描述的相同方式对我来说实际上导致了一个错误的模型(非常高的错误)。这很可能是由于所谓的虚拟变量陷阱,当您为分类变量的每个类别包含一个虚拟变量时,由于变量中的多重共线性而发生这种情况——这正是 OneHotEncoder 所做的!另请参阅以下关于 statsexchange 的讨论:https://stats.stackexchange.com/questions/224051/one-hot-vs-dummy-encoding-in-scikit-learn.
为了避免这种情况,我写了一个简单的包装器,它排除了一个变量,然后作为默认值。
class DummyEncoder(BaseEstimator, TransformerMixin):
def __init__(self, n_values='auto'):
self.n_values = n_values
def transform(self, X):
ohe = OneHotEncoder(sparse=False, n_values=self.n_values)
return ohe.fit_transform(X)[:,:-1]
def fit(self, X, y=None, **fit_params):
return self
因此,在@silviomoreto 的代码基础上,您将更改第 6 行:
enc = DummyEncoder()
这解决了我的问题。请注意,对于所有其他模型,例如 Ridge、Lasso 和 ANN,OneHotEncoder 工作得很好(并且更好)。
我选择这种方式,因为我想将它包含在我的功能管道中。但是您似乎已经对数据进行了编码。在这里,您必须为每个类别删除一列(例如,male/female 只包括一列)。因此,例如,如果您使用 pandas.get_dummies(...),则可以使用参数 drop_first=True.
最后但同样重要的是,如果你真的需要在 Python 中更深入地研究线性回归,而不是仅仅将其用作基准,我会推荐 statsmodels 而不是 scikit-learn (https://pypi.python.org/pypi/statsmodels ), 因为它提供了更好的模型统计信息,例如每个变量的 p 值等
如何为 sklearn LinearRegression 准备数据
OneHotEncode 应仅用于预期的列:具有分类变量或字符串的列,或本质上是级别而不是数字的整数。
不要 将 OneHotEncode 应用于整个数据集,包括数值变量或布尔值。
要为 sklearn LinearRegression 准备数据,应分别处理数值和分类。
- 数值列:如果您的模型包含交互项或多项式项,则进行标准化
- 分类列:通过 sklearn 或 pd.get_dummies 应用 OneHot。 pd.get_dummies 更灵活,而 OneHotEncode 在与 sklearn API.
一起工作时更一致
掉落='first'
从 0.22 版开始,sklearn 中的 OneHotEncoder
有 drop
选项。例如 OneHotEncoder(drop='first').fit(X)
,类似于
pd.get_dummies(drop_first=True)
.
使用正则化线性回归
如果使用 Lasso 等正则化线性回归,多重共线性变量将受到惩罚并收缩。
p 值统计的局限性
OLS 中的 p 值仅在 OLS 假设或多或少为真时才有效。虽然有一些方法可以处理 p 值不可信的情况,但一种可能的解决方案是使用交叉验证或留一法来获得对模型的信心。
我正在尝试将线性回归与 python 和 scikitlearn 结合使用来回答问题 "can user session lengths be predicted given user demographic information?"
我正在使用线性回归,因为用户会话长度以毫秒为单位,这是连续的。我对我所有的分类变量进行了热编码,包括性别、国家和年龄范围。
我不确定如何考虑我的一种热编码,或者我是否需要考虑。
输入数据:
我试着在这里阅读:http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html
我了解输入是我的主要内容是是否计算拟合截距、归一化、复制 x(所有布尔值),然后是 n 个作业。
我不确定在决定这些输入时要考虑哪些因素。我还担心我对变量的一种热编码是否会产生影响。
你可以这样做:
from sklearn.preprocessing import OneHotEncoder
from sklearn.linear_model import LinearRegression
# X is a numpy array with your features
# y is the label array
enc = OneHotEncoder(sparse=False)
X_transform = enc.fit_transform(X)
# apply your linear regression as you want
model = LinearRegression()
model.fit(X_transform, y)
print("Mean squared error: %.2f" % np.mean((model.predict(X_transform) - y) ** 2))
请注意,这个例子是我用同一个数据集训练和测试的!这可能会导致您的模型过度拟合。您应该避免拆分数据或进行交叉验证。
我只是想用 sklearn 拟合线性回归,我将其用作其他非线性方法的基准,例如 MLPRegressor,还有线性回归的变体,例如 Ridge、Lasso 和 ElasticNet(请参阅此处了解本组介绍:http://scikit-learn.org/stable/modules/linear_model.html).
按照@silviomoreto(适用于所有其他模型)描述的相同方式对我来说实际上导致了一个错误的模型(非常高的错误)。这很可能是由于所谓的虚拟变量陷阱,当您为分类变量的每个类别包含一个虚拟变量时,由于变量中的多重共线性而发生这种情况——这正是 OneHotEncoder 所做的!另请参阅以下关于 statsexchange 的讨论:https://stats.stackexchange.com/questions/224051/one-hot-vs-dummy-encoding-in-scikit-learn.
为了避免这种情况,我写了一个简单的包装器,它排除了一个变量,然后作为默认值。
class DummyEncoder(BaseEstimator, TransformerMixin):
def __init__(self, n_values='auto'):
self.n_values = n_values
def transform(self, X):
ohe = OneHotEncoder(sparse=False, n_values=self.n_values)
return ohe.fit_transform(X)[:,:-1]
def fit(self, X, y=None, **fit_params):
return self
因此,在@silviomoreto 的代码基础上,您将更改第 6 行:
enc = DummyEncoder()
这解决了我的问题。请注意,对于所有其他模型,例如 Ridge、Lasso 和 ANN,OneHotEncoder 工作得很好(并且更好)。
我选择这种方式,因为我想将它包含在我的功能管道中。但是您似乎已经对数据进行了编码。在这里,您必须为每个类别删除一列(例如,male/female 只包括一列)。因此,例如,如果您使用 pandas.get_dummies(...),则可以使用参数 drop_first=True.
最后但同样重要的是,如果你真的需要在 Python 中更深入地研究线性回归,而不是仅仅将其用作基准,我会推荐 statsmodels 而不是 scikit-learn (https://pypi.python.org/pypi/statsmodels ), 因为它提供了更好的模型统计信息,例如每个变量的 p 值等
如何为 sklearn LinearRegression 准备数据
OneHotEncode 应仅用于预期的列:具有分类变量或字符串的列,或本质上是级别而不是数字的整数。
不要 将 OneHotEncode 应用于整个数据集,包括数值变量或布尔值。
要为 sklearn LinearRegression 准备数据,应分别处理数值和分类。
- 数值列:如果您的模型包含交互项或多项式项,则进行标准化
- 分类列:通过 sklearn 或 pd.get_dummies 应用 OneHot。 pd.get_dummies 更灵活,而 OneHotEncode 在与 sklearn API. 一起工作时更一致
掉落='first'
从 0.22 版开始,sklearn 中的 OneHotEncoder
有 drop
选项。例如 OneHotEncoder(drop='first').fit(X)
,类似于
pd.get_dummies(drop_first=True)
.
使用正则化线性回归
如果使用 Lasso 等正则化线性回归,多重共线性变量将受到惩罚并收缩。
p 值统计的局限性
OLS 中的 p 值仅在 OLS 假设或多或少为真时才有效。虽然有一些方法可以处理 p 值不可信的情况,但一种可能的解决方案是使用交叉验证或留一法来获得对模型的信心。