Spark机器学习实验

  • 一、出租车数据分析
    • 1.数据处理
    • 2.数据分析
      • 2.1创建 DataFrame
      • 2.2KMeans 聚类分析
    • 3.百度地图可视化
      • 3.1申请地图 key
      • 3.2聚类结果可视化
  • 二、图书推荐系统
    • 1.Django简介
      • 1.1.ORM 模型
      • 1.2.Template 模板
      • 1.3 View 视图
    • 2.Django 项目搭建
      • 2.1 项目创建
      • 2.2 视图和 URL 配置
      • 2.3 创建应用
      • 2.4 创建模型
      • 2.5 Admin 管理工具
    • 3.推荐引擎设计
      • 3.1导入数据
      • 3.2训练模型
      • 3.3图书推荐
    • 4.系统设计与实现
      • 4.1BootStrap介绍与使用
      • 4.2Redis数据库安装与使用
      • 4.3视图与路由设计
      • 4.4界面设计
    • 5.Issue
    • 6.参考文档
  • 三、转载申明

一、出租车数据分析

出租车是我们经常乘坐的交通工具,但是经常会遇到打车难的问题,给我们生活和工作带来诸多不便。本章介绍 Spark 在人们打车出行生活中的应用,该应用把某地区各出租车实时的并带有地理坐标的 GPS(Global Positioning System)点作为分析对象,使用 Kmeans 聚类方法把出租车轨迹点按簇分类,通过该分类方法找到出租车出现密集的地方,并用地图的方式进行可视化展示,为人们的出行提供新的思路。

本章主要内容如下。
(1)准备数据并对数据特点进行分析。
(2)从文本文件创建 Spark DataFrame。
(3)使用 Spark 的机器学习库 Kmeans 进行聚类。
(4)使用百度地图对聚类的结果进行可视化。

1.数据处理

一般情况下,在进行分析之前需要对数据的分布、状态等有一个整体的了解,从而确定数据使用哪种方法进行分析,进而对数据进行预处理。本章使用文本数据,打开数据观察发现,数据集合中存在缺失项或是 GPS 定位点坐标无效的情况,因此需要对此种情况进行处理。因为出租车点上传的速率非常快并且密度大,所以可以把其中缺失和无效的数据进行删除,对数据分析不会造成较大的影响。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QuzNjsmS-1623383617088)(images/image-20200519094316427.png)]

其中,tid:出租车编号;lat:纬度;lon:经度;time:时间戳;tid 的值相同表示相同的车在不同的时间所处的位置。

2.数据分析

在上一节整理的数据的基础上,使用 Spark 从文本创建 DataFrame,并结合 Kmeans 机器学习聚类方法,实现对出租车在空间位置上的聚类。Kmeans 聚类可根据设定的聚类个数找出若干个聚类中心,对于出租车来讲就是出租车经常出现位置点坐标。

2.1创建 DataFrame

from pyspark.sql import SparkSession
from pyspark import SparkContext
from pyspark.ml.linalg import Vectorssc = SparkContext("local[4]", "taxi")
taxi_data = sc.textFile("datas/taxi.csv")
taxi_rdd = taxi_data.map(lambda line: line.split(','))# 创建矢量 RDD,矢量的两个参数分别为纬度和经度。下面的聚类函数需要 RDD 进行聚类。
taxi_row = taxi_rdd.map(lambda x: (Vectors.dense(x[1], x[2]),))
#显示数据的前五行
print(taxi_row.collect()[:5])
sqlsc = SparkSession.builder.getOrCreate()
taxi_df = sqlsc.createDataFrame(taxi_row, ["features"])

2.2KMeans 聚类分析

KMeans 是最常用的聚类算法之一,它将数据点聚类成预定义的簇数。Spark MLlib 实现了包括一个并行化的 k-means++,称为 kmeans||.。

from pyspark.ml.clustering import KMeans  # 引入聚类包kmeans = KMeans(k=3, seed=1)  # 聚成 3 类
model = kmeans.fit(taxi_df)  # 注意,传入的 DataFrame 是矢量名称为 features 的集合
centers = model.clusterCenters()  # 产生聚类集合
# 聚类的结果是一系列的点集,这些点集也就是出租车聚集的地区,上述代码中将数据聚类成 3 类,如图 9-2 所示。
print(centers)

3.百度地图可视化

