结巴分词关键词相似度_辨别标题党--提取关键词与比较相似度

本文介绍了如何运用结巴分词和TF-IDF算法来识别学校新闻中的标题党。首先,通过爬虫获取新闻并进行预处理,接着使用TF-IDF算法提取关键词,再训练相似度模型,最后计算标题与关键词的相似度以判断标题党行为。
摘要由CSDN通过智能技术生成

最近好几天都没有更新博客,因为网络设置崩了,然后各种扎心,最后还重装电脑,而且还有一些软件需要重新安装或者配置,所以烦了好久,搞好电脑之后,老师又布置了一个任务,个人觉得很有趣--判别学校新闻是否是标题党

虽然我不觉得老师的方法能够很好地判别标题党行为,但是也只能开干了!

第一步:通过爬虫获取学校新闻,这一部分已经在之前的文章中写过,所以不在重复了,有点不同的是,因为从文本中提取内容列会出错,有少数文章的内容没有被全部提取,所以我在源代码的基础上改变了一下,生成了一个只存放内容的文件content.csv

第二步:(1)对文档内容进行分词,并且按照文档数分别存放在不同的文档,例如3454篇新闻就用3454份文档来存放分词后的内容,但是是可以直接用一个文档来存放的,每篇文章只在文档中占一行就行,分词用结巴,不要用全模式,否则后面选择的关键词会有很多相同,另外下载百度停用词表,在停用词表中的词语就不要写入文件中,因为不能成为关键词,如是、的、好

(2)使用TF-IDF算法进行关键词提取,首先套一个循环,循环3454个文档,然后按行读取,之后各种烧脑。举个例子:在文档A中,有100个分词后的词语,通过集合去掉重复的之后还剩下80个,把这80个加到字典中,并且要计算这80个词语在文档A中各自出现的次数;然后轮到文档B,首先判断文档B中的分词词语有哪些在字典中,在字典中的话就不加进字典,但是值VALUES加1,否则加入字典。这个太难说清楚了,还是自己去看看详细介绍吧!

(3)根据TF-IDF算法得到每篇新闻权值前三的词语,并且写入文件中

第三步:(1)训练相似度模型:这是个很陌生的知识,但是用了工具就很简单了,原理就是存储许多词语,把他们分为向量,就像网络一样连在一起,把距离的远近作为词语之间的相似度,缺点就在于无法识别不在模型中的词语相似度。可以去看看这两个链接,非常详细:https://blog.csdn.net/kaoyala/article/details/79090156;https://github.com/jsksxs360/Word2Vec

(2)把模型训练好了之后就简单了,把标题从新闻中提取出来,然后进行全模式分词,对于第一个关键词,与分词后的标题逐个计算相似度,取最大相似度,然后再到第二个关键词,最后把结果写入文件中

下面附上源码:

import jieba

import math

import re

def word():

#第一步:文档预处理:读取文档 -> 删除不需要的字符(如回车符\n、制表符\t、空格等)

# -> 转换成unicode格式 -> 对文档分词 -> 转换成utf-8格式写入txt文档

#读取文档

#由于使用TF-IDF方法提取关键词,而且需要分析题目相似度,所以每篇文章生成一个文档!

with open('content.csv', 'r', newline='', encoding='utf-8')as col:

j = 1

for i in col.readlines():

content=jieba.cut(i,cut_all=False) #结巴分词精确模式

result=" ".join(content) #把generator转换为字符串类型

result=re.compile('[\u4e00-\u9fa5]+').findall(result)

# 转换为列表并且去掉了那些数字3,4英文之类的

list1=[] #存储去掉空格之后的列表

#导入停用词表,并进行简单清洗

list111 = [] #存储停用词表

with open('baidustop.txt', 'r', encoding='utf-8')as f:

for i in f.readlines():

i = i.strip() #去掉换行符

list111.append(i)

for i in result:

if len(i)<=1 : #如果是空格或者单个字就去掉不要

continue

elif i in list111: #如果在停用词表里面就不要

continue

else:

list1.append(i)

# 把分词结果写入TXT文档中

with open('txt/TF-IDF'+str(j)+'.txt','a',encoding='utf-8')as file:

