统计文本词频的几种方法(Python)_词频统计-程序员宅基地

技术标签: 计算机等级二级Python  python  人工智能  大数据  开发语言  

目录

1. 单句的词频统计

2. 文章的词频统计

方法一:运用集合去重方法

方法二:运用字典统计

方法三:使用计数器


词频统计是自然语言处理的基本任务,针对一段句子、一篇文章或一组文章,统计文章中每个单词出现的次数,在此基础上发现文章的主题词、热词。

1. 单句的词频统计

思路:首先定义一个空字典my_dict,然后遍历文章(或句子),针对每个单词判断是否在字典my_dictkey中,不存在就将该单词当作my_dictkey,并设置对应的value值为1;若已存在,则将对应的value值+1。

#统计单句中每个单词出现的次数
news = "Xi, also general secretary of the Communist Party of China (CPC) Central Committee and chairman of the Central Military Commission, made the remarks while attending a voluntary tree-planting activity in the Chinese capital's southern district of Daxing."    
def couWord(news_list): 
    ##定义计数函数  输入:句子的单词列表 输出:单词-次数 的字典
    my_dict = {}  #空字典 来保存单词出现的次数
    for v in news_list:
        if my_dict.get(v):
            my_dict[v] += 1
        else:
            my_dict[v] = 1
    return my_dict

print(couWord(news.split ()))

输出

{‘Xi,’: 1, ‘also’: 1, ‘general’: 1, ‘secretary’: 1, ‘of’: 4, ‘the’: 4, ‘Communist’: 1, ‘Party’: 1, ‘China’: 1, ‘(CPC)’: 1, ‘Central’: 2, ‘Committee’: 1, ‘and’: 1, ‘chairman’: 1, ‘Military’: 1, ‘Commission,’: 1, ‘made’: 1, ‘remarks’: 1, ‘while’: 1, ‘attending’: 1, ‘a’: 1, ‘voluntary’: 1, ‘tree-planting’: 1, ‘activity’: 1, ‘in’: 1, ‘Chinese’: 1, “capital’s”: 1, ‘southern’: 1, ‘district’: 1, ‘Daxing.’: 1}

以上通过couWord方法实现了词频的统计,但是存在以下两个问题。

(1)未去除stopword

输出结果中保护’also’、‘and’、'in’等stopword(停止词),停止词语与文章主题关系不大,需要在词频统计等各类处理中将其过滤掉。

(2)未根据出现次数进行排序

根据每个单词出现次数进行排序后,可以直观而有效的发现文章主题词或热词。

改进后的couWord函数如下:

def couWord(news_list,word_list,N):
    #输入 文章单词的列表 停止词列表  输出:Top N的单词
    my_dict = {}  #空字典 来保存单词出现的次数
    for v in news_list:
        if (v not in word_list): # 判断是否在停止词列表中
            if my_dict.get(v):
                my_dict[v] += 1
            else:
                my_dict[v] = 1
                  
    topWord = sorted(zip(my_dict.values(),my_dict.keys()),reverse=True)[:N] 
    
    return topWord

加载英文停止词列表:

stopPath = r'Data/stopword.txt'
with open(stopPath,encoding = 'utf-8') as file:
    word_list = file.read().split()      #通过read()返回一个字符串函数,再将其转换成列表

print(couWord(news.split(),word_list,5)) 

输出

[(2, ‘Central’), (1, ‘voluntary’), (1, ‘tree-planting’), (1, ‘southern’), (1, ‘secretary’)]

2. 文章的词频统计

(1)单篇文章词频统计

通过定义读取文章的函数,对其进行大小写转换等处理,形成输入文章的单词列表。

https://python123.io/resources/pye/hamlet.txt

以上为hamlet英文版文本的获取路径,下载完成后保存到工程路径下。

使用open()函数打开hamlet.txt文件,并使用read()方法读取文件内容,将文本保存在txt变量中。