通过 Spark 提供的 Kmeans 聚类方法已经找到了出租车聚集的地图坐标,但是并不能清楚地看到具体的位置,因此需要通过可视化的方法把数据在地图上进行展示。百度地图是国内顶级的地图服务提供商之一,在提供了基于位置服务的同时也提供了在不同平台下的对外开放接口,允许用户自定义地图并根据相应业务逻辑开发自己的地理信息应用。本节利用百度地图为开发者提供的第三方开发接口,并对聚类结果进行可视化,让结果的展现更直接。

3.1申请地图 key

在使用百度地图接口之前需要,通过百度地图的一个认证,用户要在百度地图开发平台中申请一个密钥 key。读者可以登录百度地图官网,注册个人账号,然后选择申请 key,申请界面如图:

申请地址:http://lbsyun.baidu.com/

地图Api控制台:http://lbsyun.baidu.com/apiconsole/center#/home

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xfsggRFk-1623383617089)(images/image-20200519102035742.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I6iHEozU-1623383617090)(images/image-20200519102105847.png)]

3.2聚类结果可视化

html文件要在apache或者ngnix服务器中运行,因为百度地图API中设置了白名单。

<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="viewport" content="initial-scale=1.0, user-scalable=no" /><style type="text/css">body,html,#allmap {width: 100%;height: 100%;overflow: hidden;margin: 0;font-family: "微软雅黑";}</style><script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=Dv4X6zApF1yzMQNFoEypNfLX"></script><title>Kmeans 聚类可视化</title>
</head><body><div id="allmap"></div>
</body></html>
<script type="text/javascript">// 百度地图API功能var map = new BMap.Map("allmap");    // 创建Map实例map.enableScrollWheelZoom(); // 允许滑轮进行放大缩小map.centerAndZoom(new BMap.Point(104.01741982, 30.67598985), 13);// 初始位置与范围map.addControl(new BMap.NavigationControl());//  添加平移缩放控件map.addControl(new BMap.ScaleControl());//  添加比例尺控件var myP1 = new BMap.Point(104.01741982, 30.67598985); // 声明点对象var myP2 = new BMap.Point(103.65063611, 30.89504347);var myP3 = new BMap.Point(104.07063581, 30.64562312);map.clearOverlays(); // 清空地图中的对象var marker1 = new BMap.Marker(myP1); // 定义点样式,默认为红色水滴形状var marker2 = new BMap.Marker(myP2);var marker3 = new BMap.Marker(myP3);map.addOverlay(marker1); // 添加点到地图map.addOverlay(marker2);map.addOverlay(marker3);
</script>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lj3ygxcX-1623383617091)(images/image-20200519105430246.png)]

地图

    map.addOverlay(marker2);map.addOverlay(marker3);
</script>

[外链图片转存中…(img-Lj3ygxcX-1623383617091)]

二、图书推荐系统

注意:在使用源代码请把所有<% %>请替换为[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oxpYEXA0-1623383822799)(images/image-20200529210559026.png)],为jekyll编译的问题不能编译通过生成Github Page.

1.Django简介

参照Django菜鸟教程:https://www.runoob.com/django/django-tutorial.html

pip install django

1.1.ORM 模型

对象关系映射 ORM(Object Relational Mapping)是一种在面向对象编程语言里实现不同类型系统数据之间转换的程序技术。

class user(models.Model):#name 字段 max_length 为字段长度, default 为默认值name=model.CharFiled(max_length=50 , default=‘‘)email=model.EmailField()password=model.CharField(max_length=8 , default=‘‘)

1.2.Template 模板

Django 的模板引擎为定义应用程序面向用户的层提供了一种强大的迷你语言,使应用程序和前端逻辑分离。模板由 HTML 和模板语法关键词组成,并不需要用到 Python 的知识。

Django 模板采用前端模块化的思路,可以将模块的前端和后端进行封装,用继承和包含的方法实现模块的重用。HTML 之间可以通过 extends 关键字和 block 关键字进行相互嵌套。

1.base.html

<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>demo</title>
</head>
<body>
<!-- 头部导航区域 -->
<% block top %>
<% endblock %>
<!-- 中部内容区域 -->
<% block content %>
<% endblock %>
<!-- 底部区域 -->
<% block bottom %>
<% endblock %>
</body>
</html>

2.top.html

<% extends 'base.html' %>
<% block top %>
<div><h1> 此处为顶部导航界面 </h1></div>
<% endblock %>

