Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scikit learn scikit学习:如果经过一次热编码后,新数据的特征少于训练/测试集,如何预测新数据_Scikit Learn_Python 3.7_Decision Tree_One Hot Encoding - Fatal编程技术网

Scikit learn scikit学习:如果经过一次热编码后,新数据的特征少于训练/测试集,如何预测新数据

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

我试图在我的第一个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.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'])
    
  • 然后我试着对它进行热编码。这就是问题产生的地方,因为编码完成后,仍然有4个特性,因为仅仅是一个数据样本,它对“高”和“是”一无所知,所以“HR”和“t”分别变成了“HR\u Low”和“t\u No”

    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查看我对您的问题的解决方案。如果您能看到之前的解决方案,而不是隐藏(因为编辑),我会很高兴,因为我认为这是一个更通用的解决方案,而不是现在的解决方案,它更适合我的场景,这将有助于未来的读者