为 ML 保存和加载一个热编码
save and load one hot encoding for ML
我已经找了两天了,似乎无法掌握解决方案。对于机器学习回归模型,我需要对某些列进行热编码。训练数据和模型拟合正在我的本地 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
据我所知,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 |
在 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()
我已经找了两天了,似乎无法掌握解决方案。对于机器学习回归模型,我需要对某些列进行热编码。训练数据和模型拟合正在我的本地 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
据我所知,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 |
在 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()