3.content.html

<% extends 'base.html' %>
<% block content %>
<div><h1> 此处为中部内容界面 </h1></div>
<% endblock %>

4.bottom.html

<% extends 'base.html' %>
<% block bottom %>
<div><h1> 此处为底部内容界面 </h1></div>
<% endblock %>

接下来我们需要向Django说明模板文件的路径,修改settings.py,修改 TEMPLATES 中的 DIRS 为**[BASE_DIR+"/templates",]**,如:

TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [BASE_DIR + "/templates", ],'APP_DIRS': True,'OPTIONS': {'context_processors': ['django.template.context_processors.debug','django.template.context_processors.request','django.contrib.auth.context_processors.auth','django.contrib.messages.context_processors.messages',],},},
]

1.3 View 视图

Django 是一种基于 MVT(model,view,template)模型的 Web 开发框架。前端请求的后台响应是通过 view.py 文件中对应的处理函数进行接收请求进行处理。示例代码如下所示。

def index(request):book_list= book.objects.all()usr=request.session.get('user' , None) # 获取当前登录用户名称userid=request.session.get('userid' , None) # 获取当前登录用户的唯一标识 idreturn render(request , 'home/index.html' , locals()) # 渲染主页并向模板传递数据

2.Django 项目搭建

2.1 项目创建

django-admin.py startproject testdjango # startproject :创建项目 film :项目名称

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aqMWbrdi-1623383682886)(images/image-20200526185338773.png)]

  • testdjango: 项目的容器。
  • manage.py: 一个实用的命令行工具,可让你以各种方式与该 Django 项目进行交互。
  • testdjango/init.py: 一个空文件,告诉 Python 该目录是一个 Python 包。
  • testdjango/asgi.py: 一个 ASGI 兼容的 Web 服务器的入口,以便运行你的项目。
  • testdjango/settings.py: 该 Django 项目的设置/配置。
  • testdjango/urls.py: 该 Django 项目的 URL 声明; 一份由 Django 驱动的网站"目录"。
  • testdjango/wsgi.py: 一个 WSGI 兼容的 Web 服务器的入口,以便运行你的项目。
python manage.py runserver 0.0.0.0:8000

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y02ZmFB6-1623383682887)(images/225A52EA-25EF-4BF1-AA5A-B91490CBF26D.jpg)]

2.2 视图和 URL 配置

在先前创建的 testdjango目录下的 testdjango目录新建一个 views.py 文件,并输入代码:

from django.http import HttpResponsedef hello(request):return HttpResponse("Hello world ! ")

接着,绑定 URL 与视图函数。打开 urls.py 文件,删除原来代码,将以下代码复制粘贴到 urls.py 文件中:

from django.urls import pathfrom . import viewsurlpatterns = [path('hello/', views.hello),
]

2.3 创建应用

Django 规定,如果要使用模型,必须要创建一个 app。我们使用以下命令创建一个 TestModel 的 app:

django-admin.py startapp TestModel

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lVuTyBlF-1623383682889)(images/image-20200526190940213.png)]

2.4 创建模型

我们修改 TestModel/models.py 文件,代码如下:

from django.db import models# Create your models here.
class user(models.Model):name = models.CharField(max_length=50, default='')  # 用户名email = models.EmailField()  # 邮箱地址password = models.CharField(max_length=6, default='admin')  # 密码def __str__(self):return self.nameclass Meta:verbose_name = "用户管理"  # 修改 Admin 后台 App 名称verbose_name_plural = "用户管理"class hits(models.Model):userid = models.IntegerField(default=0)bookid = models.IntegerField(default=0)hitnum = models.IntegerField(default=0)def __str__(self):return str(self.userid)class Meta:verbose_name = "单击量"verbose_name_plural = "单击量"class book(models.Model):id = models.CharField(max_length=50, blank=False, verbose_name="ID", default='', primary_key=True)name = models.CharField(max_length=50, blank=False, verbose_name="书名", default='')price = models.CharField(max_length=50, blank=False, verbose_name="价格", default='')cover = models.ImageField(verbose_name="封面", upload_to='upload', default='img/default.png')introduction = models.TextField(verbose_name="介绍", blank=True, default='')url = models.URLField(verbose_name='URL', blank=True, default='')publish = models.CharField(verbose_name=' 出版社 ', max_length=50, default='', blank=True)rating = models.CharField(verbose_name=' 评分 ', max_length=5, default='0')def __str__(self):return self.nameclass Meta:verbose_name = " 图书管理 "verbose_name_plural = " 图书管理 "