def readFile(filePath): 
    #输入: 文件路径  输出:字符串列表
    with open(filePath,encoding = 'utf-8') as file:
        txt = file.read().lower() #返回一个字符串,都是小写
        words = txt.split()      #转换成列表 
    
    return words

filePath = r'Data/news/hamlet.txt'
new_list = readFile(filePath)  #读取文件
print(couWord(new_list,word_list,5))

接下来,我们需要对文本进行预处理,去除标点符号、分割成单词等。我们可以使用正则表达式来实现这一步骤。

import re

# 去除标点符号
text = re.sub(r'[^\w\s]', '', text)

# 分割成单词
words = text.split()

我们使用re.sub()函数和正则表达式[^\w\s]来去除标点符号,然后使用split()方法将文本分割成单词,并将结果保存在words列表中。

或者:

我们的文本中含有标点和字符的噪声数据,所以要进行数据的清洗,将文档全部处理为只有我们需要的字母类型(为方便操作,用空格替换噪声数据,将文档全部转化为小写字母)

打开文件,进行读取,清洗数据,数据归档。

def getText():
    txt = open("Hmlet.txt","r").read()
    txt = txt.lower()
    for ch in '!@#$%^&*()_/*-~':
        txt = txt.replace(ch," ")
    return txt


hamlet = getText()
words = hamlet.split()
counts = {}
for word in words:
    counts[word] = counts.get(word,0) + 1

items = list(counts.items())
items.sort(key= lambda x:x[1],reverse=True)
for i in range(10):
    word, count = items[i]
    print("{0:<10}{1:>5}".format(word,count))

现在,我们已经得到了分割后的单词列表words,接下来我们需要统计每个单词出现的次数。我们可以使用Python的字典数据结构来实现词频统计。

word_counts = {}

for word in words:
    if word in word_counts:
        word_counts[word] += 1
    else:
        word_counts[word] = 1

这段代码中,我们首先创建一个空字典word_counts,然后遍历words列表中的每个单词。对于每个单词,如果它已经在word_counts字典中存在,则将对应的计数值加1;否则,在字典中新增一个键值对,键为单词,值为1。

在统计完词频后,我们需要按照词频降序排序,以便后续输出结果。我们可以使用Python的内置函数sorted()来实现排序。

sorted_word_counts = sorted(word_counts.items(), key=lambda x: x[1], reverse=True)

我们使用word_counts.items()方法获取word_counts字典中的所有键值对,并使用key=lambda x: x[1]指定按照键值对中的值进行排序,reverse=True表示降序排列。排序结果将保存在sorted_word_counts列表中。

最后,我们将词频统计结果输出到控制台或文件中。

for word, count in sorted_word_counts:
    print(f'{word}: {count}')

这段代码中,我们使用for循环遍历sorted_word_counts列表中的每个元素(每个元素是一个键值对),并使用print()函数输出单词和对应的词频。

(2)多篇文章词频统计

需要使用os.listdir方法读取文件夹下的文件列表,然后对文件逐一进行处理。

import os 
folderPath = r'Data/news' #文件夹路径
tmpFile = os.listdir(folderPath)
allNews = []
for file in tmpFile:  #读取文件
    newsfile = folderPath + '//' + file #拼接完整的文件路径  \\ 转义字符
    allNews += readFile(newsfile)   #把所有的字符串列表拼接到allText中
    
print(couWord(allNews,word_list,5))  

输出

[(465, ‘china’), (323, ‘chinese’), (227, ‘xi’), (196, “china’s”), (134, ‘global’)]

(3)中文文章的处理

对于中文文章的词频统计,首先要使用jieba等分词器对文章进行分词,并且加载中文的停止词列表,再进行词频统计。

3.三国演义人物出场频数

利用jieba库,进行中文分词,将其存入列表words中,遍历,将词组和词频作为键值对存入列表counts中,利用列表的有序性,进行排序,然后输出

