草庐IT

美食推荐系统的设计与实现

biyezuopinvip 2023-04-08 原文

目 录
1绪论 1
1.1课题背景及意义 1
1.2课题研究现状 1
1.3课题主要研究内容 2
2相关技术 3
2.1系统开发模式 3
2.2 JSP开发技术 4
2.3 MySQL数据库 5
2.4 Html5 6
2.5 DIV+CSS简介 6
2.5个性化推荐技术 7
3系统分析 10
3.1系统可行性分析 10
3.2系统功能需求分析 10
3.3系统流程分析 10
4系统设计 12
4.1总体设计原则 12
4.2系统功能结构设计 12
4.3系统数据库设计 13
5 系统实现 16
5.1 Html5网页前端 16
5.1.1注册登录模块 16
5.1.2首页餐厅美食推荐列表模块 17
5.1.3热销推荐模块 18
5.2后台管理端 20
5.2.1管理员登录模块 20
5.2.2菜品管理模块 21
6 系统测试 23
6.1 软件测试的目的和原则 23
6.2 测试环境 24
6.3 软件测试 24
总结 26
参考文献 27
致谢 28

课题设计推荐系统是一款美食推荐系统,该系统是基于C/S+B/S模式来设计,技术上采用Html5+JSP网页技术+个性化推荐技术开发,利用Java技术来实现,通过MySQL数据库来存取美食推荐系统相关的信息,Html5注册用户和商家用户可餐厅美食推荐列表、购物车订单及个人中心等,后台管理端可对菜品信息、菜品类别信息、优惠资讯管理、订单管理、统计及用户管理等。
3系统分析
3.1系统可行性分析
(1)技术可行性:开发这套河池学院美食推荐系统B/S架构的Java+SSM+HTML技术来实现;以Html5开发者工具进行开发,采用MySQL数据库来储存平台系统数据,使用最经典的协同过滤算法来推荐排名,以上的Html5和网站开发组合已被大量的Html5应用所证明,运行稳定可靠,可作为学院美食推荐运算推荐的开发技术,因此技术上可行。
(2)经济可行性:Html5是集合在上的功能,所以并不需要安装或者是下载,只需要人力物力的投入,时间上也合适,不需要很多额外支出,后期可以通过推广商铺来收取一定的利益,因此具有经济可行性。
(3)操作可行性:本系统实现了用户与数据库的互动,界面简单友好,操作方便。能够为用户提供更加具体的商铺数据。与此同时对于许多客户来说,Html5不占用手机的内存,而且也不受手机系统的限制,本文转载自http://www.biyezuopin.vip/onews.asp?id=14103可以使用起来特别的快捷,具有操作可行性。
(4)法律可行性:是合法的研究方向课题,符合法律要求。
系统可行性分析从技术可行性、经济可行性、运行可行性以及法律可行性等方面分析。
3.2系统功能需求分析
课题设计美食推荐系统包括Html5前端和后台管理端两个部分,注册用户和商家用户可餐厅美食推荐列表、购物车订单及个人中心等,后台管理端可对菜品信息、菜品类别信息、优惠资讯管理、订单管理、统计及用户管理等。
3.3系统流程分析
登录是使用该美食推荐系统的入口,只有合法用户方可使用软件,同时系统会根据用户属性分配不同的用户权限,进入不同的业务界面操作不同的业务模块。

package com.share.spark.project.spark

import com.share.spark.project.dao.CourseClickCountDAO
import org.apache.hadoop.hbase.HBaseConfiguration
import org.apache.hadoop.hbase.client.Result
import org.apache.hadoop.hbase.io.ImmutableBytesWritable
import org.apache.hadoop.hbase.mapreduce.TableInputFormat
import org.apache.hadoop.hbase.util.Bytes
import org.apache.log4j.{Level, Logger}
import org.apache.spark.mllib.recommendation.{ALS, Rating}
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.streaming.kafka.KafkaUtils
import org.apache.spark.streaming.{Seconds, StreamingContext}

/**
  * 使用Spark 和 Spark Streaming 分别对用户产生离线和实时的推荐结果
  */
