想法

1
2
3
1. 首先确定从0到1的产出具体步骤是怎么样的,也就是他的生命周期是怎么样的,时间安排是怎么样的
2. 明白毕设项目的背景是什么,提供了哪些帮助解决了现实当中的什么问题?
3. 感觉可以结合科大讯飞的AIMind知识图谱来做

ToDo

1
2
1. 收集研究生入学考试历年试题数据
2.

开题报告

一、选题的意义
  • 深入了解考试趋势: 通过对历年考试数据的分析,可以揭示不同年份的考试趋势,帮助教育机构更好地调整招生计划和课程设置。
  • 评估试题质量: 通过对试题的难度、区分度等方面的分析,可以评估试题的质量,有助于制定更公平、客观的评分标准。
  • 知识点覆盖情况: 分析试题中涉及的知识点,可以帮助教育机构了解考试是否覆盖了预期的教学内容,为后续课程设置提供参考。
  • 个性化学习支持: 通过对考生表现的深入分析,系统可以为每个考生提供个性化的学习支持,帮助他们更好地准备考试。
二、课题设计内容与要求

(1) 数据收集与整理: 开发数据收集模块,从研究生入学英语考试的历年试题中抽取相关数据,并进行整理和标准化.

(2) 知识点分析: 进行试题中涉及的各个知识点的分析,包括知识点的覆盖频率、考察难度等信息。

(3) 趋势分析: 通过时间序列分析,揭示考试题型和难度的变化趋势,帮助教育机构更好地调整教学方向。

(4) 个体表现: 提供考生个体成绩分析,支持对每个考生在不同知识点上的表现进行深入挖掘.

(5) 可视化报告: 设计直观的可视化报告,以图表和图形的形式呈现分析结果,使用户能够迅速理解和利用数据。

三、设计工作进度安排

(1) 2023.12.10 —- 2024.1.10 查阅资料,撰写开题报告,翻译英文资料

(2) 2024.2.11 —- 2024.2.18 需求分析,熟悉开发工具

(3) 2024.2.19 —- 2024.2.31 概要设计

(4) 2024.2.1 —- 2024.3.9 详细设计

(5) 2024.3.10 —- 2024.4.9 编写代码

(6) 2024.4.10 —- 2024.4.17 程序调试和测试

(7) 2024.4.18 —- 2024.4.31 整理资料,撰写毕业设计说明书

(8) 2024.5.1 —- 2024.5.10 答辩准备及答辩

四、申请开题

尊敬的各位老师,在您的指导下,我通过仔细的阅读任务书,以及参考各类文献,我已经为此次毕业设计做好了充足的准备,我郑重的向您请求开题

提纲

面向研究生入学考试英语试题数据分析的可视系统设计与实现

随着研究生入学考试的日益竞争激烈,对英语试题的数据分析成为了提高教学质量和帮助考生备考的关键。本课题旨在设计并实现一个面向研究生入学考试英语试题数据分析的可视系统,
通过数据可视化手段帮助教育机构和考生深入了解考试趋势、知识点覆盖情况等信息。课题的设计目标包括:
(1)数据收集与整理: 开发数据收集模块,从研究生入学英语考试的历年试题中抽取相关数据,并进行整理和标准化。
(2)知识点分析: 进行试题中涉及的各个知识点的分析,包括知识点的覆盖频率、考察难度等信息。
(3)趋势分析: 通过时间序列分析,揭示考试题型和难度的变化趋势,帮助教育机构更好地调整教学方向。
(4)个体表现: 提供考生个体成绩分析,支持对每个考生在不同知识点上的表现进行深入挖掘。
(5)可视化报告:设计直观的可视化报告,以图表和图形的形式呈现分析结果,使用户能够迅速理解和利用数据

数据收集与整理

  1. 首先,确定数据来源,例如研究生入学英语考试的历年真题。
  2. 利用网络爬虫技术或手动方式收集历年真题,并将其存储在数据库中。
  3. 对收集到的数据进行清洗、去重和标准化,以便后续分析。

知识点分析

  1. 定义知识点分类体系,如词汇、语法、阅读理解、写作等。

词频分析

整体思路:
1
2
3
4
5
首先读取docx文件并获得docx文件列表
获取词干列表
申请有道翻译开发者并获得apiKey等参数
获取带翻译的键值对列表
将数据存储到Excel当中
文件结构:

word版

​ – docx文件

词频提取.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
from docx import Document
import nltk
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
import re
from nltk.stem import PorterStemmer
from nltk.stem.lancaster import LancasterStemmer
from nltk.stem.snowball import SnowballStemmer
from nltk.stem import WordNetLemmatizer
from nltk.corpus import wordnet
import collections
import uuid
import requests
import hashlib
import time
import json
interpunctuations = [',', '.', ':', ';', '?', '(', ')', '[', ']', '&', '!', '*', '@', '#', '$', '%', '_', '-', '—', '"', '“', '”', "'"]

stops = set(stopwords.words("english"))
docxs1 = [Document('./word版/'+str(year)+'年考研英语一真题.docx') for year in range(2018, 2021)]
def get_words(docxs): # 输入文件名列表,输出单词列表(去标点数字符号,题目要求标题)
words = [] # 储存单词
for doc in docxs: # 遍历每一个文件
for para in doc.paragraphs: # 遍历文件中的每一个段落
if len(para.runs)>=1 and len(para.text)>=1: # 确实是有效段落
if para.runs[0].font.bold or para.runs[0].font.italic: # 如果是粗体或者斜体,不处理
continue
# s = re.sub(r'[.*?]', ' ', para.text)
s = re.sub(r'[[A-Z]+]', ' ', para.text) # 去掉特殊符号
s = re.sub(r'[0-9]+', ' ', s)
s = re.sub(r'②|③|①|④|⑤|⑥|⑦|⑧|⑨|⑩|⑪|⑫|⑬|⑭|⑮|⑯|⑰|_|—|-|\.', ' ', s)
s = re.sub(r'\[0-9a-z]', ' ', s)
# print(s)
s_words = word_tokenize(s) # 分词

