ValueError:X每个样本具有29个功能;期待84

时间:2019-08-10 00:13:48

标签: python pandas scikit-learn valueerror one-hot-encoding

我正在使用Lending Club API编写脚本,以预测贷款是“全额还清”还是“清还”。为此,我使用scikit-learn构建模型并使用joblib持久化。由于持久模型中的列数与新原始数据中的列数之间的差异,我遇到了ValueError。 ValueError是由于为分类变量创建伪变量而引起的。模型中使用的列数为84,在本示例中,使用新数据的列数为29。

在创建虚拟变量时,新数据的列数必须为84,但是我不确定如何继续,因为分类变量'homeOwnership','addrState'和'目的'的所有可能值中只有一部分从API获取新数据时出现'。

这是我正在测试的代码,从分类变量转换为虚拟变量并在模型实现时停止。

#......continued

df['mthsSinceLastDelinq'].notnull().astype('int')
df['mthsSinceLastRecord'].notnull().astype('int')
df['grade_num'] = df['grade'].map({'A':0,'B':1,'C':2,'D':3})
df['emp_length_num'] = df['empLength']
df = pd.get_dummies(df,columns=['homeOwnership','addrState','purpose'])
# df = pd.get_dummies(df,columns=['home_ownership','addr_state','verification_status','purpose'])

# step 3.5 transform data before making predictions

df.drop(['id','grade','empLength','isIncV'],axis=1,inplace=True)
dfbcd = df[df['grade_num'] != 0]
scaler = StandardScaler()
x_scbcd = scaler.fit_transform(dfbcd)

# step 4 predicting

lrbcd_test = load('lrbcd_test.joblib')
ypredbcdfinal = lrbcd_test.predict(x_scbcd)

这是错误消息

ValueError                                Traceback (most recent call last)
<ipython-input-239-c99611b2e48a> in <module>
     11 # change name of model and file name
     12 lrbcd_test = load('lrbcd_test.joblib')
---> 13 ypredbcdfinal = lrbcd_test.predict(x_scbcd)
     14 
     15     #add model

~\Anaconda3\lib\site-packages\sklearn\linear_model\base.py in predict(self, X)
    287             Predicted class label per sample.
    288         """
--> 289         scores = self.decision_function(X)
    290         if len(scores.shape) == 1:
    291             indices = (scores > 0).astype(np.int)

~\Anaconda3\lib\site-packages\sklearn\linear_model\base.py in decision_function(self, X)
    268         if X.shape[1] != n_features:
    269             raise ValueError("X has %d features per sample; expecting %d"
--> 270                              % (X.shape[1], n_features))
    271 
    272         scores = safe_sparse_dot(X, self.coef_.T,

ValueError: X has 29 features per sample; expecting 84

3 个答案:

答案 0 :(得分:1)

您的新数据应与用于训练和保留原始模型的数据具有相同的确切列。而且,如果在较新的数据中分类变量的唯一值数量较少,请在执行pd.get_dummies()之后手动为这些变量添加列,并将所有数据点的列设置为零。

该模型仅在获得所需的列数时才起作用。如果pd.get_dummies无法在较新的数据上创建所有这些列,则应手动进行操作。

编辑

如果要在pd.get_dummies()步骤之后自动插入缺少的列,则可以使用以下方法。 假设df_newdata是将pd.get_dummies()应用于新数据集后的数据帧,而df_olddata是在较旧的数据集(用于训练)上应用pd.get_dummies()时获得的df,则只需执行此操作:

df_newdata = df_newdata.reindex(labels=df_olddata.columns,axis=1)

这将自动在df_newdata中创建缺少的列(与df_olddata相比),并将所有行的这些列的值设置为NaN。因此,现在,您的新数据框具有与原始数据框相同的摘录列。

希望这会有所帮助

答案 1 :(得分:0)

您能否在测试数据对象transform上使用x_scbcd [StandardScaler对象]的lrbcd_test方法?这将创建测试数据的特征表示。

ypredbcdfinal = lrbcd_test.predict(x_scbcd.transform(x_scbcd))

答案 2 :(得分:0)

仅使用Transform而不是fit_transform。这应该可以解决问题。希望对您有所帮助。

    x_scbcd = scaler.transform(dfbcd)