2020年认证杯SPSSPRO杯数学建模D题(第一阶段)让电脑桌面飞起来全过程文档及程序

2020年认证杯SPSSPRO杯数学建模

D题 让电脑桌面飞起来

原题再现:

  对于一些必须每天使用电脑工作的白领来说,电脑桌面有着非常特殊的意义,通常一些频繁使用或者比较重要的图标会一直保留在桌面上,但是随着时间的推移,桌面上的图标会越来越多,有的时候想找到一个马上要用的图标是非常困难的,就比如下图所示的桌面。各种各样的图标会让你眼花缭乱,甚至有的时候反复找好几遍都找不到你想要的图标。其实只要把图标进行有效的分类就可以解决这个问题,但是手工分类往往非常浪费时间,有的时候使用者也会陷入分类决定困难,不知该如何选择。
在这里插入图片描述
  第一阶段问题: 请你的团队建立合理的数学模型,设计一种快速、有效地桌面图标分类的算法,使得能够根据图标的名字进行自动分类,让电脑桌面真正飞起来!这里需要注意的是,应用程序的图标文件不能通过扩展名来区分其功能,只能通过在已有的数据库或者互联网上查询文件名来判断其功能。当然也可以通过机器学习的方式来学习人的分类经验来形成一个分类模式。

整体求解过程概述(摘要)

  随着电脑办公的普及,对于桌面图标的分类整理已成为让很多电脑使用者极为头疼的一件事,无论是专业的计算机开发者还是日常办公人员,进行有效的桌面图标整理工作,对于办公效率提升其价值是不言而喻的,对于桌面图标的有效分类以及桌面区域的划分是解决该问题的有效途径。
  针对图标分类而言,我们获取桌面图标有关的 logo 图像、描述文本、以及近期访问量等三大特征。对于图像特征利用 CNN 进行图像特征提取匹配 logo 相似程度,根据图标名称寻找对应详细的文本介绍借助自然语言处理中的 LDA 主题提取算法,通过计算图标之间有关用途、来源等文本主题进行文本聚类,形成以主题为依据的图标存放单元。针对桌面图标点击量进行排序单独划分访问区域,根据图标 logo 特征提取后的结果结合图标的点击率调整图标的透明度和大小。最后得到五大主题图标区域与两块文件分类区域,在桌面上添加图标搜索栏,以完成对于文档类型图标的快速查找。
  最后利用 ROC 曲线通过新增图标数量判别分类器准确度为 87.8%,通过实际测试得到该模型对于桌面图标查找速度提升为 65%。

问题分析:

  (一)问题一的分析
  对于桌面图标而言,人们往往凭借记忆和直观视觉完成对于所需图标范围的定位与查找,这往往耗费使用者大量时间。因此查找桌面图标时间的长短是衡量桌面图标分类效果的重要标准,与此同时优化图标对于用户的视觉舒适度。首先对于桌面图标需要合理设置若干个基本存放单元[1],将桌面区域进行划分,缩小用户对于所需图标的查找范围,对于新产生的图标可通过分类器判决进入对应的基本存放单元。
  桌面图标包括三个维度的信息:1、所属文件的类型与自然文本 2、图标图像信息 3、近期桌面图标浏览量。首先,利用 CNN 对于图像论文进行特性提取,在输出层外接 LGAM快速训练模型,判决图标之间的相近程度。接着通过图标的名称向 Web 服务器发出请求查找对应名称内容的相应数据库,根据 LDA 主题模型进行主题聚类[2],将同一类型产品进行规律,最终根据用户的使用频率与图标颜色近似程度来改变的图标的透明度,最后留出一块基本存放单元体现桌面图标访问状况。通过桌面图标的访问评论调整图标的大小,并且对于使用频率低于一周一次的图标向用户申请删除命令。于此同时,针对大量同类型图标文件例如 Excel 与 Word 报表,在桌面增添搜索区域增加对于相近文件的区分度。

模型假设:

  1.假设用户对于桌面图标重命名合理(符合图标内容属性);
  2.假设用户图标类型较为常见,不存在大量图标名称极为近似
  3.假设图标的透明度与大小能进行调整
  4.假设图标名称与所关联的文本内容是一致的
  5.假设申请删除某桌面图标的标准为访问周期小于一周