https://python123.io/resources/pye/threekingdoms.txt

以上为三国演义中文版文本获取链接,下载后保存到工程路径下

import jieba
txt = open("threekingdoms.txt","r",encoding="utf-8").read()
counts = {}
words = jieba.lcut(txt)
for word in words:
    if len(word) == 1:
        continue
    else:
        counts[word] = counts.get(word,0) + 1
items = list(counts.items())
items.sort(key = lambda x:x[1] , reverse=True)
for i in range(15):
    word , count = items[i]
    print("{0:<10}{1:>5}".format(word,count))

该方法比英文哈姆雷特词频简单,不用去处理字符类噪声数据,这也得益于jieba库的简易操作。

但随之带来的是词频的模糊,因为jieba库的特性,导致不是人名的词组也被统计了进来。

如结果中的“二人”、”孔明曰“,这些都是冗余和词组问题的错误。

所以我们应该还需要进行进一步的处理,让词频统计人物的名字次数

经过前几步的操作,我们输出了出现频率最高的15给词组,可我们如果想要人物的出场频率呢? 这就需要对原文件进行过滤,把我们不需要的输出删除。

因为之前的输出可以简单的获取到出现频率高但不是人名的词组,所以我们这里把它们储存到一个集合中,遍历并删除原文件中存在的这些词组。

excludes = {"将军","却说","二人","不可","荆州","不能","如此","商议","如何","主公","军士","左右","军马"}
for i in excludes:
    del counts[i]

冗余处理:把出现频率高的相同人物别名进行统一

 elif word == "诸葛亮" or word == "孔明曰":
        rword = "孔明"
    elif word == "关公" or word == "云长":
        rword = "关羽"
    elif word == "玄德" or word == "玄德曰":
        rword = "刘备"
    elif word == "孟德" or word ==  "丞相":
        rword = "曹操"

 反复的经过这些处理,我们可以得到我们想要的输出

import jieba
txt = open("threekingdoms.txt","r",encoding="utf-8").read()
counts = {}
excludes = {"将军","却说","二人","不可","荆州","不能","如此","商议","如何","主公","军士","左右","军马"}
words = jieba.lcut(txt)
for word in words:
    if len(word) == 1:
        continue
    elif word == "诸葛亮" or word == "孔明曰":
        rword = "孔明"
    elif word == "关公" or word == "云长":
        rword = "关羽"
    elif word == "玄德" or word == "玄德曰":
        rword = "刘备"
    elif word == "孟德" or word ==  "丞相":
        rword = "曹操"
    else:
        rword = word
    counts[rword] = counts.get(rword,0) + 1
for i in excludes:
    del counts[i]
items = list(counts.items())
items.sort(key = lambda x:x[1] , reverse=True)
for i in range(7):
    word,count = items[i]
    print("{0:<10}{1:>5}".format(word,count))

 

方法一:运用集合去重方法

1

2

3

4

5

6

7

8

9

def word_count1(words,n):

   word_list = []

   for word in set(words):

       num = words.counts(word)

       word_list.append([word,num])

       word_list.sort(key=lambda x:x[1], reverse=True)

   for i in range(n):

       word, count = word_list[i]

       print('{0:<15}{1:>5}'.format(word, count))

说明:运用集合对文本字符串列表去重,这样统计词汇不会重复,运用列表的counts方法统计频数,将每个词汇和其出现的次数打包成一个列表加入到word_list中,运用列表的sort方法排序,大功告成。

方法二:运用字典统计

1

2

3

4

5

6

7

8

9

10

11

12

def word_count2(words,n):

    counts = {}

    for word in words:

        if len(word) == 1:

            continue

        else:

            counts[word] = counts.get(word, 0) + 1

    items = list(counts.items())

    items.sort(key=lambda x:x[1], reverse=True)

    for i in range(n):

        word, count = items[i]

        print("{0:<15}{1:>5}".format(word, count))

