train_text
=
pd
.
read_table
(
"data/新闻标题文本分类/4分类_72000/train_4_72000.txt"
,
header
=
None
,
sep
=
" "
)
test_text
=
pd
.
read_table
(
"data/新闻标题文本分类/4分类_72000/test_4_4000.txt"
,
header
=
None
,
sep
=
" "
)
print
(
train_text
.
head
(
5
)
)
print
(
"*"
*
50
)
print
(
test_text
.
head
(
5
)
)
本次演示使用的是4分类的数据集。运行上面代码,得到下面的输出:
0
中华女子学院:本科层次仅
1
专业招男生
3
1
卡佩罗:告诉你德国脚生猛的原因 不希望英德战踢点球
7
2
《赤壁OL》攻城战诸侯战硝烟又起
8
3
上海
2010
上半年四六级考试报名
4
月
8
日前完成
3
4
李永波称李宗伟难阻林丹取胜 透露谢杏芳有望出战
7
**
**
**
**
**
**
**
**
**
**
**
**
**
**
**
**
**
**
**
**
**
**
**
**
**
0
词汇阅读是关键
08
年考研暑期英语复习全指南
3
1
中国人民公安大学
2012
年硕士研究生目录及书目
3
2
日本地震:金吉列关注在日学子系列报道
3
3
名师辅导:
2012
考研英语虚拟语气三种用法
3
4
自考经验谈:自考生毕业论文选题技巧
3
可以看到数据集主要由两部分组成,前面部分是新闻标题文本,后面部分是类别标签。
使用pandas加载后train_text[0]和test_text[0]代表的就是新闻标题文本,train_text[1]和test_text[1]代表的是类别标签。
使用
jieba
对新闻标题文本分词。jieba一共提供了四种分词模式,默认使用的是精确模式,效果还不错。此外,jieba还提供了paddle模式的分词,我自己使用下来的效果是和精确模式差不多。(不过paddle模式的分词感觉确实要比精确模式好一点的。)
import jieba
def new_cut(text):
return " ".join(list(jieba.cut(train_text)))
train_text["分词结果"] = train_text[0].map(new_cut)
test_text["分词结果"] = test_text[0].map(new_cut)
print(train_text["分词结果"].head(5))
分词结果:
0 中华 女子 学院 : 本科 层次 仅 1 专业 招 男生
1 卡佩罗 : 告诉 你 德国 脚 生猛 的 原因 不 希望 英德 战 踢 点球
2 《 赤壁 OL 》 攻城战 诸侯 战 硝烟 又 起
3 上海 2010 上半年 四六级 考试 报名 4 月 8 日前 完成
4 李永波 称 李宗伟 难 阻林丹 取胜 透露 谢杏芳 有望 出战
本次使用的停用词表是哈工大停用词表,点我下载
def get_custom_stopwords(stop_words_file):
with open(stop_words_file, encoding="gbk") as f:
stopwords = f.read()
stopwords_list = stopwords.split('\n')
custom_stopwords_list = [i for i in stopwords_list]
return custom_stopwords_list
stop_words_file = "stopwords.txt"
stopwords = get_custom_stopwords(stop_words_file)
具体TfidfVectorizer的配置参数可以去参考[官方文档](sklearn.feature_extraction.text.TfidfVectorizer — scikit-learn 1.2.2 documentation),或者其他的博客。
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf_vectorizer = TfidfVectorizer(max_df=0.8,
min_df=3,
token_pattern=u'(?u)\\b[^\\d\\W]\\w+\\b',
stop_words=frozenset(stopwords),
train_weight = tfidf_vectorizer.fit_transform(train_text["分词结果"])
test_weight = tfidf_vectorizer.transform(test_text["分词结果"])
print("train:\n", f"数据集大小:{train_weight.toarray().shape[0]} 提取特征数量:{train_weight.toarray().shape[1]}")
print("test:\n", f"数据集大小:{test_weight.toarray().shape[0]} 提取特征数量:{test_weight.toarray().shape[1]}")
输出结果:
train:
数据集大小:72000 提取特征数量:20677
test:
数据集大小:4000 提取特征数量:20677
KNN分类器的K值(n_neighbors参数)取3,距离计算方式(metric参数)选择余弦距离,其他的参数默认就行。
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score, recall_score, f1_score, precision_score
import pickle
save_model = False
k = 3
knn = KNeighborsClassifier(n_neighbors=k, metric="cosine")
knn.fit(train_weight, train_text[1])
test_pred = knn.predict(test_weight)
accuracy = accuracy_score(test_pred, test_text[1])
recall = recall_score(test_pred, test_text[1], average='macro')
precision = precision_score(test_pred, test_text[1], average='macro')
f1 = f1_score(test_pred, test_text[1], average='macro')
with open("output_logs/knn_cls.txt", "a+") as log_txt:
log_txt.write(f"k = {k}\n")
log_txt.write(f"accuracy = {accuracy}\n")
log_txt.write(f"recall = {recall}\n")
log_txt.write(f"precision = {precision}\n")
log_txt.write(f"f1 = {f1}\n")
log_txt.close()
if save_model:
with open(f"output_models/knn_{k}.pkl", "wb") as f:
pickle.dump(knn, f)
print("Save model sucess!")
结果日志输出:
k = 3
accuracy = 0.8945
recall = 0.9015750424563225
precision = 0.8945
f1 = 0.8939859931730288
现在的模型分类效果可以在调调参数,比如把k值调大一点等。
CSDN下载(只需1积分)
蓝奏云下载
# encoding=utf-8
from sklearn.feature_extraction.text import TfidfVectorizer, TfidfTransformer
corpus = [
'This This is the first document.',
'This This is the second second document.',
K-近邻算法,简称KNN(k-Nearest Neighbor),是一个相当简单的分类/预测算法。其主要思想就是,选取与待分类/预测数据的最相似的K个训练数据,通过对这K个数据的结果或者分类标号取平均、取众数等方法得到待分类/预测数据的结果或者分类标号。
关于KNN,笔者在浅入浅出:K近邻算
2.1 代码
from sklearn.datasets import fetch_20newsgroups
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
def bayesian_demo():
1. 首先对文本进行分词,去除停用词等预处理操作;
2. 采用TF-IDF算法计算文本中每个词的权重,TF-IDF的公式为:TF-IDF(w,d)=TF(w,d)×IDF(w),其中TF(w,d)表示词w在文档d中的出现次数,IDF(w)表示词w的逆文档频率,其公式为:IDF(w)=log(N/n),其中N表示总文档数,n表示包含词w的文档数;
3. 将每个文本表示成一个向量,向量的每个维度对应一个词,其值为该词的TF-IDF权重;
4. 对所有文本向量进行归一化处理,使其模长为1;
5. 选取一个合适的K值,对于未分类的文本,计算其与所有已分类文本向量的距离,并选取距离最近的K个已分类文本向量;
6. 根据K个最近邻文本的分类标签,采取多数表决的方式确定未分类文本的分类标签。
需要注意的是,TF-IDF+KNN算法对于文本分类的效果受到许多因素的影响,如文本预处理、特征选择、K值的选择等。在实际应用中,需要根据具体情况进行优化和调参。