# print(s_words)
cutwords = [word for word in s_words if word not in interpunctuations]
cutwords = [word.lower() for word in cutwords if word not in stops] # 去除停用词与标点
if cutwords:
if cutwords[0] == 'read' or cutwords[0] == 'translate': # 有的翻译和阅读题目介绍没有粗体和斜体
continue
words+=cutwords
return words
def get_wordnet_pos(tag): # 词性转化翻译
if tag.startswith('J'):
return wordnet.ADJ
elif tag.startswith('V'):
return wordnet.VERB
elif tag.startswith('N'):
return wordnet.NOUN
elif tag.startswith('R'):
return wordnet.ADV
else:
return ''
def get_stems(words): # 获得词干
lem = WordNetLemmatizer() # 词形还原
words_tag = nltk.pos_tag(words)
words_final = []
for couple in words_tag:
if couple[0][0]<'a' or couple[0][0]>'z' or len(couple[0])<=1: # 去除非单词及空格
continue
if get_wordnet_pos(couple[1]):
words_final.append(lem.lemmatize(couple[0], get_wordnet_pos(couple[1])))
else:
words_final.append(lem.lemmatize(couple[0]))
return(words_final)
# APPID 与 秘钥
appid = '****'
secretKey = '********'
myurl = 'https://openapi.youdao.com/api'

def encrypt(signStr):
hash_algorithm = hashlib.sha256()
hash_algorithm.update(signStr.encode('utf-8'))
return hash_algorithm.hexdigest()

def translate(q):

# 将key设置为字典,填写参照文档
data = {}
data['from'] = 'en'
data['to'] = 'zh-CHS'
data['signType'] = 'v3'
curtime = str(int(time.time()))
data['curtime'] = curtime
salt = str(uuid.uuid1())
signStr = appid + q + salt + curtime + secretKey
sign = encrypt(signStr)
sign = encrypt(signStr)
data['appKey'] = appid
data['q'] = q
data['salt'] = salt
data['sign'] = sign
headers = {'Content-Type': 'application/x-www-form-urlencoded'}

# 使用requests的post获取
response = requests.post(myurl, data=data, headers=headers)
# print(response.content)

# 对response的内容解码
result_all = response.content.decode("utf-8")
# 转换为json形式
result = json.loads(result_all)
if 'basic' in result:
return result['basic']['explains']
else:
return '释义错误'
def translate_alls(coun):
ans = {}
for k,v in coun.items():
trans = translate(k)
ans[k] = [v, trans]
return ans
if __name__ == '__main__':
words_1 = get_words(docxs1) # 由文件获得分词列表
words_final_1 = get_stems(words_1) # 获得词干列表
coun_1 = dict(collections.Counter(words_final_1).most_common()) # 进行统计
print(coun_1)
# ans_1 = translate_alls(coun_1) # 调用API获得翻译+词频字典

结果截图展示:

image-20231217233315614

遇到的问题1:
1
ValueError: file './word版/2020年考研英语一真题.docx' is not a Word file, content type is 'application/vnd.ms-word.document.macroEnabled.main+xml'

这个报错就是docx在2007年之前的word版本创建的文件python里面的docx第三方库不支持打开

遇到的问题2:
1
2
3
  File "/usr/lib/python3.6/zipfile.py", line 1198, in _RealGetContents
raise BadZipFile("File is not a zip file")
zipfile.BadZipFile: File is not a zip file

这个代码修改一下就行

1
load_workbook("a.xlsx")----> wb = Workbook()  # 加载文件
效果展示

image-20231218184317275

缺憾:

有道翻译的API调用有些解释翻译有问题

  1. 分析每道试题所属的知识点,并统计各个知识点的覆盖频率和考察难度。

  2. 可以使用Excel或Python等工具进行数据处理和分析。

趋势分析

  1. 按照时间顺序整理试题数据,形成时间序列。
  2. 利用时间序列分析方法(如ARIMA模型)预测考试题型和难度的变化趋势。
  3. 结合可视化工具(如Matplotlib、Seaborn等)绘制趋势图,展示分析结果。

个体表现

  1. 针对每个考生,统计其在不同知识点上的正确率、得分等指标。
  2. 利用聚类、分类等机器学习算法对考生进行分组,分析不同组别在知识点上的表现。
  3. 可使用Python的scikit-learn库进行算法实现。

可视化报告

设计简洁明了的报表模板,包括以下部分:

  1. 概述:简要介绍分析目的、数据来源和分析方法。
  2. 知识点覆盖情况:列出各知识点的覆盖频率和考察难度。
  3. 趋势分析:展示时间序列分析和预测结果。
  4. 考生个体表现:展示不同考生在知识点上的表现差异。
  5. 使用Python的echarts等库生成可视化报告。

相关文档:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
https://blog.csdn.net/wardseptember/article/details/82015147
https://zhuanlan.zhihu.com/p/400688428
https://blog.csdn.net/qq_38463737/article/details/111387831
--------------------------------------------------------------
https://blog.csdn.net/Be_racle/article/details/128961533 主题提取
https://zhuanlan.zhihu.com/p/76636216
https://github.com/DengYangyong/LDA_gensim/tree/master
https://github.com/Lan-ce-lot/weibo-opinion-analysis
--------------------------------------------------------------
https://blog.csdn.net/weixin_44590691/article/details/104019047 storytelling 可视化
--------------------------------------------------------------
https://github.com/FormatFa/zhsz_backend flask + vue