方法三:使用计数器

1

2

3

4

5

6

7

def word_count3(words,n):

    from collections import Counter

    counts = Counter(words)

    for ch in "":  # 删除一些不需要统计的元素

        del counts[ch]

    for word, count in counts.most_common(n):  # 已经按数量大小排好了

        print("{0:<15}{1:>5}".format(word, count))

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/greatau/article/details/134044945

智能推荐

vscode新手注意事项(字体间隔,报错提示波浪线,头文件路径,opencv头文件路径)_vscode 插件里间距错误提醒是哪个-程序员宅基地

文章浏览阅读787次。vscode新手注意事项(字体间隔,报错提示波浪线,头文件路径,opencv头文件路径)一.字体空格刚安装vscode,不设置字体的话,字体间的间隔会很难受,需要进行如下配置。在 设置->首选项 选择 文本编辑器->字体 ,将“FONT Family ”选项修改成如下。Consolas,Consolas,monospace,Consolas二.报错提示波浪线vscode对代码进行错误提示,进行如下配置。(1)在设置->首选项 搜索errorsquiggles._vscode 插件里间距错误提醒是哪个

云服务器上划虚拟主机,云服务器上划虚拟主机-程序员宅基地

文章浏览阅读171次。云服务器上划虚拟主机 内容精选换一换您可以为需要容灾的云服务器在指定的保护组下创建保护实例。在当前的生产站点遇到不可抗力导致大规模服务器故障时,您可以调用保护组的操作接口进行故障切换,从而确保保护实例上运行的业务正常连续。为每一个需要复制的服务器挑选一个保护组,并创建一个保护实例。创建保护实例过程中,会在保护组的容灾站点创建对应的服务器和磁盘,服务器规格可根据需要进行选择,运行在专属主机和普通EC...

微型计算机故障分为哪几类,西南大学19秋[0240] 计算机维修技术在线作业-程序员宅基地

文章浏览阅读2.3k次。0240 计算机维修技术- M7 T, _$ E0 ef4 E1.[单选题]评定主板的性能首先要看()。. a4 k, f/ F% N0 C/ o4 d奥鹏作业答案可以联系QQ 7612960214 d' d: qk, l( H$ kA.C.CPU6 |, q" c! V# q1 R- i& eB.内存- z) K* M3 P: H2 {/ R0 bC.主板结构' n1 E2 ..._微型计算机常见有哪些故关型?并举例说明灰尘对微机设备会产生哪些故障关型与危害

vt-x vt-d vt-c_宏碁笔记本的vtx和vtd-程序员宅基地

文章浏览阅读4.5k次。Intel VT技术,主要由三部分技术组成:VTx、VTd和VTc。其中,VTx是处理器技术,提供内存以及虚拟机的硬件隔离,所涉及的技术有页表管理以及地址空间的保护。VTd是处理有关芯片组的技术,它提供一些针对虚拟机的特殊应用,如支持某些特定的虚拟机应用跨过处理器I/O管理程序,直接调用I/O资源,从而提高效率,通过直接连接I/O带来近乎完美的I/O性能。VTc是针对网络提供的管理,它可以在一个物_宏碁笔记本的vtx和vtd

git 常用命令_git 强制更新-程序员宅基地

文章浏览阅读6.8k次。目前由于项目需要,了解了一些基本的git命令1、首先是GIt强制pull ; git强制更新 git fetch --all git reset --hard origin/master git pull2、ubuntu系统有多个git账号,如何同时正常使用两个账号由于自己的git账号和目前公司的账号不一致,因此有此需求首先是切换到~/.ssh/目录下,执行下面命令:在此目录下新建config :touch config执行命令:v..._git 强制更新

python封装接口用于调用_python接口自动化(三十五)-封装与调用--流程类接口关联(详解)...-程序员宅基地

