一、词袋
简单来说词袋就是一种非常简单的文本数据的特征提取方法。他可以展现一篇预料出现的词语种类和数量,它本身比较简单,也有稀疏性和语义性的问题,但是比较适合初步了解NLP。
二、背景和预料数据
取自于https://www.kaggle.com/c/word2vec-nlp-tutorial/data,Kaggle中的一个赛题。
数据集由5万条IMDB电影评论组成,专门用于情感分析。评论的情绪是二元的,即IMDB评分< 5的情绪得分为0,评分>=7的情绪得分为1。没有一部电影的评论超过30条。
id - 唯一ID,标记不同评论
sentiment - 情感标签
review - 影评内容
三、数据的预处理
首先根据文本类型,要去除html标签,比如:br
接下来,标点对于我们分析情感是没有用,所以也要去掉。之后因为全是英文语料,所以分词会比中文语料简单。再去掉对情感分析没有用的停用词,将处理数据后的单词重组就行了。
df = pd.read_csv('data/labeledTrainData.tsv', sep='\t', escapechar='\\')
(1)去除html标签
example = BeautifulSoup(df['review'][1000], 'html.parser').get_text()
print(example)
(2)去除标点符号
example_letters = re.sub(r'[^a-zA-Z]', ' ', example)
print(example_letters)
(3)分词
words = example_letters.lower().split()
print(words)
(4)停用词
stopwords = {}.fromkeys([ line.rstrip() for line in open('StopWords')])
words_nostop = [w for w in words if w not in stopwords]
print(words_nostop)
(5)完整的流程
eng_stopwords = stopwords.words('english')
def clean_text(text):
text = BeautifulSoup(text,'html.parser').get_text()
text = re.sub(r'[^a-zA-Z]', ' ', text)
words = text.lower().split()
words = [w for w in words if w not in eng_stopwords]
return ' '.join(words)
print(clean_text(df['review'][1000]))
四、词袋模型训练分类器
接下来我们需要创建特征模型,并进行训练,这里要指出的是,词袋模型并没有涉及到词向量等内容。
(1)提取关键词
使用CountVectorizer将语料中的所有词汇构成一个词频矩阵,选择5000个单词作为合适的大小。
vectorizer = CountVectorizer(max_features=5000)
train_data_features = vectorizer.fit_transform(df.clean_review).toarray()
vocab = vectorizer.get_feature_names_out()
print(vocab[:15])
查看出现次数较多的词语的出现次数。
word_counts = np.sum(train_data_features, axis=0)
word_count_dict = {}
for word, count in zip(vocab, word_counts):
word_count_dict.update({word: count})
sort_list = sorted(word_count_dict.items(), key=lambda item: item[1], reverse=True)
print(sort_list[:20])
(2)对词袋模型进行训练
使用逻辑斯蒂模型对词袋进行训练。
from sklearn.model_selection import train_test_split
X_train, X_test, y_train,y_test = train_test_split(train_data_features,df.sentiment,test_size=0.2,random_state=0)
LR_model = LogisticRegression()
LR_model = LR_model.fit(X_train, y_train)
y_pred = LR_model.predict(X_test)
cnf_matrix = confusion_matrix(y_test, y_pred)
print("Recall metric in the testing dataset", cnf_matrix[1,1]/(cnf_matrix[1,0]+cnf_matrix[1,1]))
print("accuracy metric in the testing dataset", (cnf_matrix[1,1]+cnf_matrix[0,0])/(cnf_matrix[0,0]+cnf_matrix[1,1]+cnf_matrix[1,0]+cnf_matrix[0,1]))