为什么NLP特征矩阵有两列?

时间:2019-06-08 22:21:58

标签: python machine-learning scikit-learn nlp kaggle

我正在尝试Quora Insincere Questions分类竞赛(后期提交),但是有一个奇怪的错误,我无法弄清楚。这是我的代码(相关部分):

def loss(predict, observed):
  a = predict*observed
  b = predict+observed
  return 2*(a/b)

train = pd.read_csv('../input/train.csv')
test = pd.read_csv('../input/test.csv')

train = train.iloc[0:5000, :]
test = test.iloc[0:1000, :]

qid = test['qid']

train = train.drop('qid', axis=1)
test = test.drop('qid', axis=1)

x_train, x_val, y_train, y_val = train_test_split(train['question_text'], train['target'])

count = CountVectorizer(stop_words='english', ngram_range=(1,1), min_df=1, #tokenizer=LemmaTokenizer()
                       )
tfidf = TfidfVectorizer(stop_words='english', ngram_range=(1,1), min_df=1, #tokenizer=LemmaTokenizer()
                       )

count.fit(list(x_train), list(x_val))
x_train_count = count.transform(x_train)
x_val_count = count.transform(x_val)

logistic = LogisticRegression()
logistic.fit(x_train_count, y_train)
predictions = logistic.predict_proba(x_val_count)
print("loss: %0.3f " %loss(predictions, y_val))

运行它时,出现此错误:

ValueError: operands could not be broadcast together with shapes (1250,2) (1250,)

我知道为什么会出错:这是因为我不能直接将两个数组相乘。但是,有些维度没有意义:

x_val_count.shape - (1250, 8411)我认为这是数字形式的注释扩展数组(1250个测试示例)。但是打印数组的开头是这样的:

  (0, 1057) 1
  (0, 4920) 1
  (0, 5563) 1
  (1, 2894) 1
  (1, 3403) 1
  (2, 3311) 1
  (3, 1386) 1
  (3, 1646) 1
  (4, 3207) 1
  (4, 3330) 1
  (4, 6111) 1
  (5, 2346) 1
  (5, 4148) 1
  (5, 4441) 1
  (5, 5223) 1
  (5, 5316) 1
  (5, 5378) 1
  (5, 5565) 2
  (5, 7571) 1
  (6, 746)  2
  (6, 983)  1
  (6, 985)  1
  (6, 3182) 1
  (6, 3455) 1
  (6, 4636) 1

看起来只有两列。为什么会有这种差异?

predictions.shape - (1250, 2)我不知道为什么预测有两列。为什么不一个?

我希望我能知道更多,我将能够解决此问题。但是有人知道我该如何解决吗?

1 个答案:

答案 0 :(得分:0)

那里有几个问题,所以我将尝试一个一个地回答。

x_val_count.shape - (1250, 8411)表示有1250个样本和8411个特征(其中8411是您的词汇量)。但是,出于效率考虑,scikit-learn的矢量化器以稀疏矩阵(非零特征的索引)的形式存储数据。这是因为功能列中有很多0(文档-在您的情况下是Quora问题-词汇中几乎没有单词的1%)。如果要将其转换为常规矩阵,则可以简单地调用x_val_count.toarray(),但是可能会耗尽内存,因为那将是一个巨大的矩阵。输出

(0, 1057) 1
(0, 4920) 1
(0, 5563) 1

可以理解为“文档0中包含3个单词,每个单词出现一次”。如果您想知道这些单词是什么,可以在count.vocabulary_字典中查找它们,其中单词是键,而索引(1057、4920,...)是值。

对于第二个关于predictions.shape - (1250, 2)的问题,您将获得2列,因为您调用了LogisticRegression的predict_proba(),它返回了每个类别(在您的情况下为2个类别)的概率。如果只需要预测标签,则应致电predict()