https://github.com/zll17/Neural_Topic_Models 主题模型
https://zhuanlan.zhihu.com/p/587467839 BERT
https://maartengr.github.io/BERTopic/index.html BERT
https://www.lfd.uci.edu/~gohlke/pythonlibs/#hdbscan python第三方库

https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2 hugging face
https://colab.research.google.com/drive/1W7aEdDPxC29jP99GGZphUlqjMFFVKtBC?usp=sharing#scrollTo=SmxBX5UIzl_o Bertopic可视化

https://zhenti.burningvocabulary.com/kaoyan 考研英语真题免费下载

论文勾要

1
2
论文,少量代码截图
相关工作
1
2
3
4
5
6
proxy = {'http': random.choice(proxies_list)}
response = requests.get(url=url, headers=headers, proxies=proxy,verify=False)
print(response.text)

以上为我爬取的pdf内容,我需要把它存为pdf到指定文件目录

第三周

要求:

学习自然语言处理中的话题建模算法,对每一年的试题文本进行话题提取

什么是主题模型?

主题模型(Topic Model)是通过学习一系列的文档,发现抽象主题的一种统计模型。从词频的角度来讲,如果一篇文章包含某个主题,那么一定存在一些特定的词语会频繁出现。通常情况下,一篇文章中包含多个主题,而且每个主题所占的比例各不相同。

比如:“美国对伊朗再度实施单边制裁,这将对伊朗的出口贸易造成严重影响”。这里可以归为政治主题,因为描述国家的词语频繁出现。也可以归为经济主题,因为出现了制裁、出口贸易等词。我们可以预估一下,政治主题的比例为 0.7,经济主题的比例为 0.3。

主题模型是对文本中隐含主题的一种建模方法,每个主题其实是词表上词语的概率分布。主题模型是一种生成模型,一篇文章中每个词都是通过“以一定概率选择某个主题,并从这个主题中以一定概率选择某个词语”这样一个过程得到的。

比如,我们写文章一般先选定一个主题,然后用和这个主题有关的词语进行组合形成文章。

LDA 主题模型

LDA 是一种无监督学习方法,在训练时不需要手工标注的训练集,需要的仅仅是文档集以及指定主题的数量 k 即可。此外,LDA 的另一个优点是,对于每一个主题均可找出一些词语来描述它。

LDA实现原理

通过文档集生成主题集,通过主题集生成词语

code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
from gensim import corpora, models, similarities
import gensim
import re
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize

def process_articles(text):
text = text.lower()
text = text.replace('【', '')
text = text.replace('】', '')
text = text.replace('《', '')
text = text.replace('》', '')
text = re.sub('[\u4e00-\u9fa5]', ' ', text) #英文文档竟然出现了汉字,也是醉了
text = re.sub(r'/', ' ', text)
text = re.sub(r'//', ' ', text)
text = re.sub(r'\\', ' ', text)
text = re.sub(r'\\\\', ' ', text)
text = re.sub(r'-', ' ', text) #把 "-" 的两个单词分开(比如:july-edu ==> july edu)
text = re.sub(r'--', ' ', text)
text = re.sub(r'—', ' ', text)
text = re.sub(r'\d+', '', text) #去掉数字
words = word_tokenize(text)
english_stopwords = stopwords.words('english')
addition_stopwords = ['\'re', '\'s', '\'t', '\'m', '\'ll', '\'ve', '\'d', 'n\'t']
english_punctuations = [',', '.', ':', ';', '?', '(', ')', '[', ']', '&', '!', '*', '@', '#', '$', '%', '-',
'..', '...', '......', '|', '``', '\'', '\'\'', '<', '>', '~', '+', '/', '//', '"']

filter_words = [w for w in words if (w not in english_stopwords)]
filter_words = [w for w in filter_words if (w not in addition_stopwords)]
filter_words = [w for w in filter_words if (w not in english_punctuations)]

result = []
for filter_word in filter_words:
pattern = re.compile('.*[0-9]+.*') #用正则过滤后还是出现了数字,再过滤一次
match = pattern.findall(filter_word)

# 关于网址和邮箱的写法,不同文档也是五花八门,无奈写不出一个好的正则,只能在这里过滤掉
if ('www' not in filter_word and '.com' not in filter_word and '@' not in filter_word and len(
filter_word) > 1 and not match):
result.append(filter_word)

return result
def mark_title_distribute():
#对每篇文档,标记主题分布
with open(output_file_path, 'w', encoding='utf-8') as f:
for i in range(len(titles)):
f.write(titles[i])
topic_pro = lda.get_document_topics(corpus[i])
f.write(str(topic_pro) + '\n')
f.close()
def Merge_title_content():
#在保存语料时,我的做法是一行标题,一行内容。因此在取出时,需要将标题和内容合起来作为一篇文档
i = 1
for line in data_file.readlines():
if i % 2 == 1:
titles.append(line)
title = process_articles(line)
texts.append(title)
elif i % 2 == 0:
body = process_articles(line)
index = int(i / 2 - 1)
texts[index] = texts[index] + body
i = i + 1
data_file.close()
if __name__ == '__main__':
data_file_path = 'd:/2023.txt'
output_file_path = 'd:/output.txt'
data_file = open(data_file_path, encoding='utf-8')
texts = []
titles = []
Merge_title_content()
dictionary = corpora.Dictionary(texts)
corpus = [dictionary.doc2bow(text) for text in texts] #词频统计

lda = gensim.models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=10) #模型训练,这里预定义20个主题

print(lda.print_topics(num_topics=10, num_words=10))
mark_title_distribute()
输出

image-20231230172949770

第四周

主题建模出结果;调研story telling可视化,下载代码跑一个示例

story telling代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource, HoverTool
from bokeh.palettes import Category20_20
import pandas as pd