for word in list1:

file.write(word+'\n')

j+=1 #为了文档名字

def language():

#第二步:使用TF-IDF算法进行关键词提取

dict2={} #存放语料库,统计一个单词在多少个文件中存在

for i in range(1,3455):

with open('txt/TF-IDF' + str(i) + '.txt', 'r', encoding='utf-8')as file:

list2=[]

for wd in file.readlines(): #按行读取

wd=wd.replace('\n','') #去掉换行符

list2.append(wd)

#制作语料库字典,为了求解IDF

set1=set(list2) #转换为集合!

for word in set1:

dict2[word]=dict2.get(word,0)+1 #一个文档中每个单词最多只能增加1 !

with open('language.txt','a',encoding='utf-8')as f:

for j,k in zip(dict2.keys(),dict2.values()):

f.write(j+':')

f.write(str(k))

f.write('\n')

def TfIdf():

dict3={} #存放语料库中的键值对,生成该字典是为了进行索引

for line in open('language.txt','r+',encoding='utf-8'):

(key, value) = line.strip('\n').split(':') #换行符是用strip去除的,然后通过区分冒号来区分键值

dict3[key] = str(value) #把对应的键值对存放进dict3字典中

# 根据dict3求解IDF

for q in dict3.keys():

dict3[q] = math.log(3455 / (int(dict3[q]) + 1), 10) # 10是底

for j in range(1,3455): #所有文档各自遍历一遍

count = {} #存放每次文档的单词和次数

sumdict={} #用来存放TF-IDF算法后的结果

with open('txt/TF-IDF' + str(j) + '.txt', 'r', encoding='utf-8')as file:

for wd in file.readlines(): #按行读取

# 求解单词频率,为了TF

wd=wd.replace('\n','') #去掉换行符

count[wd]=count.get(wd,0)+1 #统计在本文档中该单词出现的次数

for k in count.keys():

sumdict[k] = count[k] / sum(count.values()) # TF表示词条在文档中出现的频率

sumdict[k]=sumdict[k]*dict3[k] #此处用sumdict存放TF-IDF值

data=[] #存储三个最大值

with open('TF-IDF.txt', 'a', encoding='utf-8')as f:

for i in range(3):

data.append(max(sumdict,key=lambda x:sumdict[x])) #根据字典的值查找最大值

f.write(max(sumdict,key=sumdict.get)) #写入文件中

f.write(' ') #用逗号来分割三个关键字

sumdict.pop(max(sumdict,key=sumdict.get)) #删除最大值

f.write('\n')

if __name__=='__main__':

word()

language()

TfIdf()

from gensim.corpora import WikiCorpus

import jieba

import codecs

from gensim.models import Word2Vec

from gensim.models.word2vec import LineSentence

import multiprocessing

'''

读取中文wiki语料库,并解析提取xml中的内容

'''

#将下载的语料转为文本txt格式

def dataprocess():

space = " "

i = 0

output = open('E:\wiki\chinawiki-articles.txt', 'w', encoding='utf-8')

wiki = WikiCorpus('E:\wiki\zhwiki-latest-pages-articles.xml.bz2', lemmatize=False, dictionary={})

for text in wiki.get_texts():

output.write(space.join(text) + "\n") #分割一个词之后换行

i = i + 1

if (i % 10000 == 0): #每一万文章就提示一下

print('Saved ' + str(i) + ' articles')

output.close()

print('Finished Saved ' + str(i) + ' articles')

'''

加载停用词表

'''

def createstoplist(stoppath):

print('load stopwords...')

stoplist = [line.strip() for line in codecs.open(stoppath, 'r', encoding='utf-8').readlines()]

#fromkeys用于创建一个新字典,以序列seq中元素做字典的键,value为字典所有键对应的初始值

stopwords = {}.fromkeys(stoplist) #值默认为None

return stopwords

'''

过滤英文

'''

def isAlpha(word):

try: #isalpha() 方法检测字符串是否只由字母组成。

return word.encode('ascii').isalpha()

except UnicodeEncodeError:

return False

def trans_seg():