接下来在 settings.py 中找到INSTALLED_APPS这一项,如下:

INSTALLED_APPS = ('django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','TestModel',               # 添加此项
)

在命令行中运行:

$ python manage.py migrate   # 创建表结构$ python manage.py makemigrations TestModel  # 让 Django 知道我们在我们的模型有一些变更
$ python manage.py migrate TestModel   # 创建表结构

2.5 Admin 管理工具

Django 提供了基于 web 的管理工具。

Django 自动管理工具是 django.contrib 的一部分。你可以在项目的 settings.py 中的 INSTALLED_APPS 看到它:

INSTALLED_APPS = ('django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles',
)

通常我们在生成项目时会在 urls.py 中自动设置好,我们只需去掉注释即可。

from django.contrib import admin
from django.urls import pathurlpatterns = [path('admin/', admin.site.urls),
]

你可以通过命令 python manage.py createsuperuser 来创建超级用户,如下所示:

# python manage.py createsuperuser

启动开发服务器,然后在浏览器中访问 http://127.0.0.1:8000/admin/,得到如下界面:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lH4VaHkr-1623383682890)(images/admin1.png)]

之后输入用户名密码登录,界面如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ChjvPt9Z-1623383682891)(images/A995340B-8F8C-4777-9B79-846B6A34508A.jpg)]

3.推荐引擎设计

3.1导入数据

本章实验数据来自 GitHub 共享者 moverzp 提供的 GoodBooks 数据集,读者可以在 GitHub中搜索 moverzp 即可找到该贡献者的仓库。 该数据集抓取自豆瓣图书网站,一共有 5 万多条,主要包含序号、书名、评分、价格、出版社、爬取链接的地址,数据格式如图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MY1dN0ZY-1623383682892)(images/image-20200527171230075.png)]

为了在网页前端界面上进行展示,并对图书信息进行查看,需要先将图书信息导入到数据库中。该实验主要使用的 Django 自动生成的 SQLite 数据库进行数据存储,通过 Python 脚本把 csv格式文件导入到数据库中。其主要思路是通过在前端单击浏览按钮选择图书表格上传到后台,后台接收到 csv 文件后进行解析,通过 Python 代码打开文件并逐条将数据写入到数据库中,核心代码如下。

# 上传图书数据到服务器端并入库
def handle_upload_file(name, file):path = os.path.join(settings.BASE_DIR, 'uploads')  # 服务器上传地址fileName = path + '/' + name  # 文件名with open(fileName, 'wb') as destination:  # 接收数据并保存到服务器端for chunk in file.chunks():destination.write(chunk)insertToSQL(fileName)  # 将数据插入到数据库中def insertToSQL(fileName):txtfile = open(fileName, 'r', encoding='UTF-8')for line in txtfile.readlines():  # 逐行读取数据try:bookinfo = line.split(',')  # 数据按照逗号切分获取各个字段id = bookinfo[0].decode().encode('utf-8')  # 图书编号name = bookinfo[1].decode().encode('utf-8')  # 图书名称rating = bookinfo[2].decode().encode('utf-8')  # 图书评分得分price = bookinfo[3].decode().encode('utf-8')  # 图书价格publish = bookinfo[4].decode().encode('utf-8')  # 出版社url = bookinfo[5].decode().encode('utf-8')  # 豆瓣链接try:# 创建图书对象bk_entry = book(name=name, price=price, url=url, publish=publish, rating=rating)bk_entry.save()  # 插入数据到数据库except:print('save error' + id)except:print('read error ' + id)def importBookData(request):if request.method == 'POST':file = request.FILES.get('file', None)  # 获取上传的文件信息if not file:return HttpResponse('None File uploads !')else:name = file.namehandle_upload_file(name, file)return HttpResponse('success')return render(request, 'upload.html')

3.2训练模型

因为用户在访问图书网站的时候不一定会对图书进行评分,所以不根据用户评分来进行训练模型,而根据用户的浏览记录进行相似性推荐。在项目的后台业务逻辑中会收集用户的单击事件,记录下用户 id、图书 id 以及单击的次数等信息,数据格式如表:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pJWBnfPQ-1623383682893)(images/image-20200527194253126.png)]

