天池NLP学习赛(3)基于机器学习的文本分类

本文深入探讨了基于机器学习的文本分类技术,重点介绍了文本表示方法,包括one-hot编码、词袋模型、N-gram以及TF-IDF等关键概念,并通过实例展示了如何使用Python的sklearn库进行实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于机器学习的文本分类

文本表示方法

step 1:one-hot

将每一个单词使用一个离散的向量表示。具体将每个字/词编码一个索引,然后根据索引进行赋值。

step 2:Bag of Words(词袋表示/Count Vectors)

每个文档的字/词可以使用其出现次数来进行表示。

则一段文本对应离散向量,长度和one-hot一样长,数字是出现次数

from sklearn.feature_extraction.text import CountVectorizer
corpus = [
    'This is the first document.',
    'This document is the second document.',
    'And this is the third one.',
    'Is this the first document?',
]
vectorizer = CountVectorizer()
vectorizer.fit_transform(corpus).toarray()
array([[0, 1, 1, 1, 0, 0, 1, 0, 1],
       [0, 2, 0, 1, 0, 1, 1, 0, 1],
       [1, 0, 0, 1, 1, 0, 1, 1, 1],
       [0, 1, 1, 1, 0, 0, 1, 0, 1]], dtype=int64)

step 3:N-gram

N-gram与Count Vectors类似,不过加入了相邻单词组合成为新的单词并进行计数。类似于CNN/LSTM里面步长从1变成N。

在Count Vector中作为参数进行设置。下面摘自:

example: 一句话’I like you’

(1)如果ngram_range = (2, 2)表示只选取前后的两个词构造词组合 :词向量组合为:’I like‘ 和 ’like you‘

(2)如果ngram_range = (1, 3) 表示选取1到3个词做为组合方式: 词向量组合为: ‘I’, ‘like’, ‘you’, ‘I like’, ‘like you’, ‘I like you’ 构成词频标签

vec = CountVectorizer(ngram_range=(1,3))
vec.fit_transform(corpus).toarray()
array([[0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0,
        0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0],
       [0, 0, 0, 2, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1,
        1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
       [1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0,
        0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0],
       [0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0,
        0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1]], dtype=int64)

其它参数的设置详见

step* : 对中文文本的操作

ps:用jieba库(ananconda用pip install jieba 下载,用conda下载会报错)

下面例子的原文

import pandas as pd
import jieba
chin = ["他用报话机向上级呼喊:“为了祖国,为了胜利,向我开炮!向我开炮!",
        "记者:你怎么会说出那番话?",
        "韦昌进:我只是觉得,对准我自己打,才有可能把上了我哨位的这些敌人打死,或者打下去。"]

chin = [" ".join(jieba.lcut(e)) for e in chin] # 分词,并用" "连接
chin
['他 用 报话机 向 上级 呼喊 : “ 为了 祖国 , 为了 胜利 , 向 我 开炮 ! 向 我 开炮 !',
 '记者 : 你 怎么 会 说出 那 番话 ?',
 '韦昌进 : 我 只是 觉得 , 对准 我 自己 打 , 才 有 可能 把 上 了 我 哨位 的 这些 敌人 打死 , 或者 打 下去 。']
vecchin = CountVectorizer()
vecchin.fit_transform(chin).toarray()
array([[1, 0, 2, 0, 0, 1, 0, 0, 2, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0,
        0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0,
        0],
       [0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1,
        1]], dtype=int64)

step 4:TF-IDF

TF-IDF 分数由两部分组成:

第一部分是词语频率(Term Frequency)

第二部分是逆文档频率(Inverse Document Frequency)。其中计算语料库中文档总数除以含有该词语的文档数量,然后再取对数就是逆文档频率。


TF(t)= 该词语在当前文档出现的次数 / 当前文档中词语的总数

IDF(t)= log_e(文档总数 / 出现该词语的文档总数)

具体计算方式

from sklearn.feature_extraction.text import TfidfVectorizer

tfidf = TfidfVectorizer()
tfidf.fit_transform(chin).toarray()#结果3*23:三句话,23个特征
array([[0.2773501 , 0.        , 0.5547002 , 0.        , 0.        ,
        0.2773501 , 0.        , 0.        , 0.5547002 , 0.        ,
        0.        , 0.        , 0.2773501 , 0.        , 0.        ,
        0.2773501 , 0.2773501 , 0.        , 0.        , 0.        ,
        0.        , 0.        , 0.        ],
       [0.        , 0.        , 0.        , 0.        , 0.        ,
        0.        , 0.        , 0.        , 0.        , 0.5       ,
        0.        , 0.        , 0.        , 0.        , 0.5       ,
        0.        , 0.        , 0.        , 0.        , 0.5       ,
        0.5       , 0.        , 0.        ],
       [0.        , 0.28867513, 0.        , 0.28867513, 0.28867513,
        0.        , 0.28867513, 0.28867513, 0.        , 0.        ,
        0.28867513, 0.28867513, 0.        , 0.28867513, 0.        ,
        0.        , 0.        , 0.28867513, 0.28867513, 0.        ,
        0.        , 0.28867513, 0.28867513]])
tfidf.get_feature_names()
['上级',
 '下去',
 '为了',
 '只是',
 '可能',
 '呼喊',
 '哨位',
 '对准',
 '开炮',
 '怎么',
 '或者',
 '打死',
 '报话机',
 '敌人',
 '番话',
 '祖国',
 '胜利',
 '自己',
 '觉得',
 '记者',
 '说出',
 '这些',
 '韦昌进']

example&practice

1.Bags of words& RidgeClassifier
from sklearn.linear_model import RidgeClassifier
from sklearn.metrics import f1_score

Path=r"C:/Users/10539/Desktop/nlp/"
train_df = pd.read_csv(Path+'train_set.csv', sep='\t', nrows=15000)

vectorizer = CountVectorizer(ngram_range=(1,3),max_features=3000)
train_test = vectorizer.fit_transform(train_df['text'])

clf = RidgeClassifier()
clf.fit(train_test[:10000], train_df['label'].values[:10000])

val_pred = clf.predict(train_test[10000:])
print(f1_score(train_df['label'].values[10000:], val_pred, average='macro'))
0.7934314417439411
2.TF-IDF & SVM
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.svm import SVC

tfidf = TfidfVectorizer(ngram_range=(1,3), max_df=0.9,max_features=4000)
train_test = tfidf.fit_transform(train_df['text'])
clf = SVC()
clf.fit(train_test[:10000], train_df['label'].values[:10000])

val_pred = clf.predict(train_test[10000:])
print(f1_score(train_df['label'].values[10000:], val_pred))
0.875646733138943
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值