# 创建一个简单的数据集
data = {
'Year': [2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019],
'Sales': [5, 8, 12, 15, 20, 18, 25, 30, 28, 35],
'Profit': [1, 2, 3, 5, 8, 7, 10, 12, 11, 15]
}

df = pd.DataFrame(data)

# 创建ColumnDataSource对象
source = ColumnDataSource(df)

# 创建绘图对象
p = figure(title="Sales and Profit Over Years", x_axis_label='Year', y_axis_label='Amount')

# 绘制线条
p.line(x='Year', y='Sales', line_width=2, legend_label='Sales', line_color=Category20_20[0], source=source)
p.line(x='Year', y='Profit', line_width=2, legend_label='Profit', line_color=Category20_20[2], source=source)

# 添加悬停工具
hover = HoverTool()
hover.tooltips = [('Year', '@Year'), ('Sales', '@Sales'), ('Profit', '@Profit')]
p.add_tools(hover)

# 显示图表
show(p)

效果展示

image-20240104214635122

第五周

story telling以pdf当中的形式实现

1
2
d = gensim_models.prepare(lda, corpus, dictionary)
pyLDAvis.show(d)

遇到的问题

第一个问题
1
2
3
4
5
6
Traceback (most recent call last):
File "C:\Users\13772\Desktop\所有文件\untitled\2022\12月\12月29号词频\考研英语\test.py", line 85, in <module>
pyLDAvis.show(d)
File "C:\Users\13772\AppData\Roaming\Python\Python39\site-packages\pyLDAvis\_display.py", line 262, in show
'/LDAvis.css': ["text/css", open(urls.LDAVIS_CSS_URL, 'r').read()],
OSError: [Errno 22] Invalid argument: 'https://cdn.jsdelivr.net/gh/bmabey/pyLDAvis@3.3.1/pyLDAvis/js/ldavis.v1.0.0.css'
解决方法

修改源码

image-20240114162010015

将True改为False

1
经过以上功能用例的测试,可以说明本系统基础功能和LDA主题模型功能都正常,运行结果均符合预期目标。
报错原因

如果不修改为False那么不能调研远程的JS服务,从而实现不了LDA可视化

