Scikit learn scikit学习:如果经过一次热编码后,新数据的特征少于训练/测试集,如何预测新数据
我试图在我的第一个ML项目中使用scikit learn,使用它的Scikit learn scikit学习:如果经过一次热编码后,新数据的特征少于训练/测试集,如何预测新数据,scikit-learn,python-3.7,decision-tree,one-hot-encoding,Scikit Learn,Python 3.7,Decision Tree,One Hot Encoding,我试图在我的第一个ML项目中使用scikit learn,使用它的DecisionTreeClassifier和包含数字和分类特征的数据样本,例如:['High',33',No',4] 我已经到了我能做到的地步 从.csv文件中读取培训和测试数据 physio=pd.read\u csv('data.csv',header=None,names=['HR','M','T','W','D']) 提取目标类: labels=physi.pop('D') 一个热编码的分类特征使用pandas.ge
DecisionTreeClassifier
和包含数字和分类特征的数据样本,例如:['High',33',No',4]
我已经到了我能做到的地步
physio=pd.read\u csv('data.csv',header=None,names=['HR','M','T','W','D'])
labels=physi.pop('D')
pandas.get_dummies
。这也将功能的数量从4个增加到了6个(因为“HR”和“T”分别变为“HR\u高”/“HR\u低”和“T\u是”/“T\u否”)
x_train, x_test, y_train, y_test = train_test_split(physio, labels, test_size=0.25)
dt = DecisionTreeClassifier(max_depth=8, min_samples_split=.3, min_samples_leaf=.26, max_features=4)
dt.fit(x_train, y_train)
y_pred = dt.predict(x_test)
y_检验
和y_pred
评估使用混淆矩阵的分类(也是ROC的AUC)
newSample = [['Low', 2, 'No', 8]]
newSampleDF = pd.DataFrame(newSample, columns=['HR', 'M', 'T', 'W'])
for col in physio.dtypes[physio.dtypes == 'object'].index:
for_dummy = physio.pop(col)
physio = pd.concat([physio, pd.get_dummies(for_dummy, prefix=col)], axis=1)
for col in newSampleDF.dtypes[newSampleDF.dtypes == 'object'].index:
for_dummy = newSampleDF.pop(col)
newSampleDF = pd.concat([newSampleDF, pd.get_dummies(for_dummy, prefix=col)], axis=1)
newSampleDF
时,它显示:
M W HR_Low T_No
2 8 1 1
而我试图对其进行分类的数据是
M W HR_High HR_Low T_No T_Yes
12 48 0 1 0 1
这就是我得到错误的原因:
ValueError:模型的特征数必须与输入匹配。模型n_特征为6,输入n_特征为4
这是不言而喻的,我只是不知道如何解决它。我如何让我的新数据以一种它知道缺失值的方式进行编码,在本例中为“高”和“是”
我希望我说得有道理,可以随意指出错误和改进,但请记住,这里是第一次
谢谢我认为整个方法有点问题。我们不需要使用
pd.get_dummies
,因为我们已经知道了类别列。那么为什么我们不直接使用它呢
因此,我倾向于以下解决方案:
import pandas as pd
cats = ["HR", "T"]
training_data = pd.DataFrame([[12, 48, 0, 1, 0, 1]], columns=["M","W", "HR_High", "HR_Low", "T_No", "T_Yes"])
raw_cols = ['HR', 'M', 'T', 'W']
newSample = [['Low', 2, 'No', 8]]
newSampleDF = pd.DataFrame(newSample, columns=raw_cols)
cols = ["M","W", "HR_High", "HR_Low", "T_No", "T_Yes"]
template = pd.DataFrame([6 * [None]], columns=cols)
for col in raw_cols:
if col in cats:
template.loc[0, col + "_" + newSampleDF.loc[0, col]] = 1
else:
template.loc[0, col] = newSampleDF.loc[0, col]
# replace Nans with 0
newSampleDF = template.fillna(0)
print(newSampleDF)
Out:
M W HR_High HR_Low T_No T_Yes
0 2 8 0 1 1 0
我认为整个方法有点问题。我们不需要使用
pd.get_dummies
,因为我们已经知道了类别列。那么为什么我们不直接使用它呢
因此,我倾向于以下解决方案:
import pandas as pd
cats = ["HR", "T"]
training_data = pd.DataFrame([[12, 48, 0, 1, 0, 1]], columns=["M","W", "HR_High", "HR_Low", "T_No", "T_Yes"])
raw_cols = ['HR', 'M', 'T', 'W']
newSample = [['Low', 2, 'No', 8]]
newSampleDF = pd.DataFrame(newSample, columns=raw_cols)
cols = ["M","W", "HR_High", "HR_Low", "T_No", "T_Yes"]
template = pd.DataFrame([6 * [None]], columns=cols)
for col in raw_cols:
if col in cats:
template.loc[0, col + "_" + newSampleDF.loc[0, col]] = 1
else:
template.loc[0, col] = newSampleDF.loc[0, col]
# replace Nans with 0
newSampleDF = template.fillna(0)
print(newSampleDF)
Out:
M W HR_High HR_Low T_No T_Yes
0 2 8 0 1 1 0
关于您的编辑:如果按…顺序将根据输入而改变,您的意思是
[[['Low',2',No',8]]
's items'顺序,则不,该顺序完全由我控制。或者你的意思是什么?还有,我现在正在尝试你的答案:有没有办法告诉get\u dummies
不要用n填充它,并以某种方式传递它应该填充的字符串?在本例中:“高”和“是”。还是太多了?thanks@Scaramouche查看我对您的问题的解决方案。如果您能看到之前的解决方案,而不是隐藏(因为编辑),我会很高兴,因为我认为这是一个更通用的解决方案,而不是当前更适合我的场景,这将有助于未来读者了解您的编辑:如果按…顺序将根据输入而改变,您的意思是[['Low',2',No',8]]
的项目顺序,那么不,顺序完全由我控制。或者你的意思是什么?还有,我现在正在尝试你的答案:有没有办法告诉get\u dummies
不要用n填充它,并以某种方式传递它应该填充的字符串?在本例中:“高”和“是”。还是太多了?thanks@Scaramouche查看我对您的问题的解决方案。如果您能看到之前的解决方案,而不是隐藏(因为编辑),我会很高兴,因为我认为这是一个更通用的解决方案,而不是现在的解决方案,它更适合我的场景,这将有助于未来的读者