DataWhale零基础入门NLP赛事系列——Task3基于机器学习的文本分类

基于机器学习的文本分类

在对文本进行特征化的时候,最常见的是词袋模型。

1. 词袋模型

  词袋模型(Bag of Words,简称BoW),即将所有词语装进一个袋子里,每个词语都是独立的,把每一个单词都进行统计,同时计算每个单词出现的次数。也就是说,词袋模型不考虑文本中词与词之间的上下文关系,仅仅考虑所有词的权重,而权重与词在文本中出现的频率有关。

     一般来说,词袋模型首先会进行分词,在分词之后,通过统计每个词在文本中出现的次数,我们就可以得到该文本基于词的特征,如果将各个文本样本的这些词与对应的词频放在一起,就是我们常说的向量化。向量化完毕后一般也会使用TF-IDF进行特征的权重修正,再将特征进行标准化。再进行一些其他的特征工程之后,就可以将数据带入机器学习算法进行分类聚类了。但是它只考虑了词频,没有考虑上下文的信息,会有一定局限性。
sklearn中的CountVectorizer 和TfidfVectorizer
  1. **CountVectorizer:**只考虑词汇在文本中出现的频率,属于词袋模型特征。
  2. **TfidfVectorizer:**除了考虑词汇在文本中出现的频率以外还关注包含这个词汇的所有文本的数量。能够消减高频没有意义的词汇出现带来的影响,挖掘更有意义的特征。

首先,CountVectorizer

from sklearn.feature_extraction.text import CountVectorizer
corpus = ['我爱 中国','爸爸妈妈妈妈 爱我','爸爸妈妈 爱中国']
vectorizer = CountVectorizer(ngram_range=(1,2))
features = vectorizer.fit_transform(corpus)
print('CountVectorizer:')
print(vectorizer.get_feature_names())
print(vectorizer.vocabulary_)
print(features)

结果如下:

CountVectorizer:
['中国', '我爱', '我爱 中国', '爱中国', '爱我', '爸爸妈妈', '爸爸妈妈 爱中国', '爸爸妈妈妈妈', '爸爸妈妈妈妈 爱我']
{'我爱': 1, '中国': 0, '我爱 中国': 2, '爸爸妈妈妈妈': 7, '爱我': 4, '爸爸妈妈妈妈 爱我': 8, '爸爸妈妈': 5, '爱中国': 3, '爸爸妈妈 爱中国': 6}
  (0, 1)	1
  (0, 0)	1
  (0, 2)	1
  (1, 7)	1
  (1, 4)	1
  (1, 8)	1
  (2, 5)	1
  (2, 3)	1
  (2, 6)	1

TF-IDF 词频-逆向文件频率。再处理文本时,如何将文字转化为模型可以处理的向量呢? TF-IDF 是解决方案之一,字词的重要性与其在文本出现的频率成正比,与其在语料库中出现的频率成反比。

TF 为某个词在文章中出现的次数。为了消除不同文章大小之间的差异,便于不同文章之间的比较,标准化词频:TF = 某个词在文章中出现的总次数/文章的总词数。

IDF为逆文档频率。IDF=log(词料库的文档总数/包含该词的文档数+1) 避免分母为0,所以+1 TF-IDF值 = TF*IDF

# -*- coding: utf-8 -*-
from sklearn.feature_extraction.text import TfidfVectorizer
corpus = ['我爱中国 中国','爸爸妈妈 爱 我','爸爸妈妈 爱 中国']
# corpus = ['我爱中国','爸爸妈妈爱我','爸爸妈妈爱中国']
 
print("TfidfVectorizer:")
vectorizer = TfidfVectorizer(min_df=1,
                                 norm='l2',
                                 smooth_idf=True,
                                 use_idf=True,
                                 ngram_range=(1, 1))
features = vectorizer.fit_transform(corpus)
print(vectorizer.get_feature_names())   #显示所有文本的词汇,列表类型
print(vectorizer.vocabulary_)    #词汇表,字典类型
print(features)   #文本矩阵,得到tf-idf矩阵,稀疏矩阵表示法
print(features.shape)  #(3, 3)
print(features.toarray())   #.toarray() 是将结果转化为稀疏矩阵
print(features.toarray().sum(axis=0)) #统计每个词在所有文档中的词频

结果如下:

['中国', '我爱中国', '爸爸妈妈']
{'我爱中国': 1, '中国': 0, '爸爸妈妈': 2}
  (0, 0)	0.6053485081062916
  (0, 1)	0.7959605415681652
  (1, 2)	1.0
  (2, 2)	0.7071067811865476
  (2, 0)	0.7071067811865476
(3, 3)
[[0.60534851 0.79596054 0.        ]
 [0.         0.         1.        ]
 [0.70710678 0.         0.70710678]]
[1.31245529 0.79596054 1.70710678]

分类模型1:Count Vectors + RidgeClassifier
导入需要的包

import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
# from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import RidgeClassifier
from sklearn.metrics import f1_score
from sklearn.model_selection import train_test_split 

train_df = pd.read_csv('data/train_set.csv', sep='\t')
test_df = pd.read_csv('data/test_a.csv')

vectorizer = CountVectorizer(max_features=5000)
#vectorizer = TfidfVectorizer(ngram_range=(1,3), max_features=5000,smooth_idf=True) # 0.907
train_test = vectorizer.fit_transform(train_df['text'])
train_X,test_X,train_y,test_y = train_test_split(train_test,train_df['label'].values, test_size=0.3)
clf = RidgeClassifier()
clf.fit(train_X, train_y)
del train_df

val_pred = clf.predict(test_X)
print(f1_score(test_y, val_pred, average='macro'))

分类模型2:TF-IDF + RidgeClassifier

import pandas as pd
# from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import RidgeClassifier
from sklearn.metrics import f1_score
from sklearn.model_selection import train_test_split

train_df = pd.read_csv('data/train_set.csv', sep='\t')
test_df = pd.read_csv('data/test_a.csv')
vectorizer = TfidfVectorizer(ngram_range=(1,3), max_features=5000,smooth_idf=True) # 0.907
train_test = vectorizer.fit_transform(train_df['text'])
train_X,test_X,train_y,test_y = train_test_split(train_test,train_df['label'].values, test_size=0.3)
clf = RidgeClassifier()
clf.fit(train_X, train_y)
del train_df

val_pred = clf.predict(test_X)
print(f1_score(test_y, val_pred, average='macro'))


也正在尝试线性回归、随机森林

你可能感兴趣的:(DataWhale零基础入门NLP赛事系列——Task3基于机器学习的文本分类)