作业 4:词频统计——基本功能

一、基本信息

  1.1 本次作业地址:https://edu.cnblogs.com/campus/ntu/Embedded_Application/homework/2088

  1.2 项目的Git地址:https://gitee.com/ntucs/PairProg

二、项目分析

  2.1 程序运行模块(方法、函数)介绍

  ①任务一:读取文件、统计行数写入result.txt方法

 1 def process_file(dst):     # 读文件到缓冲区
 2     sum_info = {}
 3     try:     # 打开文件
 4         f = open(dst, "r")
 5     except IOError  as e:
 6         print (e)
 7         return None
 8     try:     # 读文件到缓冲区
 9         # 统计行数
10         lines = len(f.readlines())
11         sum_info["file_row_count"] = lines
12         f.close()  # 关闭文件
13         #重新打开文件
14         f = open(dst, "r")
15         bvffer = f.read()
16     except:
17         print ("Read File Error!")
18         return None
19     f.close() #关闭文件
20     sum_info["bvffer"] = bvffer
21     return sum_info

 

  ②任务一:使用正则表达式统计词频,存放如字典模块

 

 1 def process_buffer(bvffer):
 2     if bvffer:
 3         word_freq = {}
 4         # 下面添加处理缓冲区 bvffer代码,统计每个单词的频率,存放在字典word_freq
 5         #文本字符串前期处理
 6         strl_ist = bvffer.replace(punctuation, '').lower().split(' ')
 7         #正则表达式规范
 8         regex_str = "^[a-z]{4,}.{1,}"
 9         #如果单词在字典里,则字典值加1,不在则添加该单词到字典里
10         for str in strl_ist:
11             if re.match(regex_str, str):
12                 if str in word_freq.keys():
13                     word_freq[str] = word_freq[str] + 1
14                 else:
15                     word_freq[str] = 1
16         return word_freq

  

  任务一:保存排名前十结果至result.txt模块

 

 1 #  保存结果到文件(result.txt)
 2 def save_info(sorted_word_freq,lines):
 3     try:
 4         result_txt = open("result.txt", "w")  # 以写模式打开,并清空文件内容
 5     except Exception as e:
 6         result_txt = open("result.txt", "x")  # 文件不存在,创建文件并打开
 7 
 8     result_txt.write("lines:" + lines + "\n")  # 按行存储,添加换行符
 9     result_txt.write("words:" +"10"+"\n")  # 按行存储,添加换行符
10 
11     for item in sorted_word_freq[:10]:
12         item = str(item).replace('(', '').replace(')', '').replace(',', ':').replace("'", "")
13         str1 = item.split(':')
14         str1 = "<" + str1[0] + ">:" + str1[1]
15         result_txt.write(str1 + "\n")  # 按行存储,添加换行符
16     result_txt.close()

 

  ④任务一:主函数调用各个模块逻辑

 

 1 if __name__ == "__main__":
 2     #命令行传递参数
 3     parser = argparse.ArgumentParser()
 4     parser.add_argument('dst')
 5     args = parser.parse_args()
 6     dst = args.dst
 7     #process_file接受参数
 8     sum_info = process_file(dst)
 9     # print(sum_info["file_row_count"])
10     word_freq = process_buffer(sum_info["bvffer"])
11     sorted_word_freq2 = output_result(word_freq)
12     lines = str(sum_info["file_row_count"])
13     save_info(sorted_word_freq2,lines)

 

  ⑤任务二:停词表模块

  功能实现方法:使用 nltk(Natural Language Toolkit,自然语言处理工具包,在NLP领域中,最常使用的一个Python库。)下载英文停词表,存放到list_stopWords集合中,接着对将要处理的英文单词进行判断是否与list_stopWords中的词汇相等,如果相等则跳过,即停词功能。

  代码模块如下:

 1 def process_buffer(bvffer):
 2     if bvffer:
 3         word_freq = {}
 4         # 下面添加处理缓冲区 bvffer代码,统计每个单词的频率,存放在字典word_freq
 5         #文本字符串前期处理
 6         strl_ist = bvffer.replace(punctuation, '').lower().split(' ')
 7         #英文停止词,set()集合函数消除重复项
 8         nltk.download("stopwords")
 9         list_stopWords = list(set(stopwords.words('english')))
10 
11         #如果单词在字典里,则字典值加1,不在则添加该单词到字典里
12         for str in strl_ist:
13             if str not in list_stopWords:
14                 if str in word_freq.keys():
15                     word_freq[str] = word_freq[str] + 1
16                 else:
17                     word_freq[str] = 1
18         return word_freq

 

  任务二:列出高频短语模块

  实现步骤: 使用 使用 nltk(Natural Language Toolkit,自然语言处理工具包,在NLP领域中,最常使用的一个Python库。)中Text的相关函数——collocations 列出文本中出现频率较高的双连词,如United States, Vice President。

  实现代码如下:

1 #提取词组
2 def getcizu():
3     # 这里设置自己的文件夹
4     corpus_root = 'D:\project_resPIDER\student_info'
5     wordlists=PlaintextCorpusReader(corpus_root, '.*',encoding='ISO-8859-1')
6     # 自行修改自己所设置文件夹下txt的名字
7     x=nltk.text.Text(wordlists.words('Gone_with_the_wind.txt'))
8     #改动20可以设置提取词组的数目
9     print(x.collocations(50, window_size=3))

 

  2.2 程序算法时间、空间复杂度分析

  针对任务2的主要逻辑模块停词表进行分析时间和空间复杂度。

  假设停词表文件有N个单词,待分析的文本单词集合有n个单词,根据两个for循环分析,则该模块的时间复杂度大概为