论文缩略图:

在这里插入图片描述

全部论文请见下方“ 只会建模 QQ名片” 点击QQ名片即可

部分程序代码:(代码和文档not free)

import logging
import logging.config
import ConfigParser
import numpy as np
import random
import codecs
import os
from collections import OrderedDict
#获取当前路径
path = os.getcwd()
#导入日志配置文件
logging.config.fileConfig("logging.conf")
#创建日志对象
logger = logging.getLogger()
# loggerInfo = logging.getLogger("TimeInfoLogger")
# Consolelogger = logging.getLogger("ConsoleLogger")
#导入配置文件
conf = ConfigParser.ConfigParser()
conf.read("setting.conf")
#文件路径
trainfile = os.path.join(path,os.path.normpath(conf.get("filepath", "trainfile")))
wordidmapfile = os.path.join(path,os.path.normpath(conf.get("filepath","wordidmapfile")))
thetafile = os.path.join(path,os.path.normpath(conf.get("filepath","thetafile")))
phifile = os.path.join(path,os.path.normpath(conf.get("filepath","phifile")))
paramfile = os.path.join(path,os.path.normpath(conf.get("filepath","paramfile")))
topNfile = os.path.join(path,os.path.normpath(conf.get("filepath","topNfile")))
tassginfile = os.path.join(path,os.path.normpath(conf.get("filepath","tassginfile")))
#模型初始参数
K = int(conf.get("model_args","K"))
alpha = float(conf.get("model_args","alpha"))
beta = float(conf.get("model_args","beta"))
iter_times = int(conf.get("model_args","iter_times"))
top_words_num = int(conf.get("model_args","top_words_num"))
class Document(object):
def __init__(self):
self.words = []
self.length = 0
#把整个文档及真的单词构成 vocabulary(不允许重复)
class DataPreProcessing(object):
def __init__(self):
self.docs_count = 0
self.words_count = 0
#保存每个文档 d 的信息(单词序列,以及 length)
self.docs = []
#建立 vocabulary 表,照片文档的单词
self.word2id = OrderedDict()
def cachewordidmap(self):
with codecs.open(wordidmapfile, 'w','utf-8') as f:
for word,id in self.word2id.items():
f.write(word +"\t"+str(id)+"\n")
class LDAModel(object):
def __init__(self,dpre):
self.dpre = dpre #获取预处理参数
#
#模型参数
#聚类个数 K,迭代次数 iter_times,每个类特征词个数 top_words_num,超参数α(alpha) β(beta)
#
self.K = K
self.beta = beta
self.alpha = alpha
self.iter_times = iter_times
self.top_words_num = top_words_num
#
#文件变量
#分好词的文件 trainfile
#词对应 id 文件 wordidmapfile
#文章-主题分布文件 thetafile
#词-主题分布文件 phifile
#每个主题 topN 词文件 topNfile
#最后分派结果文件 tassginfile
#模型训练选择的参数文件 paramfile
#
self.wordidmapfile = wordidmapfile
self.trainfile = trainfile
self.thetafile = thetafile
self.phifile = phifile
self.topNfile = topNfile
self.tassginfile = tassginfile
self.paramfile = paramfile
# p,概率向量 double 类型,存储采样的临时变量
# nw,词 word 在主题 topic 上的分布
# nwsum,每各 topic 的词的总数
# nd,每个 doc 中各个 topic 的词的总数
# ndsum,每各 doc 中词的总数
self.p = np.zeros(self.K)
# nw,词 word 在主题 topic 上的分布
self.nw = np.zeros((self.dpre.words_count,self.K),dtype="int")
# nwsum,每各 topic 的词的总数
self.nwsum = np.zeros(self.K,dtype="int")
# nd,每个 doc 中各个 topic 的词的总数
self.nd = np.zeros((self.dpre.docs_count,self.K),dtype="int")
# ndsum,每各 doc 中词的总数
self.ndsum = np.zeros(dpre.docs_count,dtype="int")
self.Z = np.array([ [0 for y in xrange(dpre.docs[x].length)] for x in xrange(dpre.docs_count)])
# M*doc.size(),文档中词的主题分布
#随机先分配类型,为每个文档中的各个单词分配主题
for x in xrange(len(self.Z)):
self.ndsum[x] = self.dpre.docs[x].length
for y in xrange(self.dpre.docs[x].length):
topic = random.randint(0,self.K-1)#随机取一个主题
self.Z[x][y] = topic#文档中词的主题分布
self.nw[self.dpre.docs[x].words[y]][topic] += 1
self.nd[x][topic] += 1
self.nwsum[topic] += 1
self.theta = np.array([ [0.0 for y in xrange(self.K)] for x in xrange(self.dpre.docs_count) ])
self.phi = np.array([ [ 0.0 for y in xrange(self.dpre.words_count) ] for x in xrange(self.K)])
def sampling(self,i,j):
#换主题
topic = self.Z[i][j]
#只是单词的编号,都是从 0 开始 word 就是等于 j
word = self.dpre.docs[i].words[j]
#if word==j:
# print 'true'
self.nw[word][topic] -= 1
self.nd[i][topic] -= 1
self.nwsum[topic] -= 1
self.ndsum[i] -= 1
Vbeta = self.dpre.words_count * self.beta
Kalpha = self.K * self.alpha
self.p = (self.nw[word] + self.beta)/(self.nwsum + Vbeta) * \
(self.nd[i] + self.alpha) / (self.ndsum[i] + Kalpha)
#随机更新主题的吗
# for k in xrange(1,self.K):
# self.p[k] += self.p[k-1]
# u = random.uniform(0,self.p[self.K-1])
# for topic in xrange(self.K):
# if self.p[topic]>u:
# break
#按这个更新主题更好理解,这个效果还不错
p = np.squeeze(np.asarray(self.p/np.sum(self.p)))
topic = np.argmax(np.random.multinomial(1, p))
self.nw[word][topic] +=1
self.nwsum[topic] +=1
self.nd[i][topic] +=1
self.ndsum[i] +=1
return topic
def est(self):
# Consolelogger.info(u"迭代次数为%s 次" % self.iter_times)
for x in xrange(self.iter_times):
for i in xrange(self.dpre.docs_count):
for j in xrange(self.dpre.docs[i].length):
topic = self.sampling(i,j)
self.Z[i][j] = topic
logger.info(u"迭代完成。")
logger.debug(u"计算文章-主题分布")
self._theta()
logger.debug(u"计算词-主题分布")
self._phi()
logger.debug(u"保存模型")
self.save()
def _theta(self):
for i in xrange(self.dpre.docs_count):#遍历文档的个数词
self.theta[i] = (self.nd[i]+self.alpha)/(self.ndsum[i]+self.K * self.alpha)
def _phi(self):
for i in xrange(self.K):
self.phi[i] = (self.nw.T[i] + self.beta)/(self.nwsum[i]+self.dpre.words_count * self.beta)
def save(self):
# 保存 theta 文章-主题分布
logger.info(u"文章-主题分布已保存到%s" % self.thetafile)
with codecs.open(self.thetafile,'w') as f:
for x in xrange(self.dpre.docs_count): for y in xrange(self.K):
f.write(str(self.theta[x][y]) + '\t')
f.write('\n')
# 保存 phi 词-主题分布
logger.info(u"词-主题分布已保存到%s" % self.phifile)
with codecs.open(self.phifile,'w') as f:
for x in xrange(self.K):
for y in xrange(self.dpre.words_count):
f.write(str(self.phi[x][y]) + '\t')
f.write('\n')
# 保存参数设置
logger.info(u"参数设置已保存到%s" % self.paramfile)
with codecs.open(self.paramfile,'w','utf-8') as f:
f.write('K=' + str(self.K) + '\n')
f.write('alpha=' + str(self.alpha) + '\n')
f.write('beta=' + str(self.beta) + '\n')
f.write(u'迭代次数 iter_times=' + str(self.iter_times) + '\n')
f.write(u'每个类的高频词显示个数 top_words_num=' + str(self.top_words_num) + '\n')
# 保存每个主题 topic 的词
logger.info(u"主题 topN 词已保存到%s" % self.topNfile)
lda = LDAModel(dpre)
lda.est()
if __name__ == '__main__':
run()
全部论文及程序请见下方“ 只会建模 QQ名片” 点击QQ名片即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/318850.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机创新协会冬令营——暴力枚举题目02

