【问题标题】:Classifying sentences with SciKit使用 SciKit 对句子进行分类
【发布时间】:2017-09-30 04:29:58
【问题描述】:

我有两个包含一堆句子的文件。其中一个文件包含带有肯定词的句子,而另一个带有否定词的句子。我正在尝试在“正面”和“负面”两个类别上训练分类器,这样当我给它一个新句子时,它会告诉它属于哪个类别。这是我目前所拥有的:

...
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf_vect= TfidfVectorizer(use_idf=True, smooth_idf=True, sublinear_tf=False)

input_list = ['A positive sentence', 'A negative sentence', ...]
class_list = [0, 1, ...]

df= pd.DataFrame({'text':input_list,'class': class_list})

X = tfidf_vect.fit_transform(df['text'].values)
y = df['class'].values

a_train, a_test, b_train, b_test = train_test_split(X, y, test_size=0.33, random_state=42)

from sklearn.ensemble import RandomForestClassifier
classifier = RandomForestClassifier(n_estimators=10)

classifier.fit(a_train.toarray(), b_train)
prediction = classifier.predict(a_test.toarray())

from sklearn import metrics
print(metrics.f1_score(b_test, prediction, average='macro'))

# classify a new sentence
df= pd.DataFrame({'text': ['A negative sentence', 'A positive sentence'],'class': [1, 0]})
print(classifier.predict(tfidf_vect.transform(df['text'].values)))

当我尝试对新句子进行分类时,我得到一个特征不匹配。我的问题是,这段代码中考虑的功能到底是什么?以及如何定义特征(例如,如果我想做的不仅仅是一袋单词,并且让每个单词的每个向量编码更多内容)?

【问题讨论】:

  • 1) 考虑的特征是每个句子中每个 unigram 的 tfidf 分数。 2) 最后一行 (print(classifier.predict(X))) 的调用是故意的吗?我认为应该是classifier.predict(tfidf_vect.transform(df['text'].values))
  • @Elisha 感谢您指出这一点

标签: python machine-learning scikit-learn


【解决方案1】:

toTfidfVectorizer 内置了一个很好的函数来帮助解决这个问题。对于下面的示例,您可以查看特征对应的单词。

tfidf_vect= TfidfVectorizer(use_idf=True, smooth_idf=True,
                            sublinear_tf=False)

input_list = ['A positive sentence', 'A negative sentence', ]
class_list = [0, 1]

df= pd.DataFrame({'text':input_list,'class': class_list})

X = tfidf_vect.fit_transform(df['text'].values)
y = df['class'].values

print(tfidf_vect.get_feature_names())
print()
print(X.todense())

输出

[u'negative', u'positive', u'sentence']

[[ 0.          0.81480247  0.57973867]
 [ 0.81480247  0.          0.57973867]]

如果您想扩展您的模型以包含成对的单词,您也可以轻松做到这一点:

tfidf_vect= TfidfVectorizer(use_idf=True, smooth_idf=True,
                            sublinear_tf=False, ngram_range=(1, 2))

input_list = ['A positive sentence', 'A negative sentence', ]
class_list = [0, 1]

df= pd.DataFrame({'text':input_list,'class': class_list})

X = tfidf_vect.fit_transform(df['text'].values)
y = df['class'].values

print(tfidf_vect.get_feature_names())
print()
print(X.todense())

输出

[u'negative', u'negative sentence', u'positive', u'positive sentence', u'sentence']

[[ 0.          0.          0.6316672   0.6316672   0.44943642]
 [ 0.6316672   0.6316672   0.          0.          0.44943642]]

如果您想添加更多自定义功能,则可以通过在末端用螺栓固定它们来做到这一点,如下所示:

X = np.array(X.todense())
my_feature = np.array([[0.7, 1.2]])
np.concatenate((X, my_feature.T), axis=1)

输出:

array([[ 0.        ,  0.        ,  0.6316672 ,  0.6316672 ,  0.44943642,
     0.7       ],
       [ 0.6316672 ,  0.6316672 ,  0.        ,  0.        ,  0.44943642,
     1.2       ]])

【讨论】:

  • 谢谢,这真的很有帮助。因此,假设对于每个术语,我想添加一个特征,例如该术语是否以字母“n”开头,并在当前向量上赋予该特征 50% 的权重,我将使用 np.array([[x1 , x2]]) 其中 x1,2 等是术语在 input_list 中出现的顺序?
猜你喜欢
  • 2015-03-16
  • 2012-08-31
  • 1970-01-01
  • 2016-03-20
  • 2017-08-08
  • 2017-08-01
  • 2016-05-16
  • 2015-02-05
  • 2021-03-26
相关资源
最近更新 更多