【问题标题】:save and load one hot encoding for ML为 ML 保存和加载一种热编码
【发布时间】:2020-04-18 00:58:38
【问题描述】:

我已经搜索了两天,似乎无法掌握解决方案。对于机器学习回归模型,我需要对某些列进行热编码。训练数据和模型拟合正在我的本地 PC 上进行。在此之后,模型将被上传到服务器进行预测。

问题在于新数据不是初始编码的一部分,因此我需要以与在我的 PC 上学习数据相同的方式对其进行热编码。我发现我可以保存编码器(sklearn.preprocessing -> OneHotEncoder)。 但我无法将数据转换为正确的格式。

为了让这里更容易理解,我刚刚创建了一个带有一些非常简单的虚拟数据的笔记本。

# Import pandas library 
import pandas as pd 
# initialize list of lists 
data = [['tom', 10], ['nick', 15], ['juli', 14]] 
# Create the pandas DataFrame 
df = pd.DataFrame(data, columns = ['Name', 'Age']) 
# print dataframe.
df 

输出:

姓名年龄

汤姆 10

尼克 15

7 月 14 日


# hot encoding
hot_Name = pd.get_dummies(df.Name)
X = pd.concat((df[['Age']], hot_Name), axis=1)
X

输出:

年龄朱莉尼克汤姆

10 0 0 1

15 0 1 0

14 1 0 0


# outside data
# initialize list of lists 
data_new = [['michael', 20], ['juli', 45]] 
# Create the pandas DataFrame 
df_new = pd.DataFrame(data_new, columns = ['Name', 'Age']) 
# print dataframe. 
df_new

输出:

姓名年龄

迈克尔 20

七月 45

是否可以像“data”一样对“data_new”进行编码并保存编码器以供以后在实时传入数据上使用?

预期在 df_new 模型中使用的热编码:

年龄朱莉尼克汤姆

20 0 0 0

45 1 0 0

【问题讨论】:

  • 那么它和django有什么关系呢?
  • 是的,对不起,我在那里实现它。但不是直接连接。将删除标签

标签: python machine-learning one-hot-encoding


【解决方案1】:

据我所知,pandas 没有公开使用get_dummies 完成的序列化编码方法。我会直接使用OneHotEncoder 对变量进行编码,然后使用joblib 对其进行序列化。

import joblib
import pandas as pd 
from sklearn.preprocessing import OneHotEncoder

col_names = ['name', 'age']
data = [['tom', 10], ['nick', 15], ['juli', 14]] 

enc = OneHotEncoder(handle_unknown='error')
enc.fit(data)
joblib.dump(enc, 'encoder.joblib')

然后在服务器上:

enc = joblib.load('encoder.joblib')
data_df = pd.DataFrame(data=data, columns=col_names)
enc_df = pd.DataFrame(data=enc.transform(data).toarray(), columns=enc.get_feature_names(col_names), dtype=bool)
df = pd.concat([data_df, enc_df], axis=1)

df 的输出:

|   | name | age | name_juli | name_nick | name_tom | age_10 | age_14 | age_15 |
|---|------|-----|-----------|-----------|----------|--------|--------|--------|
| 0 | tom  | 10  | False     | False     | True     | True   | False  | False  |
| 1 | nick | 15  | False     | True      | False    | False  | False  | True   |
| 2 | juli | 14  | True      | False     | False    | False  | True   | False  |

【讨论】:

  • 谢谢,这很有帮助,但不是解决方案。在“在服务器上”部分,您将初始信息再次放入编码中。当我尝试获取 df_new 的“michael”信息时,出现错误“在转换期间在第 0 列中找到未知类别 ['michael']”。另一个问题是 OneHotEncoding 对所有列进行了编码。不应对年龄进行编码,因为这是一组真正可比较的值,对于 ML,应保留在一个列中。
  • @DimiDev 我不知道你在建模什么,所以不知道什么是有意义的编码。在某些情况下,单热编码年龄是一个很好的举措。至于预测中出现新类别时的错误,这是故意的。你的模型应该如何处理它过去没有接触过的类别?相应地处理问题。如果您需要,您也可以选择忽略 OneHotEncoder(handle_unknown='ignore') 的错误。
  • 做了一些测试,仍然有“不编码时代”的问题。但是是的,handle_unknown 帮助很大。将发布结果。
  • 如果在data 中你只传递名字,没有,你不会得到年龄编码。我确信这很明显,所以很可能有一些我没有得到的复杂性。请注意,您可以传递需要 OHE(One-Hot Encoded)的任何 2d 数组(可选地使用 reshape 处理您的 1d),然后将 concat 与其余数据一起传递。
【解决方案2】:

在 Lukasz Tracewski 的帮助下: 由于 categorical_features 不再起作用。数据帧必须分成两个 df,一个带有数据用于编码,另一个用于不编码并在之后连接。

import joblib
import pandas as pd 
from sklearn.preprocessing import OneHotEncoder

col_names_encode = ['Name']

# learning data
data = [['tom', 10], ['nick', 15], ['juli', 14]] 
df = pd.DataFrame(data, columns = ['Name', 'Age']) 

# data from data lake
data_new = [['michael', 20], ['juli', 45]] 
df_new = pd.DataFrame(data_new, columns = ['Name', 'Age']) 

# get only data for encoding
df_encode = df.drop(columns=["Age"])

# one hot encoding
enc = OneHotEncoder(handle_unknown='ignore')
enc.fit(df_encode)
df_encode = pd.DataFrame(data=enc.transform(df_encode).toarray(), columns=enc.get_feature_names(col_names_encode), dtype=bool)
# trasfer true and false to 1 and 0
df_encode = df_encode * 1

# concatenate data
df = pd.concat((df[['Age']], df_encode), axis=1)

#use the encoder to encode new incoming data
df_new_encode = df_new.drop(columns=["Age"])

df_new_encode = pd.DataFrame(data=enc.transform(df_new_encode).toarray(), columns=enc.get_feature_names(col_names_encode), dtype=bool)
df_new = pd.concat((df_new[['Age']], df_new_encode), axis=1)
df_new = df_new * 1

df_new.head()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-19
    • 2021-01-20
    • 2018-10-25
    • 2019-02-06
    • 1970-01-01
    • 2020-01-30
    • 2021-06-08
    相关资源
    最近更新 更多