Python scikit学习混合数据类型的分类(文本、数字、分类)

Python scikit学习混合数据类型的分类(文本、数字、分类),python,pandas,machine-learning,scikit-learn,Python,Pandas,Machine Learning,Scikit Learn,我正在尝试使用Pandas和scikit learn在Python中执行分类。我的数据集包含文本变量、数字变量和分类变量的组合 假设我的数据集如下所示: Project Cost Project Category Project Description Project Outcome 12392.2 ABC This is a description Fully Funded 4939

我正在尝试使用Pandas和scikit learn在Python中执行分类。我的数据集包含文本变量、数字变量和分类变量的组合

假设我的数据集如下所示:

Project Cost        Project Category        Project Description       Project Outcome
12392.2             ABC                     This is a description     Fully Funded
493992.4            DEF                     Stack Overflow rocks      Expired
Project Cost        Project Category        Project Description       Project Outcome
12392.2             0                       This is a description     0
493992.4            1                       Stack Overflow rocks      1
Project Cost        Project Category        Project Description       Project Outcome
12392.2             0                       (0, 249)\t0.17070240732941433\n (0, 304)\t0..     0
493992.4            1                       (0, 249)\t0.17070240732941433\n (0, 304)\t0..     1
我需要预测变量
项目结果
。以下是我所做的(假设
df
包含我的数据集):

  • 我将类别
    项目类别
    项目结果
    转换为数值

    df['Project Category'] = df['Project Category'].factorize()[0]
    df['Project Outcome'] = df['Project Outcome'].factorize()[0]
    
  • 数据集现在如下所示:

    Project Cost        Project Category        Project Description       Project Outcome
    12392.2             ABC                     This is a description     Fully Funded
    493992.4            DEF                     Stack Overflow rocks      Expired
    
    Project Cost        Project Category        Project Description       Project Outcome
    12392.2             0                       This is a description     0
    493992.4            1                       Stack Overflow rocks      1
    
    Project Cost        Project Category        Project Description       Project Outcome
    12392.2             0                       (0, 249)\t0.17070240732941433\n (0, 304)\t0..     0
    493992.4            1                       (0, 249)\t0.17070240732941433\n (0, 304)\t0..     1
    
  • 然后我使用
    TF-IDF

    tfidf_vectorizer = TfidfVectorizer()
    df['Project Description'] = tfidf_vectorizer.fit_transform(df['Project Description'])
    
  • 数据集现在看起来像这样:

    Project Cost        Project Category        Project Description       Project Outcome
    12392.2             ABC                     This is a description     Fully Funded
    493992.4            DEF                     Stack Overflow rocks      Expired
    
    Project Cost        Project Category        Project Description       Project Outcome
    12392.2             0                       This is a description     0
    493992.4            1                       Stack Overflow rocks      1
    
    Project Cost        Project Category        Project Description       Project Outcome
    12392.2             0                       (0, 249)\t0.17070240732941433\n (0, 304)\t0..     0
    493992.4            1                       (0, 249)\t0.17070240732941433\n (0, 304)\t0..     1
    
  • 既然所有变量现在都是数值,我想我最好开始训练我的模型

    X = df.drop(columns=['Project Outcome'], axis=1)
    y = df['Project Outcome']
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1)
    model = MultinomialNB()
    model.fit(X_train, y_train)
    
  • 但是我得到了一个错误
    ValueError:在尝试执行
    model.fit
    时,设置一个带有序列的数组元素。
    。当我打印
    X_train
    时,我注意到
    项目说明
    由于某种原因被
    NaN
    取代


    有什么帮助吗?使用不同数据类型的变量进行分类有好方法吗?谢谢。

    第2步出现的问题与
    tfidf\u矢量器.fit\u转换(df['Project Description'])
    有关,因为tfidf\u矢量器.fit\u转换随后以压缩形式存储在df['Project Description']列中。您希望将结果作为稀疏矩阵(或者更理想的是作为密集矩阵)保存,以用于模型训练和测试。下面是以密集形式准备数据的示例代码

    import pandas as pd
    import numpy as np
    df = pd.DataFrame({'project_category': [1,2,1], 
                       'project_description': ['This is a description','Stackoverflow rocks', 'Another description']})
    
    from sklearn.feature_extraction.text import TfidfVectorizer
    tfidf_vectorizer = TfidfVectorizer()
    X_tfidf = tfidf_vectorizer.fit_transform(df['project_description']).toarray()
    X_all_data_tfidf = np.hstack((df['project_category'].values.reshape(len(df['project_category']),1), X_train_tfidf))
    
    我们在“项目类别”中添加的最后一行,用于您是否希望将其作为功能包含在模型中。

    替换此项

    df['Project Description'] = tfidf_vectorizer.fit_transform(df['Project Description'])
    

    您还可以使用:tfidf_vectorizer.fit_transform(df['Project Description']).todense()

    此外,您不应该简单地将类别转换为数字。例如,如果将A、B和C转换为0、1和2。它们被视为2>1>0,因此C>B>A通常不是这样,因为A只是不同于B和C。为此,您可以使用一种热编码(在熊猫中,您可以使用“get_dummies”进行此编码)。您可以将下面的代码用于所有分类功能

    #df has all not categorical features
    featurelist_categorical = ['Project Category', 'Feature A',
               'Feature B']
    
    for i,j in zip(featurelist_categorical, ['Project Category','A','B']):
      df = pd.concat([df, pd.get_dummies(data[i],prefix=j)], axis=1)
    
    功能前缀不是必需的,但在有多个分类功能的情况下,它将特别有助于您

    #df has all not categorical features
    featurelist_categorical = ['Project Category', 'Feature A',
               'Feature B']
    
    for i,j in zip(featurelist_categorical, ['Project Category','A','B']):
      df = pd.concat([df, pd.get_dummies(data[i],prefix=j)], axis=1)
    

    另外,如果你不想因为某种原因将你的功能分割成数字,你可以使用H2O.ai。使用H2O,您可以直接将分类变量作为文本输入到模型中。

    在所有转换之前,请尝试执行
    df.isnull().sum().sum()
    。如果这是您的意思,则不存在缺失值。在上述步骤之前,这些值已从数据集中删除。