Python scikit-learn分类算法中如何处理混合数据类型(文本、数值、类别)的数据?

5

我正在尝试使用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

我需要预测变量项目结果。以下是我的操作步骤(假设df包含我的数据集):

  1. I converted the categories Project Category and Project Outcome to numeric values

    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             0                       This is a description     0
493992.4            1                       Stack Overflow rocks      1
  1. Then I processed the text column using 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             0                       (0, 249)\t0.17070240732941433\n (0, 304)\t0..     0
493992.4            1                       (0, 249)\t0.17070240732941433\n (0, 304)\t0..     1
  1. So since all variables are now numerical values, I thought I would be good to go to start training my model

    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)
    
但是当我尝试进行 model.fit 时,出现了一个错误:“ValueError:使用序列设置数组元素”。当我打印 X_train 时,我注意到“Project Description”因某种原因被替换为“NaN”。
这个有帮助吗?有没有好方法可以使用具有不同数据类型的变量进行分类?谢谢。

请在所有转换之前尝试执行 df.isnull().sum().sum() - Danylo Baibak
如果您的意思是缺失值,那么在上述步骤之前,它们已经从数据集中删除了。 - vdvaxel
2个回答

2
最初的回答

替换这个

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

with

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

你还可以使用:tfidf_vectorizer.fit_transform(df['Project Description']).todense()
同时,你不应该简单地将类别转换为数字。例如,如果你将A、B和C转换为0、1和2,则它们被视为2>1>0,因此C>B>A,而实际上A只是与B和C不同。为此,你可以使用One-Hot-Encoding(在Pandas中,你可以使用'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)

特征前缀不是必需的,但在多个分类特征的情况下会有所帮助。
此外,如果出于某种原因您不想将特征拆分为数字,则可以使用H2O.ai。使用H2O,您可以直接将分类变量作为文本输入模型。

1
问题出现在第二步,即tfidf_vectorizer.fit_transform(df['Project Description'])。因为tfidf_vectorizer.fit_transform 返回一个稀疏矩阵,然后将其存储在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))

我们在“project_category”上添加的最后一行是如果您想将其作为模型的一个特征包含在内。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接