使用一位有效编码进行逻辑回归

7

我有一个数据框(data),它的头部如下所示:

          status      datetime    country    amount    city  
601766  received  1.453916e+09    France       4.5     Paris
669244  received  1.454109e+09    Italy        6.9     Naples

我希望能够根据日期时间,国家,金额城市来预测状态

由于状态,国家,城市都是字符串,所以我对它们进行了独热编码:

one_hot = pd.get_dummies(data['country'])
data = data.drop(item, axis=1) # Drop the column as it is now one_hot_encoded
data = data.join(one_hot)

接下来,我创建了一个简单的LinearRegression模型并拟合了我的数据:

y_data = data['status']
classifier = LinearRegression(n_jobs = -1)
X_train, X_test, y_train, y_test = train_test_split(data, y_data, test_size=0.2)
columns = X_train.columns.tolist()
classifier.fit(X_train[columns], y_train)

但我收到了以下错误信息:
“无法将字符串转换为浮点数:'received'”
我有一种错过了什么的感觉,希望能得到一些如何继续的建议。感谢您读到这里!

尝试使用y_data = data['status'] == 'received',我相信LinearRegression在这里期望一个数值/布尔变量。 - m-dz
3个回答

5
考虑以下方法:

首先,让我们对所有非数字列进行一次独热编码:

In [220]: from sklearn.preprocessing import LabelEncoder

In [221]: x = df.select_dtypes(exclude=['number']) \
                .apply(LabelEncoder().fit_transform) \
                .join(df.select_dtypes(include=['number']))

In [228]: x
Out[228]:
        status  country  city      datetime  amount
601766       0        0     1  1.453916e+09     4.5
669244       0        1     0  1.454109e+09     6.9

现在我们可以使用LinearRegression分类器:

In [230]: classifier.fit(x.drop('status',1), x['status'])
Out[230]: LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)

非常感谢!您介意解释一下为什么我的初始解决方案没有成功吗? - Mornor
1
@Mornor,欢迎您。我猜X_train[columns]和/或y_data有一些string列,因此出现了could not convert string to float: 'received'的错误提示。 - MaxU - stand with Ukraine
6
我希望指出你的答案部分正确。确实,它只对字符串进行了LabelEncode,而没有进行one-hot编码。这将导致错误的结果,因为有些字符串的价值比其他字符串“更高”。 - Mornor
2
如果有人想知道"Mornor"是什么意思,那是因为标签编码将会变成数字值。例如:法国=0、意大利=1等。这意味着一些城市比其他城市更有价值。使用独热编码后,每个城市都具有相同的值:例如:法国=[1,0]、意大利=[0,1]。此外,不要忘记虚拟变量陷阱https://www.algosome.com/articles/dummy-variable-trap-regression.html。 - Juan Acevedo

2
备选方案(因为您应该真正避免使用LabelEncoder在特征上)。 ColumnTransformerOneHotEncoder可以对数据框中的特征进行一位有效编码:
ct = ColumnTransformer(
    transformers=[
        ("ohe", OneHotEncoder(sparse_output=False), ["country", "city"]),
    ],
    remainder="passthrough",
).set_output(transform="pandas")

print(ct.fit_transform(X))

   ohe__country_France  ohe__country_Italy  ohe__city_Naples  ohe__city_Paris  remainder__datetime  remainder__amount
0                  1.0                 0.0               0.0              1.0               1.4539                4.5
1                  0.0                 1.0               1.0              0.0               1.4541                6.9
2                  1.0                 0.0               0.0              1.0               1.4561                5.0

完整的管道,包含逻辑回归:
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
from sklearn.pipeline import make_pipeline
from sklearn.linear_model import LogisticRegression

raw_data = pd.DataFrame([["received", 1.4539, "France", 4.5, "Paris"], ["received", 1.4541, "Italy", 6.9, "Naples"], ["not-received", 1.4561, "France", 5.0, "Paris"]], columns=["status", "datetime", "country", "amount", "city"])

# X features include all variables except 'status', y label is 'status':
X = raw_data.drop(["status"], axis=1)
y = raw_data["status"]

# Create a pipeline with OHE for "country" and "city", then fits Logistic Regression:
pipe = make_pipeline(
    ColumnTransformer(
        transformers=[
            ("one-hot-encode", OneHotEncoder(), ["country", "city"]),
        ],
        remainder="passthrough",
    ),
    LogisticRegression(),
)

pipe.fit(X, y)

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接