因为不根据用户评分进行训练,所以在训练时候采用隐式评分模型,核心代码如下:

from pyspark import SparkContext
from pyspark.sql import SparkSession, Row
from pyspark.mllib.recommendation import ALS
import os
import shutilsc = SparkContext()  # 获取 Spark 上下文
txt = sc.textFile('datas/hit.txt')  # 读取本地用户浏览记录文件
ratingsRDD = txt.flatMap(lambda x: x.split()).map(lambda x: x.split(','))  # 用户记录转换为 RDD
sqlContext = SparkSession.builder.getOrCreate()  # 创建 sqlContextuser_row = ratingsRDD.map(lambda x: Row(  # 将 RDD 转换成行数据userid=int(x[0]), bookid=int(x[1]), hitnum=int(x[2])
))
user_df = sqlContext.createDataFrame(user_row)
user_df.registerTempTable('test')  # 登录临时表
datatable = sqlContext.sql("select userid, bookid, sum(hitnum) as hitnum from test group by userid , bookid")  # 统计用户单击过得图书次数
bookrdd = datatable.rdd.map(lambda x: (x.userid, x.bookid, x.hitnum))
model = ALS.trainImplicit(bookrdd, 10, 10, 0.01)  # 训练模型if os.path.exists('recommendModel'):  # 判断是否存在模型文件夹shutil.rmtree('recommendModel')  # 递归删除文件夹
model.save(sc, 'recommendModel')  # 保存模型到本地

3.3图书推荐

模型训练完毕后,可以通过 MatrixFactorizationModel 类的 load 方法加载模型,该方法有两个参数,第一个参数 spark 初始化上下文,第二个参数为用户的编号,可以通过 recommendProducts函数对用户进行图书推荐,该函数有两个参数,第一个参数为用户编号,第二个编号为推荐的图书数量,可以通过前端请求灵活设定推荐的数目。对用户推荐的结果存到 Redis 内存数据库中,后台定时执行该训练代码更新数据库,随着用户浏览量的增加和系统用户量的增加,推荐会越来越准确。

import redis
from pyspark import SparkContext
from pyspark.mllib.recommendation import MatrixFactorizationModelpool = redis.ConnectionPool(host='localhost', port=6379)
redis_client = redis.Redis(connection_pool=pool)
sc = SparkContext()def getRecommendByUserId(userid, rec_num):try:model = MatrixFactorizationModel.load(sc, 'recommendModel')result = model.recommendProducts(userid, rec_num)temp = ''for r in result:temp += str(r[0]) + ',' + str(r[1]) + ',' + str(r[2]) + '|'redis_client.set(userid, temp)print('load model success ---' + temp)except Exception as e:print('load model failed!' + str(e))sc.stop()getRecommendByUserId(1, 5)

4.系统设计与实现

4.1BootStrap介绍与使用

Bootstrap 是 Twitter 推出的一个用于前端开发的开源工具包。它由 Twitter 的设计师 Mark Otto和 Jacob Thornton 合作开发,是一个 CSS/HTML 框架。

BootStrap中文网:https://www.bootcss.com/

Bootstrap 教程:https://www.runoob.com/bootstrap/bootstrap-tutorial.html

Bootstrap 已经定义了包括按钮、表单、表格等基本元素在内的多种不同的样式,不需要开发者再去重新写 css 样式去控制外观。同时 Bootstrap 还提供了栅格布局结构,可以通过简单的 class设置即可实现响应式布局以适应不同屏幕尺寸的终端。

bootstrap除了包含一个css文件之外还包含有BootStrap.min.js文件,因为js文件是基于JQuery开发的,所以在引用 bootstrap 时候需要先引入 jquery,引用方式如下。

<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

注:使用 cdn 时候,如果网络连接断开会导致样式访问不到,网站排版错乱。

4.2Redis数据库安装与使用

Redis教程:https://www.runoob.com/redis/redis-tutorial.html

Python redis 使用介绍:https://www.runoob.com/w3cnote/python-redis-intro.html

pip3 install redis

简单实例:

import redis   # 导入redis 模块r = redis.Redis(host='localhost', port=6379, decode_responses=True)
r.set('name', 'runoob')  # 设置 name 对应的值
print(r['name'])
print(r.get('name'))  # 取出键 name 对应的值
print(type(r.get('name')))  # 查看类型