第二个问题
1
2
3
4
5
6
7
8
9
10
Traceback (most recent call last):
File "C:\Users\13772\Desktop\所有文件\untitled\2022\12月\12月29号词频\考研英语\test.py", line 84, in <module>
d = gensim_models.prepare(lda, corpus, dictionary)
File "C:\Users\13772\AppData\Roaming\Python\Python39\site-packages\pyLDAvis\gensim_models.py", line 123, in prepare
return pyLDAvis.prepare(**opts)
File "C:\Users\13772\AppData\Roaming\Python\Python39\site-packages\pyLDAvis\_prepare.py", line 439, in prepare
topic_info = _topic_info(topic_term_dists, topic_proportion,
File "C:\Users\13772\AppData\Roaming\Python\Python39\site-packages\pyLDAvis\_prepare.py", line 246, in _topic_info
default_term_info = default_term_info.sort_values(
TypeError: drop() takes from 1 to 2 positional arguments but 3 were given
解决方法

image-20240114163941953

在源码上面添加axis=1即可

可视化展示

image-20240114171829401

第六周

  1. 阅读完storytelling的论文

  2. 将多个展示页面集成起来,使用vue + flask实现

预期效果

1
2
3
数据源: 2018-2023考研英语真题,数据是词频
1. 一个是通过visLDA(python库)生成的一个html文件,一个是pyecharts生成的html文件
2. 希望可视化大屏展示的左上角有按钮切换年份,看每一年展示的数据不同
遇到的问题
第一个

image-20240123231300676

解决方法

将webpack.base.conf.js里面的eslint校验给关掉

image-20240123231410386

第二个问题

效果

image-20240127134821803

难点

  1. LDAvis库生成的html页面如何嵌入到大屏页面

  2. LDA模型可视化依赖生成的LDA模型,需要延迟加载

第七周

1.美化页面

效果:

词云图可以随意改变,只需要一个蒙版图片就可以完成

蒙版图片如下

logo

image-20240202133727766

引用文章

[1] 王祖超, 袁晓如. 轨迹数据可视分析研究[J]. 计算机辅助设计与图形学学报, 2015, 27(1): 9-25.
[2] 刘明吉, 王秀峰. 数据挖掘中的数据预处理[J]. 计算机科学, 2000, 27(4): 54-57.
[3] 周水庚, 李丰, 陶宇飞, 等. 面向数据库应用的隐私保护研究综述[J]. 计算机学报, 2009, 32(5): 847-861.
[4] 徐宝文, 张卫丰. 数据挖掘技术在 Web 预取中的应用研究[J]. 计算机学报, 2001, 24(4): 430-436.
[5] 周庆, 牟超, 杨丹. 教育数据挖掘研究进展综述[J]. 软件学报, 2015, 26(11): 3026-3042.
[6] Souri A, Hosseini R. A state-of-the-art survey of malware detection approaches using data mining techniques[J]. Human-centric Computing and Information Sciences, 2018, 8(1): 1-22.
[7] Hasan M K, Ghazal T M, Alkhalifah A, et al. Fischer linear discrimination and quadratic discrimination analysis–based data mining technique for internet of things framework for Healthcare[J]. Frontiers in Public Health, 2021, 9: 737149.
[8] Lin G, Zhang J, Luo W, et al. Software vulnerability discovery via learning multi-domain knowledge bases[J]. IEEE Transactions on Dependable and Secure Computing, 2019, 18(5): 2469-2485.
[9] Eckhart M, Ekelhart A, Weippl E. Automated security risk identification using AutomationML-based engineering data[J]. IEEE Transactions on Dependable and Secure Computing, 2020, 19(3): 1655-1672.
[10] Luo Y, Qin X, Tang N, et al. Deepeye: Towards automatic data visualization[C]//2018 IEEE 34th international conference on data engineering (ICDE). IEEE, 2018: 101-112.

第八周

遇到的BUG1
JS代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
<script>
function handleSelectChange() {
// 获取下拉框元素
var yearSelect = document.getElementById("yearSelect");
// 获取选中的值
var selectedValue = yearSelect.value;
axios({
methods: "get",
url: '/pre',
params: {
year: selectedValue
},
}).then(resp => {
var myChart = echarts.init(document.getElementById('echart1'));
var keywords = {{form|safe}};

var data = [];
for (var name in keywords) {
data.push({
name: name,
value: Math.sqrt(keywords[name])
})
}

var maskImage = new Image();

var option = {
series: [{
type: 'wordCloud',
sizeRange: [4, 150],
rotationRange: [0, 0],
gridSize: 0,
shape: 'pentagon',
maskImage: maskImage,
drawOutOfBound: false,
// layoutAnimation: true,
keepAspect: true,
textStyle: {
fontWeight: 'bold',
color: function () {
return 'rgb(' + [
Math.round(Math.random() * 200) + 50,
Math.round(Math.random() * 50),
Math.round(Math.random() * 50) + 50
].join(',') + ')';
}
},
emphasis: {
textStyle: {
color: '#528'
}
},
data: data.sort(function (a, b) {
return b.value - a.value;
})
}]
};

maskImage.onload = function () {
option.series[0].maskImage
myChart.setOption(option);
}

maskImage.src = '../static/images/logo.png';

// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
window.onresize = function () {
myChart.resize();
}
var delayedIframe = document.getElementById('delayedIframe');
delayedIframe.src = '/show_ldavis';
})
})
</script>

<script>
$(function echarts_1() {
// 获取下拉框元素
var yearSelect = document.getElementById("yearSelect");
// 获取选中的值
var selectedValue = yearSelect.value;
axios({
methods: "get",
url: '/pre',
params: {
year: selectedValue
},
}).then(resp => {
var myChart = echarts.init(document.getElementById('echart1'));
var keywords = {{form|safe}};

var data = [];
for (var name in keywords) {
data.push({
name: name,
value: Math.sqrt(keywords[name])
})
}

var maskImage = new Image();

var option = {
series: [{
type: 'wordCloud',
sizeRange: [4, 150],
rotationRange: [0, 0],
gridSize: 0,
shape: 'pentagon',
maskImage: maskImage,
drawOutOfBound: false,
// layoutAnimation: true,
keepAspect: true,
textStyle: {
fontWeight: 'bold',
color: function () {
return 'rgb(' + [
Math.round(Math.random() * 200) + 50,
Math.round(Math.random() * 50),
Math.round(Math.random() * 50) + 50
].join(',') + ')';
}
},
emphasis: {
textStyle: {
color: '#528'
}
},
data: data.sort(function (a, b) {
return b.value - a.value;
})
}]
};

maskImage.onload = function () {
option.series[0].maskImage
myChart.setOption(option);
}

maskImage.src = '../static/images/logo.png';

// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
window.onresize = function () {
myChart.resize();
}
var delayedIframe = document.getElementById('delayedIframe');
delayedIframe.src = '/show_ldavis';
})
})
)
</script>
python代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@app.route('/pre')
def get_wordcloud_chart2():
global d, data_file_path, year, data_file, texts, titles, lda
year = request.args.get('year')
data_file_path = r'F:\GithubProgram\BigScreenVus\big_screen\txt\{}.txt'.format(year)
data_file = open(data_file_path, encoding='utf-8')
texts = []
titles = []
Merge_title_content()
dictionary = corpora.Dictionary(texts)
corpus = [dictionary.doc2bow(text) for text in texts] # 词频统计

lda = gensim.models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=10,
passes=20) # 模型训练,这里预定义10个主题
# passes训练轮次
data = wordcloud_picture2()
print(data)
d = gensim_models.prepare(lda, corpus, dictionary)
title = "考研英语可视化大屏展示"
return render_template('index.html', form=data, title=title)

出现的问题是form提取来的数据总是没有变化,原因是form会有缓存,然后每次在加载完HTML页面的时候又会去执行echarts_1函数

image-20240427170127234

后来改善
python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@app.route('/pre')
def get_wordcloud_chart2():
global d, data_file_path, year, data_file, texts, titles, lda
year = request.args.get('year')
data_file_path = r'F:\GithubProgram\BigScreenVus\big_screen\txt\{}.txt'.format(year)
data_file = open(data_file_path, encoding='utf-8')
texts = []
titles = []
Merge_title_content()
dictionary = corpora.Dictionary(texts)
corpus = [dictionary.doc2bow(text) for text in texts] # 词频统计

lda = gensim.models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=10,
passes=20) # 模型训练,这里预定义10个主题
# passes训练轮次
data = wordcloud_picture2()
print(data)
d = gensim_models.prepare(lda, corpus, dictionary)
title = "考研英语可视化大屏展示"
return jsonify(data)