object FoodRecommendStreamingApp {
  def main(args: Array[String]): Unit = {
    if (args.length != 4) {
      System.err.println("Usage: KafkaReceiverWordCount <zkQuorum> <group> <topics> <numThreads>")
      System.exit(1)
    }

    //设置日志提示等级
    Logger.getLogger("org.apache.spark").setLevel(Level.WARN)

    //args为 hadoop:2181 test streamingtopic 1
    val Array(zkQuorum, group, topics, numThreads) = args

    val sparkConf = new SparkConf().setAppName("FoodRecommendStreamingApp").setMaster("local[2]").set("spark.akka.frameSize", "2000").set("spark.network.timeout", "1200")
    val sparkContext = new SparkContext(sparkConf)
    val hbaseConf = HBaseConfiguration.create()
    hbaseConf.set("hbase.zookeeper.quorum", "hadoop")
    hbaseConf.set("hbase.zookeeper.property.clientPort", "2181")
    hbaseConf.set("zookeeper.session.timeout", "6000000")

    println("\n=====================step 2 load data==========================")
    //加载HBase中的数据

    //读取数据并转化成rdd
    hbaseConf.set(TableInputFormat.INPUT_TABLE, "ratings")
    val ratingsData = sparkContext.newAPIHadoopRDD(hbaseConf, classOf[TableInputFormat],
      classOf[ImmutableBytesWritable],
      classOf[Result])

    val hbaseRatings = ratingsData.map { case (_, res) =>
      val foodId = Bytes.toString(res.getValue(Bytes.toBytes("info"), Bytes.toBytes("fid")))
      val rating = Bytes.toString(res.getValue(Bytes.toBytes("info"), Bytes.toBytes("rating")))
      val userId = Bytes.toString(res.getValue(Bytes.toBytes("info"), Bytes.toBytes("uid")))
      Rating(userId.toInt, foodId.toInt, rating.toDouble)
    }.cache()

    val numTrainRatings = hbaseRatings.count()
    println(s"[DEBUG]get $numTrainRatings train data from hbase")

    val rank = 10
    val lambda = 0.01
    val numIter = 10

    //第一次运行,初始化用户的推荐信息

    println("\n=====================system initiallizing...==========================")
    println("\n[DEBUG]training model...")
    val firstTrainTime = System.nanoTime()
    val model = ALS.train(hbaseRatings, rank, numIter, lambda)
    val firstTrainEndTime = System.nanoTime() - firstTrainTime
    println("[DEBUG]first training consuming:" + firstTrainEndTime / 1000000000 + "s")

    println("\n[DEBUG]save recommended data to hbase...")
    val firstPutTime = System.nanoTime()

    //为每一个用户产生初始的推荐食物,取top10
    for (i <- 1 to 60) {
      val topRatings = model.recommendProducts(i, 10)
      var recFoods = ""
      for (r <- topRatings) {
        val rating = r.rating.toString.substring(0, 4)
        recFoods += r.product + ":" + rating + ","
      }
      CourseClickCountDAO.put("users", i.toString, "info", "recFoods", recFoods.substring(0, recFoods.length - 1))
    }
    val firstPutEndTime = System.nanoTime() - firstPutTime
    println("[DEBUG]finish job consuming:" + firstPutEndTime / 1000000000 + "s")


    //实时推荐引擎部分
    println("\n=====================start real-time recommendation engine...==========================")
    val streamingTime = 120
    println(s"[DEBUG]The time interval to refresh model is: $streamingTime s")

    //接受实时的用户行为数据
    //    val streamingContext = new StreamingContext(sparkContext, Seconds(streamingTime))
    //    val ssc = new StreamingContext(sparkContext, Seconds(60))


    val ssc = new StreamingContext(sparkContext, Seconds(10))
    val topicMap = topics.split(",").map((_, numThreads.toInt)).toMap

    // TODO... Spark Streaming 如何对接 Kafka

    val logs = KafkaUtils.createStream(ssc, zkQuorum, group, topicMap).map(_._2)
    val cleanData = logs.map(line => {
      val infos = line.split("::")
      Rating(infos(0).toInt, infos(1).toInt, infos(2).toDouble)
    })

    var allData = hbaseRatings
    allData.cache.count()
    hbaseRatings.unpersist()
    var index = 0
    cleanData.foreachRDD { rdd =>
      index += 1
      println("\n[DEBUG]this round (" + index + ") received: " + rdd.count + " data lines.")
      val refreshStartTime = System.nanoTime()
      val tmpData = allData.union(rdd).cache
      tmpData.count()
      allData = tmpData
      tmpData.unpersist()
      allData = allData.union(rdd).repartition(10).cache()
      val model = ALS.train(allData, rank, numIter, lambda)
      val refreshEndTime = System.nanoTime() - refreshStartTime
      println("[DEBUG]training consuming:" + refreshEndTime / 1000000000 + " s")
      println("[DEBUG]begin refresh hbase user's recBooks...")
      val refreshAgainStartTime = System.nanoTime()

      //只更新当前有行为产生的用户的推荐数据
      val usersId = rdd.map(_.user).distinct().collect()
      for (u <- usersId) {
        val topRatings = model.recommendProducts(u, 10)
        var recFoods = ""
        for (r <- topRatings) {
          val rating = r.rating.toString.substring(0, 4)
          recFoods += r.product + ":" + rating + ","
        }
        CourseClickCountDAO.put("users", u.toString, "info", "recFoods", recFoods.substring(0, recFoods.length - 1))
      }
      val refreshAgainConsumingTime = System.nanoTime() - refreshAgainStartTime
      println("[DEBUG]finish refresh job,consuming:" + refreshAgainConsumingTime / 1000000000 + " s")
    }

    ssc.start()
    ssc.awaitTermination()
    sparkContext.stop()

  }
}






























有关美食推荐系统的设计与实现的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  3. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  4. ruby-on-rails - Rails 中的推荐引擎 - 2

    我想为我的Rails网络应用程序提供推荐功能。特别是,我想向新注册的用户推荐他可能想要关注的其他用户。Rails中是否有用于此目的的引擎/gem?如果没有,我应该从哪里开始构建它?谢谢。 最佳答案 有Coletivogemhttps://github.com/diogenes/coletivo我试了一下。在MySQL上运行。Neo4jhttp://neo4j.org真的很容易实现一个“跟随谁”。事实上,大多数展示其能力的样本都涉及“跟随谁”。快速提示-只有在JRuby上运行时,Neo4j.rb才会很酷。如果不是-使用Neograph

  5. 电脑0x0000001A蓝屏错误怎么U盘重装系统教学 - 2

      电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。  准备工作:  1、U盘一个(尽量使用8G以上的U盘)。  2、一台正常联网可使用的电脑。  3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。  4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。  U盘启动盘制作步骤:  注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注

  6. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  7. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  8. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  9. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  10. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

随机推荐