您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > Python

如何使用 Python 构建推荐引擎?

时间:2020-08-24 12:10:20  来源:CSDN  作者:
如何使用 Python 构建推荐引擎?

作者 | Craig Kerstiens

译者 | 弯月,责编 | 王晓曼

头图 | CSDN 下载自东方IC

出品 | CSDN(ID:CSDNnews)

以下为译文:

我非常喜欢数据。数据可以告诉你用户在干什么,还可以提供各种深刻的见解。数据应用的一个方面就是根据历史记录或用户做出的类似选择来提供建议。

其实,多年以前,我写了一个很小的应用程序,尝试根据葡萄酒的等级来推荐葡萄酒。这是一个小应用,我只分享给了几个好友,他们中有些人与我有相似的品味,而有些人则有不同的品味。

最初,我主要是为了研究如何编写推荐引擎,但如果能够顺便找到一些喜欢的新酒,那就是意外之喜了。事实证明,尽管只有少数几种葡萄酒的评分,但这款应用的推荐依然超出了我的预期。

另外,我也很喜欢 Postgres(不奇怪吧),最近我一直在想为什么我不能直接在 Postgres 中研究机器学习呢。没错,我们有 madlib,但是我想编写自己的推荐引擎。于是,我做了简单的尝试,结果发现我可以在 Postgres 中做很多事情。下面就让我来介绍一下如何在 Postgres 内快速构建一个推荐引擎。

 

从现有代码着手