再次欢迎大家参加此次的冬令营,我们协会欢迎所有志同道合的同学们。话不多说,先来看看今天的题目吧。♪(^∇^*) 题目 力扣题号:2367. 算术三元组的数目 注:下述题目和示例均来自力扣 题目 给你一个下标从 0 开始、严格递增 的整…

Winform中使用Websocket4Net实现Websocket客户端并定时存储接收数据到SQLite中

场景 SpringBootVue整合WebSocket实现前后端消息推送: SpringBootVue整合WebSocket实现前后端消息推送_websocket vue3.0 springboot 往客户端推送-CSDN博客 上面实现ws推送数据流程后,需要在windows上使用ws客户端定时记录收到的数据到文件中&#x…

C/C++动态内存分配 malloc、new、vector(简单讲述)

路虽远,行则将至 事虽难,做则必成 今天来主要讲C中动态内存分配 其中会穿插一些C的内容以及两者的比较 如果对C语言中的动态内存分配还不够理解的同学 可以看看我之前的博客:C语言动态分配 在讲解C的动态内存分配之前 我们先讲一下C内存模型 &#xff1…

利用深度学习图像识别技术实现教室人数识别

引言 在现代教育环境中,高效管理和监控教室成为了一个重要议题。随着人工智能技术的迅猛发展,特别是深度学习和图像识别领域的突破,我们现在可以通过智能系统来自动识别教室内的人数,从而实现更加智能化的教室管理。 深度学习与图…