连接池:

import redis    # 导入redis 模块pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
r = redis.Redis(connection_pool=pool)
r.set('name', 'runoob')  # 设置 name 对应的值
print(r.get('name'))  # 取出键 name 对应的值

4.3视图与路由设计

视图views.py需要应用的包:

from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect
import osfrom testdjango import settings
from .models import *
from utils import tools
import redis

(1)创建用户登录视图

def login(request):if request.method == 'POST':  # 相应前台的 POST 事件name = request.POST.get('name')  # 接收前台传递的用户名password = request.POST.get('password')  # 接收前台传递的密码userEntry = user.objects.filter(name=name, password=password)  # 查询数据库if userEntry.exists():  # 判断是否存在用户request.session['user'] = name  # 用户名写入到 session 会话request.session['userid'] = userEntry[0].idreturn HttpResponseRedirect('/')return render(request, 'login.html')

(2)创建用户注册视图,核心代码如下

def register(request):if request.method == 'POST':name = request.POST.get('name')password = request.POST.get('password')userEntry = user(name=name, password=password)userEntry.save()return HttpResponseRedirect('/login/')return render(request, 'register.html', locals())

(3)创建用户单击视图,核心代码如下

def getBookInfo(request):id = request.GET.get('id')bk = book.objects.get(id=id)# 设置单击量username = request.session.get('user', None)currentuser = user.objects.get(name=username)try:hit = hits.objects.get(userid=currentuser.id, bookid=id)hit.hitnum += 1hit.save()except:hit = hits()hit.bookid = idhit.hitnum = 1hit.userid = currentuser.idhit.save()data = str(currentuser.id) + ',' + str(id) + ',' + str(1)tools.writeToLocal('datas/hit.txt', data)return render(request, 'detail.html', locals())

(4)创建主页,核心代码如下

def index(request):book_list = book.objects.all()usr = request.session.get('user', None)userid = request.session.get('userid', None)return render(request, 'index.html', locals())

(5)创建推荐视图,核心代码如下

pool = redis.ConnectionPool(host='localhost', port=6379)
redis_client = redis.Redis(connection_pool=pool)def getRecommendBook(request):userid = request.session.get('userid', None)recommendbook = redis_client.get(int(userid))booklist = str(recommendbook).split('|')bookset = []for bk in booklist[:-1]:bookid = bk.split(',')[1]bk_entry = book.objects.get(id=bookid)bookset.append(bk_entry)return render(request, 'recommend.html', locals())

(6)路由设计,核心代码如下

from django.contrib import admin
from django.urls import path
from TestModel import viewsurlpatterns = [path('admin/', admin.site.urls),path('hello/', views.hello),path('/', views.index),path('importBookData/', views.importBookData),path('login/', views.login),path('register/', views.register),path('getBookInfo/', views.getBookInfo),path('getRecommendBook/', views.getRecommendBook),
]

(7)在项目的根路径下新建utils包,并新建tools.py,内容如下:

def writeToLocal(filepath, str):ft = open(filepath, "a+")ft.writelines(str + '\n')ft.close()

4.4界面设计

在项目的路径下新增templates目录,分别新建下面的文件:

(1)base.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>图书推荐系统</title><link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body><!-- 中部内容区域 --><div class="container"><div class="row" ><div class="col-md-6"><% block content %><% endblock %></div></div></div><script src="https://cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script><script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script></body>
</html>

(2)login.html

<% extends 'base.html' %>
<% block content %><form action="/login/" method="post"><% csrf_token %><div class="form-group"><label for="name">用户名</label><input type="text" class="form-control" id="name" name="name" placeholder="请输入用户名"></div><div class="form-group"><label for="name">密码</label><input type="password" class="form-control" id="password" name="password" placeholder="请输入密码"></div><button type="submit" class="btn btn-default">登录</button><a href="/register/" class="btn btn-primary">注册</a></form>
<% endblock %>

(3)register.html

<% extends 'base.html' %>
<% block content %><form action="/register/" method="post"><% csrf_token %><div class="form-group"><label for="name">用户名</label><input type="text" class="form-control" id="name" name="name" placeholder="请输入用户名"></div><div class="form-group"><label for="password">密码</label><input type="password" class="form-control" id="password" name="password" placeholder="请输入密码"></div><button type="submit" class="btn btn-default">注册</button></form>
<% endblock %>