O(N*n),又根据操作系统的空间内存重复调用可知,该模块的时间复杂度经优化后应该小于O(N*n)。

  另一方面,该模块的空间复杂度由程序定义的list集合的容量决定,即停词表容量加待分析文本容量,大概为50k左右。

 1 def process_buffer(bvffer):
 2     if bvffer:  3 word_freq = {}  4 # 下面添加处理缓冲区 bvffer代码,统计每个单词的频率,存放在字典word_freq  5 #文本字符串前期处理  6 strl_ist = bvffer.replace(punctuation, '').lower().split(' ')  7 #英文停止词,set()集合函数消除重复项  8 nltk.download("stopwords")  9 list_stopWords = list(set(stopwords.words('english'))) 10 11 #如果单词在字典里,则字典值加1,不在则添加该单词到字典里 12 for str in strl_ist: 13 if str not in list_stopWords: 14 if str in word_freq.keys(): 15 word_freq[str] = word_freq[str] + 1 16 else: 17 word_freq[str] = 1 18 return word_freq

 

 

 

  2.3 程序运行案例截图

  ①任务1:result.txt截图

  

  ②任务2:停词表的使用与result2.txt截图

  

  

  ③任务2:高频词组截图(前30个)

  

 

三、性能分析

  2.1 所花时间

  任务一:

  

  任务二:

  

 

  性能改进:根据上面任务二总运行时间截图可以得到,该模块运行时间冗长,长达至40s。经过分析可知停词表功能实现代码中,

每运行一次,下载一次nltk停词表。这是不必要的,所以讲下载停词表代码删去可得优化总运行时间。

  

 

  

  如图对比可知,程序总运行时间显著减少了35s。

  2.2 性能图表

 

  

四、其他

  3.1 结队编程时间开销

  每天1hour,大概一周左右完成全部功能。主要时间开销分两个部分——查阅

技术文档、结队编程大体分工为两位同学同时查阅技术文档,接着交流讨论。对各

个技术方式实践结队编程最后选择最合适的方案。

  3.2 结队编程照片

  

 

 

五、事后分析与总结

  4.1 提取高频短语——讨论过程

  在解决任务2——提取高频短语时,我们两位同学在解决方法方面出现了分歧。

  55号潘博提出 使用nltk中的collection方法,思考角度为“不重复造轮子”,并且该工具包已经发展成熟,

在使用过程中并不会产生程序问题。

  56号侯磊同学提出 使用正则表达式,针对2个词汇的短语,与3个词汇的短语编写正则表达式,从文本中找出

符合要求的短语集合之后,进行短语统计(类似词频统计)。

  最后,我们综合考虑是程序的时间复杂度,决定使用潘博同学的方法。

  4.2 互相评价

  潘博评价侯磊:侯磊同学虽然在编程方面基础不是很好,但是在合作的过程中积极为项目做贡献,在查阅资料与学习

方面不遗余力。美中不足的是对编写程序背后的逻辑方面,不够严谨,希望以后能够多加思考。

  侯磊评价潘博:潘博同学不管在编程能力还是在技术储备方面都非常优秀,能够灵活运用已经学习的各门专业知识,

并且在代码编写与调试方面也非常熟练。在完成任务的同时,积极帮助我解答疑问,受益匪浅,期待下一次的合作。

  4.3 评价整个过程

  我们觉得,从本次作业完成的过程中,理解了软件工程不仅仅是一门关于程序编写与设计的学科,他还是一门包含“人”

的学科,甚至团队合作是软件开发中的至关重要的一环。

  4.5 建议

  ①希望在课后作业的项目中能够包含 一些更“热门前言”的技术知识点,或者锻炼编程能力的算法。

  ②并且希望能够提高编程的比重,而减少博客编写的比重。相比于码字,我们更喜欢码代码。

  ③结队编程应该找能力相差不多的同学结队。

  4.4 其他——总结思考

  ①.适用的项目

 

  需要快速实现或功能逻辑复杂,研究型项目,缺少设计,设计简单。

 

  ②人员的选择

 

  人员经验

 

  开发经验至少两年以上,两个经验相当的程序员。

 

如果经验相差太多,容易造成一方的强势,另外一方弱势,不容易形成讨论的局面。

 

极限编程的基础在于开发团队的成员都是经验丰富,技术娴熟的。如果开发经验少于两年的人,对于团队合作,时间的管理,进度的把握,软件的构架经验欠缺。

 

  人员性格

 

  性格上有些程序员性格外向,有很多想法。有的性格内向,思维紧密。最好是有性格中性的两个人,其次是性格内向加一个性格外向的人,最糟糕的是看到两个性格外向的人再争吵,两个性格内向的人什么话也不说。

 

  ③.广义的结对和狭义的结对

 

  狭义的理解:仅仅在编程时结对,两个人一起完成代码。

 

  广义的理解:理解需求,设计时结对,编写主要功能时结对,重复性不重要的功能分开。最后再一起Review代码。

 

  

转载于:https://www.cnblogs.com/panboo/p/9800729.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值