stopwords = createstoplist(r'E:\wiki\baidustop.txt')

i = 0

with codecs.open('E:\wiki\seg\chinawiki-segment40.txt', 'w', 'utf-8') as wopen:

print('开始...')

with codecs.open('E:\wiki\zhUTF8\chinawiki-articles-jian.txt', 'r', 'utf-8') as ropen:

for line in ropen.readlines():

line = line.strip() #去掉空格

i += 1

print('line ' + str(i)) #第几行

text = ''

for char in line.split(): #对每行进行列表分割

if isAlpha(char): #如果是英文就不要

continue

text += char #空格加词语

# print(text)

words = jieba.cut(text) #默认模式分词

seg = ''

for word in words:

if word not in stopwords: #如果在停用词表就不用这个词

if len(word) > 1 and isAlpha(word) == False: # 去掉长度小于1的词和英文

if word != '\t': #空格

seg += word + ' '

wopen.write(seg + '\n')

print('结束!')

'''

利用gensim中的word2vec训练词向量

'''

def word2vec():

print('Start...')

rawdata='E:\wiki\seg\chinawiki-segment40.txt'

modelpath='E:\wiki\model\chinawikimodel.model'

#vectorpath='E:\word2vec\vector'

model=Word2Vec(LineSentence(rawdata),size=400,window=5,min_count=5,workers=multiprocessing.cpu_count())#参数说明,gensim函数库的Word2Vec的参数说明

model.save(modelpath)

#model.wv.save_word2vec_format(vectorpath,binary=False)

print("Finished!")

if __name__=='__main__':

# dataprocess()

# trans_seg()

# word2vec()

model= Word2Vec.load('E:\wiki\model\chinawikimodel.model')

# print(model.most_similar('开心',topn=5))

try:

pro=model.similarity('开心', '不存在')

except:

pro=0

print(pro)

'''

计算关键词与题目相似度的流程:加载题目文件与关键词文件--》把题目进行分词--》把分词后的结果保存

--》把关键词与分词题目词语逐一比较相似度取最大值--》每篇文章得到三个相似度(三个关键词)

前期准备:jieba分词、wiki中文语料、word2vec模型训练、词向量比较相似度

标题文档:fosu1中提取,关键词文档:TF-IDF.txt中提取,皆是3454行

'''

import csv

import jieba

from gensim.models import Word2Vec

import re

#加载词语模型,用来输出词语相似度

model= Word2Vec.load('E:\wiki\model\chinawikimodel.model')

list1=[] #存储分词后的标题

list2=[] #存储关键词

list3=[] #存储相似度

#用with同时打开两个文件

with open('fosu1.csv','r',newline='',encoding='utf-8')as file1,open('TF-IDF.txt','r',encoding='utf-8')as file2:

read1 = csv.reader(file1) # 读取文件

title = [row[0] for row in read1] # 获取标题

for i in title:

i = jieba.cut(i, cut_all=False) #全模式识别名字的效果很差

#虽然使用精确模式有所改变,但是很多名字都不在模型中,所以没法识别,返回错误

tit = ",".join(i)

tit=re.compile('[\u4e00-\u9fa5]+').findall(tit) #只取中文

list1.append(tit)

for j in file2.readlines():

j=j.strip()

j=j.split(' ')

list2.append(j) #关键词

file3=open('similarity.txt','a',encoding='utf-8')

n=0 #第几个标题

for p,q in zip(list1,list2):

word=" ".join(q)

file3.write(title[n] + ':')

file3.write(word+'|')

for w in range(3):

pro=[] #暂时存储一个关键词与其他标题分词的相似度

for i in p:

try: #关键词与他们逐一比较相似度

pro.append(model.similarity(i,q[w]))

except: #有些词语不在模型词典中,会报错

if i==q[w]: #如果词语不在模型中,但是标题中有相同的词语,那么就把相似度设为1.0

pro.append(1.0)

else: #否则为0.0

pro.append(0.0)

pro=float('%.2f'%max(pro)) #取相似度最大的为关键词与标题的相似度

file3.write(str(pro)+' ')

file3.write('\n')

n+=1 #标题+1

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值