(4)index.html

<% extends 'base.html' %>
<% block content %><table class="table"><caption>图书列表</caption><thead><tr><th>ID</th><th>名称</th><th>价格</th></tr></thead><tbody><% for book in book_list %><tr><td><a href="/getBookInfo/?id={{ book.id }}">{{ book.id }}</a></td><td>{{ book.name }}</td><td>{{ book.price }}</td></tr><% endfor %></tbody></table><a href="/getRecommendBook/" class="btn btn-primary">我的推荐列表</a>
<% endblock %>

(5)detail.html

<% extends 'base.html' %>
<% block content %><form><div class="form-group"><label for="name">书名</label><input type="text" class="form-control" id="name" name="name" value="{{ bk.name }}" disabled></div><div class="form-group"><label for="name">出版社</label><input type="text" class="form-control" id="publish" name="publish" value="{{ bk.publish }}" disabled></div><div class="form-group"><label for="name">价格</label><input type="text" class="form-control" id="price" name="price" value="{{ bk.price }}" disabled></div><div class="form-group"><label for="name">评分</label><input type="text" class="form-control" id="name" name="name" value="{{ bk.rating }}" disabled></div><div class="form-group"><label for="name">URL</label><input type="text" class="form-control" id="url" name="url" value="{{ bk.url }}" disabled></div><a href="/" class="btn btn-primary">返回</a></form>
<% endblock %>

(6)recommend.html

<% extends 'base.html' %>
<% block content %><table class="table"><caption>推荐列表</caption><thead><tr><th>ID</th><th>名称</th><th>价格</th></tr></thead><tbody><% for book in bookset %><tr><td><a href="/getBookInfo/?id={{ book.id }}">{{ book.id }}</a></td><td>{{ book.name }}</td><td>{{ book.price }}</td></tr><% endfor %></tbody></table><a href="/" class="btn btn-primary">返回</a>
<% endblock %>

(7)upload.html

<% extends 'base.html' %>
<% block content %><form action="/importBookData/" method="post" enctype="multipart/form-data"><% csrf_token %><label> 请选择上传的文件: </label><input class="form-control" type="file" name="file"><button class="btn btn-primary" type="submit"> 上传 </button></form>
<% endblock %>

5.Issue

1.django.template.exceptions.TemplateDoesNotExist: upload.html

解决方案:

  • 在项目的目录下面新增templates目录
  • 在settings.py的TEMPLATES中修改DIRS设置,添加模板路径

2.RuntimeError: You called this URL via POST, but the URL doesn’t end in a slash and you have APPEND_SLASH set

解决方案:在settings.py中设置APPEND_SLASH = False

3.Forbidden (CSRF token missing or incorrect.)

解决方案:https://blog.csdn.net/weixin_42694291/article/details/86165884

确认settings.py中MIDDLEWARE的有:django.middleware.csrf.CsrfViewMiddleware

html中的form添加模板标签<% csrf_token %>

6.参考文档

  1. Django教程 https://www.runoob.com/django/django-tutorial.html
  2. 基于Spark ALS算法的个性化推荐:https://www.cnblogs.com/wheng/p/11795268.html
  3. Redis教程:https://www.runoob.com/redis/redis-tutorial.html
  4. BootStrap中文网:https://www.bootcss.com/
  5. Bootstrap 教程:https://www.runoob.com/bootstrap/bootstrap-tutorial.html

三、转载申明

本文转自csdn、博客园多个网站汇总所得,属于个人笔记,不与转载