简易机器学习笔记(七)计算机视觉基础 - 常用卷积核和简单的图片的处理

前言 这里实际上涉及到了挺多有关有关理论的东西,可以详细看一下paddle的官方文档。不过我这里不过多的谈有关理论的东西。 【低层视觉】低层视觉中常见的卷积核汇总 图像处理中常用的卷积核 在代码中,我们实际上是用不同的卷积核来造成不同的影响&a…

普中STM32-PZ6806L开发板(资料收集...)

简介 逐渐收集一些开发过程中使用到的文档资料数据手册 DS18B20 数据手册 DS18B20 Datasheet 开发文档 STM32F1各种文档 https://www.st.com/en/embedded-software/stm32cubef1.html#documentation HAL库文档开发文档 你使用的HAL文档, 在STM32CubeMX生成过程的最下面有…

如何在群晖7.2中运行WPS Office镜像容器并使用固定地址公网访问

文章目录 1. 拉取WPS Office镜像2. 运行WPS Office镜像容器3. 本地访问WPS Office4. 群晖安装Cpolar5. 配置WPS Office远程地址6. 远程访问WPS Office小结 7. 固定公网地址 wps-office是一个在Linux服务器上部署WPS Office的镜像。它基于WPS Office的Linux版本,通过…

性能测试之(九):JMeter关联

关联:当请求之间有依赖关系,比如下一个请求的入参是上一个请求返回的数据,这需要进行关联处理; 关联场景1:登录之后返回token,后续的请求需要带token; 常用的关联方法:(在后置处理器…

Unity | 渡鸦避难所-5 | 角色和摄像机之间的遮挡物半透明

1 前言 角色在地图上移动到岩石后面时,完全被岩石遮挡,玩家只能看到岩石。这逻辑看起来没问题,但并不是玩家想要看到的画面,玩家更希望关注角色的状态 为了避免角色被遮挡,可以使用 Cinemachine Collider 功能&#x…

AI:110-基于深度学习的药物分子结构生成与预测

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的关键代码,详细讲解供…

C++面向对象语法总结(二)

目录 《C面向对象语法总结(一)》 十一、继承 继承,可以让子类拥有父类的多有成员(变量、函数)如下面的代码:Student是子类(subclass,派生类),Person是父类(superclass…

echarts点击柱子、线节点、横坐标标签

echarts点击柱子、线节点、横坐标标签 x轴标签要为标签文字添加点击事件,必须先在xAxis里设置响应事件 xAxis: {triggerEvent: true, },然后直接监听 thisChart.on("click" ,function (params) {console.log(params) });通过params.componentSubType来…