JS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<script type="text/javascript">
function handleSelectChange() {
// 获取下拉框元素
var yearSelect = document.getElementById("yearSelect");
// 获取选中的值
var selectedValue = yearSelect.value;
axios({
methods: "get",
url: '/pre',
params: {
year: selectedValue
},
}).then(resp => {
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('echart1'));
{#console.error('form:', {{form}});#}
var keywords = resp.data;

var data = [];
for (var name in keywords) {
data.push({
name: name,
value: Math.sqrt(keywords[name])
})
}

var maskImage = new Image();

var option = {
series: [{
type: 'wordCloud',
sizeRange: [4, 150],
rotationRange: [0, 0],
gridSize: 0,
shape: 'pentagon',
maskImage: maskImage,
drawOutOfBound: false,
// layoutAnimation: true,
keepAspect: true,
textStyle: {
fontWeight: 'bold',
color: function () {
return 'rgb(' + [
Math.round(Math.random() * 200) + 50,
Math.round(Math.random() * 50),
Math.round(Math.random() * 50) + 50
].join(',') + ')';
}
},
emphasis: {
textStyle: {
color: '#528'
}
},
data: data.sort(function (a, b) {
return b.value - a.value;
})
}]
};

maskImage.onload = function () {
option.series[0].maskImage
myChart.setOption(option);
}

maskImage.src = '../static/images/logo.png';

// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
window.onresize = function () {
myChart.resize();
}

var delayedIframe = document.getElementById('delayedIframe');
delayedIframe.src = '/show_ldavis';
})

}
</script>

第九周

task
  1. 界面的优化,问题如下

    这个⚪变成圆缺了

    image-20240308141349942

  2. 我们需要一个导航栏,我们展示的词云图是怎么来的?

    首先我们需要通过预览某一年的试题,然后预览试题界面下面有按钮,分别是关键词提取,可视化展示等等

  3. 可能需要加一个考生分数统计

  4. 主题模型用多种,然后做一个对比方案

1
2
3
1. 要去知道前端预览word文档或者pdf或者txt文件
2. 文档页面展示后会有多个按钮(词汇分析,)
3.

IDEA

1
2
3
4
5
6
7
8
9
10
11
主题模型效果之间如何对比,具体是对比什么?
这个对比后的结果,我们该如何可视化呢?
考研英语还有其他什么点能用来补充可视化内容吗?(之前老师说考研英语成绩数据)
感觉可以用考研英语历年的平均分做一个柱状图
根据考研英语不同的题型平均分来做一个条形图或者雷达图
可以使用hugeface做分类,就是先有标签,然后给打分,然后得到一个可视化图

LDA和BERT两种主题模型的比较,比较主题分布通过热力图
比较关键词的可视化通过词云图
TVCG期刊 文本数据

1
pip install -i https://pypi.douban.com/simple scikit-learn==0.19.2