Spark机器学习实验相关推荐

  1. 【Spark】实验6 Spark机器学习库MLlib编程实践

    Spark机器学习库MLlib编程实践 一.实验目的 通过实验掌握基本的MLLib编程方法: 掌握用MLLib解决一些常见的数据分析问题,包括数据导入.成分分析和分类和预测等. 二.实验平台 新工科智 ...

  2. 还在用Tensorboard?机器学习实验管理平台大盘点

    文 | SisyphusBJ 源 | Pytorch Lightning wandb.ai comet.ml neptune.ai allegro trains mlflow guild.ai sac ...

  3. Spark机器学习管道 - Pipeline

    Spark机器学习管道 - Pipeline 一.实验目的 二.实验内容 三.实验原理 四.实验环境 五.实验步骤 5.1 启动Spark集群和Zeppelin服务器. 5.2 使用管道创建一个小型工 ...

  4. 手把手带你玩转Spark机器学习-使用Spark构建回归模型

    系列文章目录 手把手带你玩转Spark机器学习-专栏介绍 手把手带你玩转Spark机器学习-问题汇总 手把手带你玩转Spark机器学习-Spark的安装及使用 手把手带你玩转Spark机器学习-使用S ...

  5. Spark机器学习管道 - Estimator

    Spark机器学习管道 - Estimator 一.实验目的 二.实验内容 三.实验原理 四.实验环境 五.实验步骤 5.1 启动Spark集群和Zeppelin服务器. 5.2 使用IDF esti ...

  6. 基于大数据的Uber数据实时监控(Part 1:Spark机器学习)

    导言 据Gartner称:到2020年,25亿辆联网汽车将成为物联网的主要对象.联网车辆预计每小时可以生成25GB的数据,对这些数据进行分析实现实时监控.大数据目前是10个主要领域之一,利用它可以使城 ...

  7. 用Spark机器学习数据流水线进行广告检测

    在这篇文章中,我们Spark的其它机器学习API,名为Spark ML,如果要用数据流水线来开发大数据应用程序的话,这个是推荐的解决方案.关键点: 了解机器学习数据流水线有关内容. 怎么用Apache ...

  8. Spark机器学习9· 实时机器学习(scala with sbt)

    Spark机器学习 1 在线学习 模型随着接收的新消息,不断更新自己:而不是像离线训练一次次重新训练. 2 Spark Streaming 离散化流(DStream) 输入源:Akka actors. ...

  9. Apache Spark机器学习.1.7 机器学习工作流示例

    1.7 机器学习工作流示例 为了进一步了解学习机器学习的工作流,在这里让我们学习一些例子. 本书后续章节会研究风险建模.欺诈检测.客户视图.流失预测和产品推荐.对于诸如此类的项目,目标往往是确定某些问 ...

  10. Spark机器学习MLlib系列1(for python)--数据类型,向量,分布式矩阵,API

    Spark机器学习MLlib系列1(for python)--数据类型,向量,分布式矩阵,API 关键词:Local vector,Labeled point,Local matrix,Distrib ...

最新文章

  1. iis6中FTP配置的技巧和细节
  2. Windows10下搭建Java环境(最新教程)
  3. Linux内核分析 - 网络[十六]:TCP三次握手
  4. 图像传感器与信号处理——详解CCD与CMOS图像传感器
  5. 数据库语法_圣诞快乐:用GaussDB T 绘制一颗圣诞树,兼论高斯数据库语法兼容...
  6. java 删除桌面快捷方式_能否在桌面创建快捷方式运行java程序?
  7. 河南城镇化争植“智慧”基因
  8. 身材太好的女生在职场中有哪些劣势?
  9. 实验一 线性表的顺序存储与实现_线性表的存储结构(java)
  10. 电子书 Java程序员面试宝典(第4版).pdf
  11. 关于pr(premier)2020不能使用beat edit的解决方法
  12. Klari汽车静态电流(暗电流)测试数据采集系统专用电流探头
  13. 计算机网络物理层测试
  14. /Volumes/TeXLive2019/install-tl: No binary platform specified/available, quitting.
  15. AntV X6源码简析
  16. 与其被生活逼,不如被自己逼
  17. 2021蓝牙耳机选购清单:高颜值、高颜值、降噪,五款蓝牙耳机推荐
  18. js实现图片左右移动轮播
  19. 学徒浅析Android——Android7.0(N)对于自定义证书和非CA机构证书的适配校验
  20. Flutter基础之部分控件学习

热门文章

  1. 实战 Mantle 解析界面app 科技频道
  2. 我的世界java版的名字是独一无二吗_2018独一无二霸气网名,二字网名超拽霸气冷酷...
  3. 采样频率Hz 采样率KSPS或MSPS,两种单位的换算关系
  4. 百度贴吧恶意代码分析
  5. 无人机学习笔记 8 雷达工作波段划分
  6. 经济学计算机是必修课吗,大学中经济学专业的每年的必修课是什么?例如...
  7. 算法——最短路径应用
  8. 百度导航5.0之后的坑
  9. pytorch和python的区别_Keras和PyTorch的视觉识别与迁移学习对比
  10. privilege权限级别的命令介绍及实例分析