首先,我快速浏览了 Python 推荐的一些示例引擎。为了简单起见,我想建立一款更小巧、更简洁的应用,我并不介意使用其它库。后来,我找到了一个简洁的rec-engine(https://github.com/scottfitzcodes/rec-engine-example)示例,该示例利用了 Pandas 和简单的数据模型大幅降低了构建推荐引擎的难度。

 

设置初始表结构

我抽取了该示例应用程序使用的数据集,并将其转换为 SQL 进行加载:


 

CREATE TABLE orders (id int, product_idint);

CREATE TABLE products(id serial, nametext);

INSERT INTO orders

VALUES (1,1),(1,2),(2,3),(2,10),(2,13),(3,3),(4,8),(4,9),(4,12),(5,3),(5,5),(5,7),(5,12),(6,1),(7,5),(7,13),(8,4),(9,3),(10,3),(10,13),(11,1),(11,8),(11,4),(12,8),(12,12),(13,5),(13,2),(13,7),(14,3),(14,13),(14,5),(15,3),(15,13);

INSERT into products ("name")

VALUes ('Baseball Bat'), ('BaseballGlove'), ('Football'), ('Basketball Hoop'), ('Football Helmet'), ('BattingGloves'), ('Baseball'), ('Hockey Stick'), ('Ice Skates'), ('Soccer Ball'),('Goalie Mask'), ('Hockey Puck'), ('Cleats');

 

 

加载DataFrame

该 Python 示例直接从 CSV 加载了 DataFrame。但我想在 Postgres 中构建应用。通过上面一步,我将所有数据都存储在了表中,但是如今将其放入DataFrame中……我不是很想再解析成CSV格式。

解决这个问题的方法有很多种(比如创建 JSONB 对象、创建自定义类型等),但我选择了一种非常简单而且很容易实现的方法:将两个数组按照相同的方式排序,然后利用这两个数组创建DataFrame。

为此,我定义了一个函数,并导入了pandas:


 

CREATE OR REPLACE FUNCTIONgetrecommendations (id integer, orderids int[], orderedproducts int[],productids int[], productnames text[])

RETURNS json

AS $$

import pandas as pd

注意:首先你需要在 PostgreSQL 数据库安装 plpython3u。

你可能注意到,我并没有用一个数组或一个字典传递订单而是传递了两个数组,后面的产品也是两个数组。为了将数据传递到SQL函数中,我创建了如下查询:


 

(SELECT ARRAY(SELECT id from ordersorder by id))

接下来,我就可以将订单数据加载到 DataFrame 了:


 

o = {'order_id': orderids, 'product_id':orderedproducts}

orders = pd.DataFrame(data=o)

下一组数据与嵌入到PostgreSQL函数中的Python示例(https://github.com/scottfitzcodes/rec-engine-example/blob/master/engine.py)相同:


 

orders_for_product =orders[orders.product_id == id].order_id.unique;

relevant_orders =orders[orders.order_id.isin(orders_for_product)]

accompanying_products_by_order =relevant_orders[relevant_orders.product_id != id]

num_instance_by_accompanying_product =accompanying_products_by_order.groupby("product_id")["product_id"].count.reset_index(name="instances")

num_orders_for_product =orders_for_product.size

product_instances = pd.DataFrame(num_instance_by_accompanying_product)

product_instances["frequency"]= product_instances["instances"]/num_orders_for_product

recommended_products =pd.DataFrame(product_instances.sort_values("frequency",ascending=False).head(3))

产品部分的处理与订单相同:创建字典,然后加载 DataFrame。最后,将结果集作为 JSONB 对象返回。两部分结合到一起,完整的函数如下所示:


 

CREATE OR REPLACE FUNCTIONgetrecommendations (id integer, orderids int[], orderedproducts int[],productids int[], productnames text[])

RETURNS json

AS $$

import pandas as pd

o = {'order_id': orderids, 'product_id': orderedproducts}

orders = pd.DataFrame(data=o)

orders_for_product = orders[orders.product_id == id].order_id.unique;

relevant_orders = orders[orders.order_id.isin(orders_for_product)]

accompanying_products_by_order =relevant_orders[relevant_orders.product_id != id]

num_instance_by_accompanying_product =accompanying_products_by_order.groupby("product_id")["product_id"].count.reset_index(name="instances")

num_orders_for_product = orders_for_product.size

product_instances = pd.DataFrame(num_instance_by_accompanying_product)

product_instances["frequency"] =product_instances["instances"]/num_orders_for_product

recommended_products = pd.DataFrame(product_instances.sort_values("frequency",ascending=False).head(3))

p = {'product_id': productids, 'name': productnames}

products = pd.DataFrame(data=p)

recommended_products = pd.merge(recommended_products, products,on="product_id")

return recommended_products.to_json(orient="table")

$$ LANGUAGE 'plpython3u';

 

 

运行推荐引擎

直接在 SQL 中调用该函数,就可以获得推荐结果:


 

SELECT json_pretty(getrecommendations(

3,

(SELECT ARRAY(SELECT id from orders order by id)),

(SELECT ARRAY(SELECT product_id from orders order by id)),

(SELECT ARRAY(SELECT id from products order by id)),

(SELECT ARRAY(SELECT name from products order by id))

));

{"schema":{"fields":[{"name":"index","type":"integer"},{"name":"product_id","type":"integer"},{"name":"instances","type":"integer"},{"name":"frequency","type":"number"},{"name":"name","type":"string"}],"primaryKey":["index"],"pandas_version":"0.20.0"},"data":[{"index":0,"product_id":13,"instances":4,"frequency":0.5714285714,"name":"Cleats"},{"index":1,"product_id":5,"instances":2,"frequency":0.2857142857,"name":"FootballHelmet"},{"index":2,"product_id":7,"instances":1,"frequency":0.1428571429,"name":"Baseball"}]}

虽然这种做法可行,但我并不推荐。直接将所有应用程序逻辑嵌入数据库,会导致跟踪迁移和发布的难度加大。同时,它还需要一个复杂的流水线每晚提取数据并加载到 Spark 中,生成结果,然后将其反馈到数据库,这个工作量可不容小觑。对于 Plpython3u 和 Pandas 来说,每天使用 pg_cron 运行上述代码可能是一个更简单的解决方案。

原文:https://info.crunchydata.com/blog/recommendation_engine_in_postgres_with_pandas_and_python

本文为 CSDN 翻译,转载请注明来源出处。



Tags:Python 推荐引擎   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
我非常喜欢数据。数据可以告诉你用户在干什么,还可以提供各种深刻的见解。数据应用的一个方面就是根据历史记录或用户做出的类似选择来提供建议。...【详细内容】
2020-08-24  Tags: Python 推荐引擎  点击:(68)  评论:(0)  加入收藏
▌简易百科推荐
Python 是一个很棒的语言。它是世界上发展最快的编程语言之一。它一次又一次地证明了在开发人员职位中和跨行业的数据科学职位中的实用性。整个 Python 及其库的生态系统使...【详细内容】
2021-12-27  IT资料库    Tags:Python 库   点击:(1)  评论:(0)  加入收藏
菜单驱动程序简介菜单驱动程序是通过显示选项列表从用户那里获取输入并允许用户从选项列表中选择输入的程序。菜单驱动程序的一个简单示例是 ATM(自动取款机)。在交易的情况下...【详细内容】
2021-12-27  子冉爱python    Tags:Python   点击:(4)  评论:(0)  加入收藏
有不少同学学完Python后仍然很难将其灵活运用。我整理15个Python入门的小程序。在实践中应用Python会有事半功倍的效果。01 实现二元二次函数实现数学里的二元二次函数:f(x,...【详细内容】
2021-12-22  程序汪小成    Tags:Python入门   点击:(32)  评论:(0)  加入收藏
Verilog是由一个个module组成的,下面是其中一个module在网表中的样子,我只需要提取module名字、实例化关系。module rst_filter ( ...); 端口声明... wire定义......【详细内容】
2021-12-22  编程啊青    Tags:Verilog   点击:(7)  评论:(0)  加入收藏
运行环境 如何从 MP4 视频中提取帧 将帧变成 GIF 创建 MP4 到 GIF GUI ...【详细内容】
2021-12-22  修道猿    Tags:Python   点击:(5)  评论:(0)  加入收藏
面向对象:Object Oriented Programming,简称OOP,即面向对象程序设计。类(Class)和对象(Object)类是用来描述具有相同属性和方法对象的集合。对象是类的具体实例。比如,学生都有...【详细内容】
2021-12-22  我头秃了    Tags:python   点击:(9)  评论:(0)  加入收藏
所谓内置函数,就是Python提供的, 可以直接拿来直接用的函数,比如大家熟悉的print,range、input等,也有不是很熟,但是很重要的,如enumerate、zip、join等,Python内置的这些函数非常...【详细内容】
2021-12-21  程序员小新ds    Tags:python初   点击:(5)  评论:(0)  加入收藏
Hi,大家好。我们在接口自动化测试项目中,有时候需要一些加密。今天给大伙介绍Python实现各种 加密 ,接口加解密再也不愁。目录一、项目加解密需求分析六、Python加密库PyCrypto...【详细内容】
2021-12-21  Python可乐    Tags:Python   点击:(7)  评论:(0)  加入收藏
借助pyautogui库,我们可以轻松地控制鼠标、键盘以及进行图像识别,实现自动抢课的功能1.准备工作我们在仓库里提供了2个必须的文件,包括: auto_get_lesson_pic_recognize.py:脚本...【详细内容】
2021-12-17  程序员道道    Tags:python   点击:(13)  评论:(0)  加入收藏
前言越来越多开发者表示,自从用了Python/Pandas,Excel都没有打开过了,用Python来处理与可视化表格就是四个字——非常快速!下面我来举几个明显的例子1.删除重复行和空...【详细内容】
2021-12-16  查理不是猹    Tags:Python   点击:(20)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条