前几天为了实现文本分类,看了不少博客文章之类的,就fasttext还算稍微能看懂,代码也最终能跑得起来,但是好多博客的代码都是更新之前的了,会报错,找坑填坑一路爬出来,总算跑通了,发出来做个记录吧。
看过我博客的小伙伴应该知道我的这篇自制文本分类的骚操作
还是跟它一样,先有数据,我就不多说了。
接下来首先是先写一个文本分类处理的代码,待会儿再写一个文本分类预测的代码,我是分开运行的,你也可以自己整合,我还是继续我的半自动
我记得我看的fasttext说的好像是,它属于一种监督性学习,那么监督学习最大的特点就是数据要有标签。我们的文本分类处理代码实现的就是把你的文章咔咔咔分词之后,再给他打上标签
上代码:
# encoding=gbk
import os
import jieba
import random
import fasttext
def writeData(sentences,fileName):
out=open(fileName,'w',encoding='utf-8')
for sentence in sentences:
out.write(sentence+"\n")
def run():
#这里是循环读取文章文件,会依次到D:\新闻数据\房产,D:\新闻数据\教育,D:\新闻数据\时尚。。。。这五个文件夹下读取文章
list=['房产','教育','时尚','星座','股票']
sentences = []
for c in list:
file_dir = 'D:\新闻数据\{}'.format(str(c))
for root, dirs, files in os.walk(file_dir):
# print(root) # 当前目录路径
# print(dirs) # 当前路径下所有子目录
# print(files) # 当前路径下所有非目录子文件
for x in files:
try:
path = root+'\\' + x
print(path)
with open(path, "r+", encoding="utf-8") as f:
content = f.read().replace('\n','')
segs = jieba.lcut(str(content)) # 分词
#这里就是分词之后再整理成fasttext喜欢的格式,打上标签,分成了五种类别
#最后的文本大概像这样的:
#小明 小红 小蓝__label__人类
#苹果 橘子 香蕉__label__水果
sentences.append(" ".join(segs) + "\t" + "__label__" +'{}'.format(str(c)))
except:
pass
random.shuffle(sentences) #乱序处理 必须要
writeData(sentences, 'train_data.txt')
if __name__=='__main__':
run()
OK,这一步运行完之后,你的文件夹下就会有一个train_data.txt的文件了,里面就是格式化完成的内容了。
接下来编写文本分类预测代码了:
#encoding=gbk
import jieba
import fasttext
#下面这三句就是fasttext的骚操作了,操作完之后会生成它自己的一个模型,我们就固定写法,先会用,再理解深究
#fasttext.train_supervised这个函数里面除了放咱们的train_data.txt,还有好多其他参数,我这边没看明白作用都是什么,干脆没写,让它用默认的了。知道的小伙伴可以留言告诉我一下,互相学习嘛,万分感谢
model = fasttext.train_supervised("train_data.txt")
model.save_model("model_file.bin")
classifier = fasttext.load_model('model_file.bin')
#ok',模型也生成好了,接下来就到了紧张又有成就感的测试环节,先读取一篇咱们用来做测试的文章(你悄咪咪从某个新闻网站复制下来的一篇文章)
with open('D:\新闻数据\测试.txt', "r+", encoding="utf-8") as f:
content = f.read().replace('\n', '')
texts = ' '.join(jieba.lcut(content)) #这里我图方便 后面可以用hanlp等 提高分词准确
texts = [texts]
#接下来就可以打印结果了
#这个可以得到前k个类别,比如咱们做的分类共分为5类,我写k=5,就会把这五类以及可能性都打印出来,k=3就打印可能性最大的前三个,大于5也是打印5个,具体有没有别的什么影响,我没有试验,知道的小伙伴可以告诉我一下,万分感谢
lables=classifier.predict(texts,k=5)
print(lables)
print('*'*50)
#这个是不写k,那他默认的就打印可能性最大的那一个类别
lables=classifier.predict(texts)
print(lables)
接下来咱们看运行结果吧,为了有对照性,咱们把昨天写的那个自制文本分类骚操作也运行起来,pk一下。
这里注意,咱们待会儿复制的文章得是这两个文本分类里面都有的类型,也就是说咱们的自制文本分类训练过星座这类型的文章,这篇fasttext文本分类也训练过星座这个类型的文章,这样才公平嘛
fasttext里我训练了房产’,‘教育’,‘时尚’,‘星座’,'股票
自制文本分类里我倒是训练的多,反正fasttext里有的它都有,接下来咱们去悄咪咪的复制新闻去,然后让他俩做预测
第一局:咱们复制个房产类的文章,扔到测试.txt文件里
运行结果,自制文本分类:
表现不错,接下来看看fasttext的表现
也不错嘛,都猜出来了。
第二局:复制个教育类的
还是咱们的自制文件分类先抛砖引玉
不错不错,自制的也蛮好用的嘛,接下来看看fasttext的表现吧
六六六,人家也是丝毫不怂,战况很焦灼
第三局:这次复制时尚类的
自制文本分类先上:
完美完成任务,接下来看看fasttext的表现:
噗,哈哈哈哈,终于被我打败了,咳咳,我赢了,不玩了。
欢迎留言,欢迎指正,欢迎点赞,欢迎交流,一起学习一起浪