【问题标题】:ML Classification : Encoding categorical dataML 分类:编码分类数据
【发布时间】:2020-12-21 05:27:31
【问题描述】:

我是这方面的初学者,

我有一个分类问题,我的数据如下所示:

等等……

结果列是因变量。没有任何数据是有序的。 (名称列有 36 个不同的名称。)

因为它是分类数据,我尝试了 OneHotEncoding 并得到了 ValueError: Number of features of the model must match the input

我理解并提到了这个:SO Question,它得到了修复。

还有另一个站点:Medium 使用 Pandas 的 factorize 函数来解决这个 ValueError

我的问题是:

  1. 解决此问题的正确方法是什么?我应该factorize 并申请OneHotEncoding 吗?
  2. 或者由于我的数据不是序数,我不应该使用分解?
  3. 我总是获得 100% 的准确率。是因为我做的编码吗?

我的代码如下:

培训

# -*- coding: utf-8 -*-

import numpy as np

import pandas as pd
dataset = pd.read_csv("model_data.csv")


dataset['Col1'] = pd.factorize(dataset['Col1'])[0]
dataset['Col2'] = pd.factorize(dataset['Col2'])[0]
dataset['name'] = pd.factorize(dataset['name'])[0]
dataset['ID'] = pd.factorize(dataset['ID'])[0]

X = dataset.iloc[:, 0:-1].values
y = dataset.iloc[:, -1].values

# Encoding
# Encoding categorical data
# Encoding the Independent Variable
from sklearn.compose import make_column_transformer
from sklearn.preprocessing import OneHotEncoder

ct = make_column_transformer((OneHotEncoder(sparse='False'), [0,1,2,3]),  remainder = 'passthrough')
X = ct.fit_transform(X)


# Encoding the Dependent Variable
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
y = le.fit_transform(y)
print(y)

#
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20, random_state = 0)



from sklearn.ensemble import RandomForestClassifier
classifier = RandomForestClassifier(n_estimators = 5, criterion = 'entropy', max_depth = 5, random_state = 0)
classifier.fit(X_train, y_train)

# Predicting the Test set results
y_pred = classifier.predict(X_test)

测试

test_data_set =  pd.read_csv("test_data.csv")


test_data_set['Col1'] = pd.factorize(test_data_set['Col1'])[0]
test_data_set['Col2'] = pd.factorize(test_data_set['Col2'])[0]
test_data_set['name'] = pd.factorize(test_data_set['name'])[0]
test_data_set['ID'] = pd.factorize(test_data_set['ID'])[0]

X_test_data = test_data_set.iloc[:, 0:-1].values
y_test_data = test_data_set.iloc[:, -1].values


y_test_data = le.transform(y_test_data)


classifier.fit(X_test_data, y_test_data) #fixes ValueError
y_test_pred = classifier.predict(X_test_data)

from sklearn.metrics import confusion_matrix, accuracy_score
cm = confusion_matrix(y_test_data, y_test_pred)
print(cm)
print(accuracy_score(y_test_data, y_test_pred))

编辑

  • 我的数据集中的行数是 2000。
  • accuracy_score 的结果是 1.0

混淆矩阵

[[113   0]

 [  0  30]] 

我不确定我有大约 2000 行,但我的 TP 和 TN 加起来只有 143 个计数。

【问题讨论】:

  • 你的数据集中有多少行?另外,不要在您的 test_data 上使用 fit_transform。并添加您的问题中生成的结果。
  • @AniketBote 我已经编辑了这个问题。我删除了 fit_transform
  • 另外,添加一个混淆矩阵。此外,请确保测试数据和训练数据不包含相同的样本。测试数据的长度至少应为训练集的 20%,并且应能代表所有标签。
  • 您不使用classifier.fit(X_test_data, y_test_data) 拟合您的测试数据并覆盖您之前的训练数据拟合吗?我认为你不应该对测试数据做一个fit,而只是一个predict
  • @Berger 是的,在我尝试修复 ValueError 之前,我也从未这样做过。可能是错的。

标签: python machine-learning scikit-learn


【解决方案1】:

以下是如何使用 OneHotEncoding 对数据执行二进制分类的示例。

您首先对所有具有特征的列使用 one-hot-encoding,然后将“结果”列中的 Y/N 类分解为 1/0 视图。

dataset = pd.read_csv("model_data.csv")

dataset = pd.get_dummies(dataset , columns=['Col1', 'Col2', 'name', 'ID'])
dataset.Result = pd.factorize(dataset.Result)[0]

您应该在生成的数据框中获得如下所示的结果,您可以将其用于您的训练/测试步骤。

初始数据帧:

  Col1 Col2     name    ID Result
0   AB    A     John -2500      N
1   AB    A     John -2500      N
2    A    A     John -2500      N
3    A    A    Jacob -2500      Y
4    A    A  Micheal -2500      Y
5    A   AB     John -2500      N
6    A    A  Sheldon -2500      Y
7   AB   AB  Sheldon -2500      N
8   AB   AB    Jacob -2500      Y

结果数据框:


   Result  Col1_A  Col1_AB  Col2_A  Col2_AB  name_Jacob  name_John  name_Micheal  name_Sheldon  ID_-2500
0       0       0        1       1        0           0          1             0             0         1
1       0       0        1       1        0           0          1             0             0         1
2       0       1        0       1        0           0          1             0             0         1
3       1       1        0       1        0           1          0             0             0         1
4       1       1        0       1        0           0          0             1             0         1
5       0       1        0       0        1           0          1             0             0         1
6       1       1        0       1        0           0          0             0             1         1
7       0       0        1       0        1           0          0             0             1         1
8       1       0        1       0        1           1          0             0             0         1

希望对你有帮助。

【讨论】:

  • 谢谢!我已经用这个训练了我的模型,并且在测试时我得到了 ValueError: Number of features of the model must match the input. 因为我的测试数据的 n_features 较少。如何克服这个?
  • @user3164187,可能,这个问题已经回答了这个问题。 stackoverflow.com/questions/44026832/…
【解决方案2】:

您可以使用pd.get_dummies() 方法,它通常非常可靠。 This guide 应该可以帮助您入门。干杯!

【讨论】:

  • 我的数据是标称的,如果我使用 get_dummies(),模型会将其视为 Ordinal 吗?
  • @user3164187 get_dummies() 通常用于您希望对其进行一次性编码的标称数据;如果您有序数数据,那么您宁愿远离它,或者您可以使用 pd.qcut() 使用基于分位数的离散化并创建新列,以指定您的数据是否在截止范围内。例如,如果特征范围在 0-100 之间,pd.qcut() 可以创建 4 个新列 - '0-25'、-26-50'、'51-75' 和 '76-100' - 带有 0 和1s 表示该示例是否在该范围内。
猜你喜欢
  • 2021-03-19
  • 1970-01-01
  • 2017-11-06
  • 1970-01-01
  • 1970-01-01
  • 2021-03-30
  • 1970-01-01
  • 2018-12-20
  • 2019-10-24
相关资源
最近更新 更多