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

发布于:2022-11-28 ⋅ 阅读:(251) ⋅ 点赞:(0)

目 录
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()

  }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到