遇到的问题

  1. requests.exceptions.SSLError:(MaxRetryError(“HTTPSConnectionPool(host=‘huggingface.co‘, port=443)

解决方案:

1
2


第十周

finishedList:

  1. 新增词频可视化词云图和词表格
  2. 新增Bertopic主题聚类可视化图
  3. 新增关于零样本分类模型进行多标签分类的bart-large-mnli模型的可视化图
  4. 实现了年份变化前端后端交互
  5. 初步勾画毕业论文写作思路

效果如下

image-20240329152621756

image-20240329152637907

论文可以写的点

1
1.考研英语背景,结合时代 2.需求 3.关键词 4.摘要 5.英语词频 6.LDA 7.bertopic 8.bart-minl 9. ChatGPT提取主题 10.参考文献

有查询毕业论文写作案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
摘要
先简要介绍背景;再说明研究对象和研究方法,并简单罗列主要的
研究结果;最后,一两句话提出研究得出的建议。
Abstract
一、绪论
(一)研究背景
主要写:随着社会的发展,选题受到了很大的关注,但是还存在什么问题没有解决,因此,对本文进行研究是非常必要的。
(二)研究意义
说明研究必要性,主要分两部分子
(1)理论意义:分点概括文章主要做了什么,完善丰富了....理论
(2)现实意义:研究结果对社会,对企业的影响
(三)研究方法
文献分析法、问卷调查法、访谈法、实地调研法、数理分析法

二、理论基础和国内外研究现状
(一)理论基础:研究基于什么理论,具体见相似选题的硕士毕业文和期刊论文。
(二)国内外研究现状:格式:作者(xx年)用XX方法研究xx得到xx结论(建议文献总结方式:按研究结论主题分条罗列,每条再按时间顺序罗列)

三、现状分析
(一)具体的数据处理过程:介绍下问卷的分发及处理情况
(二)统计分析:统计教据基本特征,例如,频率、占比、平均值,标准差等,可分多个层面进行叙述,比如,从学校、老师、学生三个层次叙述调查得到的结果。

四、问题及原因
(一)问题:针对第三章发现的问题,进行叙述,一般分4条
(二)存在问题的原因:可根据文章总体字数进行叙述,如果字数足够了,也可删去。

第十一周

todolist
  1. 可以新增单词量图

    image-20240405133751078

参考:https://github.com/xuwhao/vocab-statistics

  1. 求历年词频的交集

  2. 词频统计相邻年份(https://cloud.tencent.com/developer/article/1379258)

  3. 一些东西点击按钮,新生成的界面可以悬浮起来

第十二周

1.主题模型可视化 https://www.bilibili.com/video/BV1zw411u77k/?

LDA一致性

1
2
3
4
https://www.gsx42.cn/news/241246.html
https://blog.csdn.net/weixin_44585839/article/details/106500139?
https://blog.csdn.net/stay_foolish12/article/details/127240167
[0.445, 0.331, 0.399, 0.371, 0.371, 0.492, 0.568, 0.556, 0.768, 0.546, 0.616, 0.521, 0.637, 0.625, 0.667]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
  <div class="boxall" style="height: 3.69rem;width: 33%;">
<div class="alltitle" id="dynamicTitle3"></div>
<div class="allnav" id="echart6" style="width: 100%; height: 3.39rem;"></div>
<div class="boxfoot"></div>
</div>

const titleElement = document.getElementById('dynamicTitle4');
titleElement.textContent = resp.data.title;
var myChart = echarts.init(document.getElementById('echart8'));
option = {
xAxis: {
type: 'category',
name: '主题数',
data: resp.data.labels
},
yAxis: {
type: 'value',
name: '一致性得分'
},
toolbox: {
feature: {
saveAsImage: {}
}
},
series: [
{
data: resp.data.scores,
type: 'line',
smooth: true
}
]
};

myChart.setOption(option);
window.onresize = function () {
myChart.resize();
}
以上为一个echars技术生成的一个柱状图,它的图形大小能够自适应div容器



那么一下这个又该如何自适应容器呢? 帮忙改一改代码
问题: 如何让通过iframe嵌入的HTML的大小自适应容器?

前端代码:
<div class="boxall" style="height: 7.0rem;">
<div class="alltitle">LDA</div>
<iframe id="delayedIframe" width="100%" height="100%" frameborder="0"></iframe>
</div>

<script>
var delayedIframe = document.getElementById('delayedIframe');
delayedIframe.src = '/show_ldavis?year=' + selectedValue;
</script

后端代码
# 渲染LDA可视化展示
@app.route('/show_ldavis')
def show_ldavis():
global d, year, data_file, texts, lda
year = request.args.get('year')
texts = []
Merge_content(year)
dictionary = corpora.Dictionary(texts)
corpus = [dictionary.doc2bow(text) for text in texts] # 词频统计
# 获取最佳主题数
labels, scores = get_lda_coherence(year)
max_value = max(scores)
max_index = scores.index(max_value)

lda = gensim.models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=max_index + 1,
passes=10) # 模型训练,这里预定义10个主题
# passes训练轮次
# data = get_topic_word_freq()
# print(data)
d = gensim_models.prepare(lda, corpus, dictionary)
vis_html = pyLDAvis.display(d)
return render_template('ldavis_template.html', vis_html=vis_html)


$$
P(\tilde{W} | M) = \Pi_{m-1}^{m}P()
$$

LDA困惑度的计算公式如下:
$$
𝑝𝑒𝑟𝑝𝑙𝑒𝑥𝑖𝑡𝑦=𝑒𝑥𝑝(-\frac{\Sigma_{d=1}^{D}logp(W_{d})}{\Sigma_{d=1}^{D}N_{d}})公式(1)
$$

$$
score(w_{i},w_{j},\in) = \frac{p(w_{i},w_{j}) + \in}{p(w_{i})p(w_{j})}公式(2)
$$

$$
score(w_{i},w_{j},\in) = \frac{D(w_{i},w_{j}) + \in}{D(w_{j})}公式(3)
$$

1
https://datav.aliyun.com/portal/editor

1.B/S 结构,有什么优点?

B/S 架构的全称为 Browser/Server,即浏览器/服务器结构,Browser 指的是Web 浏览器,通过浏览器 与后台服务器交互就是 B/S 架构

1.最大的优点就是可以在任何地方进行操作而不用安装任何专门的软件

2.系统的扩展非常容易,只要能上网,再由系统管理员分配一个用户名和密码,就可以使用了,或者在线申请

2.服务器是哪个,如何配置的?

服务器本地运行的,因为springboot是封装tomacat所以不用再配置tommcat,直接启动 main 类运行即可。

3.为什么选择 java 语言进行开发?

Java 是一种面向对象的编程语言,提供了丰富的面向对象的特性,如封装、继承、多态,使得代码更加模块化、可维护性更高。

4.Ajax 应用程序的优势有哪些?

  1. 通过异步模式,提升了用户体验。

  2. 优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用

  3. Ajax 引擎在客户端运行,承担了一部分本来由服务器承担的工作,从而减少了大用户量下的服务器负载

5.黑白盒子测试是什么?

白盒测试也称为结构测试,主要用于检测软件编码过程中的错误。程序员的编程经验、对编程软件的掌握程度、工作状态等因素都会影响到编程质量,导致代码错误。黑盒测试又称为功能测试,主要检测软件的每一个功能是否能够正常使用。在测试过程中,将程序看成不能打开的黑盒子,JavaEasy666 不考虑程序内部结构和特性的基础上通过程序接口进行测试,检查程序功能是否按照设计需求以及说明书的规定能够正常打开使用

1
2
3
4
5
6
7
8
9
10
11
12
def get_appear_word_lastyear():
repeated_words_count_list = []
previous_key_words = set()
for year in range(2018, 2025):
text = get_pdf_content(year)
text = clean_context(text)
key_words = set(word_tokenize(text))
if previous_key_words:
repeated_words_count = len(previous_key_words.intersection(key_words))
repeated_words_count_list.append(repeated_words_count)
previous_key_words = key_words
return repeated_words_count_list
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var myChart = echarts.init(document.getElementById('echart2'));
var keywords = resp.data;

var data = [];
for (var wordFreq of keywords) {
data.push({
name: wordFreq[0],
value: wordFreq[1] // 直接使用词频值,不需要进行 Math.sqrt 处理
})
}

var maskImage = new Image();
var option = {
series: [{
type: 'wordCloud',
sizeRange: [4, 220],
rotationRange: [0, 0],
gridSize: 0,
shape: 'pentagon',
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<button id="confirm-btn" onclick="handleSelectChange()">确定</button>
<button id="reset-btn">重置</button>
function handleSelectChange() {
console.log("变化了!!!")
get_text();
get_word_table();
get_lda_coherence();
get_lda_perplexity();
show_ldavis();
}
function get_word_table() {
var yearSelect = document.getElementById("year-select");
var selectedValue = yearSelect.value;
axios({
method: "get",
url: '/getWordFreq',
params: {year: selectedValue} // 传递选中的年份给后端
}).then(resp => {
const table = document.getElementById('wordFreqTable');
// 清空表格内容
table.innerHTML = "";
for (const wordFreq of resp.data) { // 使用 for...of 循环
1
2
3
4
5
# 获取词频
@app.route('/getWordFreq')
def getWordFreq():
year = request.args.get('year')
text = get_pdf_content(year)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def clean_context(text):
text = text.lower()
text = text.replace('【', '')
text = text.replace('】', '')
text = text.replace('《', '')
text = text.replace('》', '')
text = re.sub('[\u4e00-\u9fa5]', ' ', text) # 英文文档竟然出现了汉字,也是醉了
text = re.sub(r'/', ' ', text)
text = re.sub(r'[^A-Za-z]', ' ', text)
text = re.sub(r'//', ' ', text)
text = re.sub(r'\\', ' ', text)
text = re.sub(r'\\\\', ' ', text)
text = re.sub(r'-', ' ', text) # 把 "-" 的两个单词分开(比如:july-edu ==> july edu)
text = re.sub(r'--', ' ', text)
text = re.sub(r'—', ' ', text)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
dictionary = corpora.Dictionary(texts)
corpus = [dictionary.doc2bow(text) for text in texts] # 词频统计
# 获取最佳主题数
labels, scores = get_lda_coherence(year)
max_value = max(scores)
max_index = scores.index(max_value)

lda = gensim.models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=max_index + 1,
passes=10) # 模型训练,这里预定义10个主题
# passes训练轮次
# data = get_topic_word_freq()
# print(data)
d = gensim_models.prepare(lda, corpus, dictionary)
vis_html = pyLDAvis.display(d)

答辩老师问题

1
2
3
1. 数据来源哪里?  网站的真题数据
2. 你读取真题文本里面的数据是怎么处理的,图片怎么筛选掉? PdfReader(pdf_file)读取文件,再通过pdf的extract_text()方法提取文本数据
3. 系统的受众用户是谁? 大学生,培训机构

论文问题

1
2
代码块改成白底的
可行性分析那一块需要删减
1
2
3
4
5
6
7
第一章 5页
第二章 5页
第三章 9页
第四章 5页
第五章 9页
第六章 5页
第七章 1页
1
在技术实施前,必须对拟采用的技术进行深入评估。这包括技术的成熟度,即技术是否已经经过广泛应用并验证其有效性;技术支持,即是否有稳定的技术社区或专业团队提供帮助;以及资源可用性,确保有足够的硬件、软件和人力资源来实现系统建设。此外,还需考虑技术的兼容性、可扩展性和安全性,确保所选技术能够满足当前和未来发展的需求,同时保护系统的稳定性和数据的安全性。
1
2
在国内学者在英文文本分析领域的研究方向主要包括情感分析、主题建模、语义分析和信息提取等。近年来,随着深度学习技术的发展,更多研究开始集中于利用神经网络模型处理复杂的文本分析任务,如长文本生成和细粒度情感分析[2]。中国科学院计算技术研究所、清华大学计算机科学与技术系、北京大学信息科学技术学院等是国内在英文文本分析领域具有重要影响力的研究机构。这些机构通常会在国内外的学术会议和期刊上发布研究成果,比如在业内熟知的ACL(计算语言学年会)和EMNLP(自然语言处理的经验方法会议)。国内研究中常用的技术包括词向量表示、卷积神经网络和递归神经网络,并结合大数据处理技术,如分布式计算框架等。常用的工具包括Python编程语言及其相关库(如NLTK、spaCy)、深度学习框架(如TensorFlow、PyTorch)等。这些技术在提高模型理解能力方面表现出色,但还需要大量标记数据和计算资源,这是一个很大的挑战。还有处理英文文本在多样和复杂语境下的能力仍然需要更深入的研究。
要求: 以上内容包含的东西不变,但是希望字数有800字
1
2
整个数据可视化模块的工作流程大体上,首先获取源文本数据,再将文本数据进行清洗,然后将数据进行格式转化,再将数据传递到可视化工具进行可视化展示。
要求: 以上内容包含的东西不变,但是希望逻辑严谨
1
在数据可视化模块的大体的工作流程中,我们首先需要获取源文本数据。这是整个流程的起点,我们需要确保获取的数据是完整且准确的。接下来,我们需要对获取的文本数据进行清洗。这一步骤非常关键,因为它可以帮助我们去除数据中的无关的信息、错误的数据等。清洗过程需要仔细进行,以确保后续步骤基于的数据是准确且有用的。清洗完数据后,我们需要将数据进行格式转化。这一步骤的目的是将数据转化为适合可视化工具处理的格式。最后一步,我们将处理好的数据传递到可视化工具进行可视化展示。在这个步骤中,我们需要选择合适的可视化方法,以便更好地展示数据的特性和趋势。整个数据可视化模块的工作流程。每一步都需要仔细执行,以确保最终的可视化结果是准确且有意义的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
学生陈述要点:
1. 系统研究背景及意义
2. 系统所使用到的相关技术
3. 系统主要研究的内容
4. 毕业设计论文的展示


老师提出的问题:
1. 数据来源哪里?

2.你读取真题文本里面的数据是怎么处理的,图片怎么筛选掉?

3. 系统的受众用户是谁?

学生回答要点:
第一答: 网站(https://zhenti.burningvocabulary.com/kaoyan)的真题数据。

第二答: PdfReader(pdf_file)读取文件,再通过pdf的extract_text()方法提取文本数据,并在现场打开Pycharm编辑器定位代码位置并且讲解代码。

第三答: 需要考研的大学生、专门辅导考研的培训机构等等。


老师提出的意见:
1. 论文的外文翻译摘要要和正文的摘要样式要统一
2. 将论文的第一章的研究方法二级标题删除
3. 论文当中的代码块背景颜色换成白色
4. 论文当中的可行性分析部分将经济可行性删除掉。