文章浏览阅读84次。简介流程相关的接口,主要用 session 关联,如果写成函数(如上篇),s 参数每个函数都要带,每个函数多个参数,这时候封装成类会更方便。在这里我们还是以博客园为例,带着小伙伴们实践一下。接口封装大致流程1、在接口测试中,有些接口经常会被用到比如登录的接口,这时候我们可以每个接口都封装成一个方法,如:登录、保存草稿、发布随笔、删除随笔,这四个接口就可以写成四个方法2、接口封装好了后,后面我们写用..._pycharm接口自动化需封装接口内容

随便推点

android开发面试题_csdn android 移动软件开发 面试题-程序员宅基地

文章浏览阅读2.1k次。打包下载: Android面试题带答案.doc(108.5 KB, 下载次数: 2126) 2012-1-11 11:20 上传点击文件名下载附件 下载积分: 下载豆 -1 Android面试题1. 下列哪些语句关于内存回收的说明是正确的? (b ) A、 程序员必须创建一个线程来释放内存 B、 内存回收程序负责释放无用内_csdn android 移动软件开发 面试题

前端和后端的区别?-程序员宅基地

文章浏览阅读10w+次,点赞105次,收藏254次。有的人认为,前端很好学,后端不好学。也有的人认为,前端不好学,后端好学,归根到底还得看个人兴趣。前端和后端做简单的叙述后端:入门难,深入更难,枯燥乏味,没有太大成就感,看一堆业务逻辑代码。前端:入门简单,先易后难,能看到自己做出来的展示界面,有成就感。前端和后端两者工作的内容和负责的东西是完全的不同01展示的方式不同前端指的是用户..._后端

Python学习记录_python专业学习记录-程序员宅基地

文章浏览阅读115次。Python学习记录_python专业学习记录

pix2pix 与 pix2pixHD的大致分析_patchgan pix2pix改进-程序员宅基地

文章浏览阅读1.9w次,点赞6次,收藏45次。图像翻译,指从一副图像到另一副图像的转换。可以类比机器翻译,一种语言转换为另一种语言。下图就是一些典型的图像翻译任务:比如语义分割图转换为真实街景图,灰色图转换为彩色图,白天转换为黑夜......本文主要介绍图像翻译的三个比较经典的模型pix2pix,pix2pixHD, vid2vid。pix2pix提出了一个统一的框架解决了各类图像翻译问题, pix2pixHD则在pix2pix的基础上,较好的解决了高分辨率图像转换(翻译)的问题, vid2vid则在pix2pixHD的基础上,较好的_patchgan pix2pix改进

SpringBoot与Spring的对比_springboot比spring做了什么改进-程序员宅基地

文章浏览阅读9k次,点赞2次,收藏7次。一、原有Spring优缺点分析1.Spring的优点分析Spring是Java企业版(Java Enterprise Edition,JEE,也称J2EE)的轻量级代替品。无需开发重量级的EnterpriseJavaBean(EJB),Spring为企业级Java开发提供了一种相对简单的方法,通过依赖注入和面向切面编程,用简单的Java对象(Plain Old Java Object,POJO)实现了EJB的功能。2.Spring的缺点分析虽然Spring的组件代码是轻量级的,但它的配置却是重量_springboot比spring做了什么改进

(20200720已解决)_pickle.UnpicklingError: A load persistent id instruction was encountered,-程序员宅基地

文章浏览阅读1.8w次,点赞3次,收藏18次。but no persistent_load function was specified.问题描述如题,提取pickle数据解决方案直接解释是因为生成pickle文件的过程中使用了persistent_load,但是读取过程中没有提供。本例中的具体原因是,读取的pickle文件并非pickle格式,只是用pickle这个词表示这是一个规范压缩的数据文件,改用合适的read_*()函数就可以了...__pickle.unpicklingerror: a load persistent id instruction was encountered, b

推荐文章

热门文章

相关标签