Python 为ML保存并加载一个热编码
我已经找了两天了,至少我不能找到答案。对于机器学习回归模型,我需要对一些列进行热编码。训练数据和模型拟合正在我的本地PC上进行。之后,模型将上载到服务器进行预测 问题是,新数据不是初始编码的一部分,因此我需要以与在PC上学习数据相同的方式对其进行热编码。我发现我可以保存编码器(sklearn.preprocessing->onehotcoder)。 但我无法将数据转换为正确的格式 为了便于理解,我刚刚创建了一个带有一些非常简单的虚拟数据的笔记本Python 为ML保存并加载一个热编码,python,machine-learning,one-hot-encoding,Python,Machine Learning,One Hot Encoding,我已经找了两天了,至少我不能找到答案。对于机器学习回归模型,我需要对一些列进行热编码。训练数据和模型拟合正在我的本地PC上进行。之后,模型将上载到服务器进行预测 问题是,新数据不是初始编码的一部分,因此我需要以与在PC上学习数据相同的方式对其进行热编码。我发现我可以保存编码器(sklearn.preprocessing->onehotcoder)。 但我无法将数据转换为正确的格式 为了便于理解,我刚刚创建了一个带有一些非常简单的虚拟数据的笔记本 # Import pandas library
# 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
朱莉14
输出: 朱利·尼克·汤姆的年龄 10001 150 110 14100
输出: 姓名年龄 迈克尔20 朱莉45 是否可以将“data_new”编码为与“data”相同的方式,并保存编码器,以便在实时传入数据上使用 df_new的th模型中预期使用的热编码: 朱利·尼克·汤姆的年龄 20 0 0 0
45 1 0 0据我所知,
pandas
没有公开使用get_dummie
进行串行编码的方法。我会直接使用onehotcoder
对变量进行编码,然后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,一个用于编码,另一个用于不编码,然后连接
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()
那么它和django有什么关系呢?是的,对不起,我用这个来实现它。但不是直接联系。将删除标记谢谢这是非常有用的,但不完全是解决方案。在“服务器上”部分,您将初始信息再次输入到编码中。当我试图获取dfu new的“michael”信息时,出现了一个错误“在转换期间在第0列中发现未知类别['michael']。另一个问题是OneHotEncoding对所有列进行了编码。不应该对年龄进行编码,因为这是一组真正可比较的值,应该保留在ML的一列中。@DimiDev我不知道你在建模什么,所以无法判断编码的意义。在某些情况下,对年龄进行热编码是一个好的举措。至于预测中出现新类别时的错误,这是故意的。您的模型应该如何处理过去未公开的类别?相应地处理这个问题。如果需要,您也可以选择忽略OneHotEncoder(handle_unknown='ignore')的错误。进行了一些测试,但仍然存在“不编码年龄”的问题。但是是的,你的未知帮助了很多。将发布结果。如果在
数据中只传递姓名,不传递,则不会获得年龄编码。我相信这是显而易见的,所以可能有一些复杂的东西我没有得到。请注意,您可以传递任何需要OHE(一个热编码)的2d数组(可以选择使用重塑
处理1d),然后用剩余数据传递concat
。
| | 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 |
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()