跳转至

16 基础用户画像:如何用好用户的注册信息?

你好,我是黄鸿波。

在前面的课程中我们讲了内容画像,讲了推荐系统的服务端搭建,本节课我们就在前面的基础上,讲解用户画像的知识。

我将本节课分为了下面三个重要部分。

  1. 什么是用户画像,用户画像在推荐系统中的作用是什么。
  2. 用户画像中的用户行为数据分析。
  3. 如何利用用户信息搭建一个基础的用户画像。

用户画像及其作用

首先我们来聊一聊什么是用户画像。

先来区分一下内容画像和用户画像。内容画像是用来刻画内容的一系列的特征组合,它只需要对内容服务,与用户的行为以及日志等相关信息并没有什么直接的联系。

但是用户画像就不一样了,一个优秀的用户画像不仅仅是对用户基本信息的特征提取,往往还包含着用户的行为信息、用户潜在行为信息以及用户的行为所关联的内容信息等。因此,相比于内容画像,用户画像更加复杂多变,所起的作用也更加庞杂。

通过用户画像,我们可以很容易地定位到一个人的喜好,并对喜好进行预测。要想给用户推荐更好的内容,就必须先对用户有着充分地了解。在很多公司中都会存在运营这个岗位,这个岗位有一个非常重要的岗位职责就是对用户进行定位,然后找到自己产品中的潜在用户,然后通过一系列的营销手段给用户进行产品的推荐。这个时候,运营人员就相当于一个推荐系统。

用户画像的好坏可以直接决定着推荐的质量。一个好的用户画像,不仅能够刻画出这个用户本身的基本属性,更能够让算法知道如何利用用户画像的特征来挖掘潜在的信息。

我们来假想这样一个场景,现在有以下两种用户画像。

第一种只是在注册的时候记录了基本的用户信息,这些用户信息假设包含了性别、年龄、所在地等。第二种是在第一种的基础上增加了用户的浏览记录,我们可以根据用户的浏览记录来获取到用户最近在看的是哪一类内容,有没有进行点赞、收藏,以及在这个页面停留多久。

很显然,第二种画像相比于第一种更能利用好历史信息,找到兴趣点进行推荐。

用户画像中的用户行为数据分析

用户的行为数据是非常关键,不同的用户行为完全不同。可以说,一万个人能有一万个完全不同的用户行为,我们之所以说推荐系统是千人千面的,就是因为有千变万化的行为信息。

在用户画像中,我们可以用多种方法来分析用户的行为数据。我们来看三个常见的用户行为数据分析的方法。

行为路径分析

行为路径分析是用户画像中最重要的一个部分,它可以帮助我们理解用户在产品中的行为。这些行为包含了一个用户从进入网站到关闭浏览器这个过程中的所有行为(比如搜索、浏览内容、点赞、收藏、评论、转发,在一些电商网站中还有添加到购物车和购买等),我们可以将每个用户从开始到结束的所有行为保存成一条记录,然后利用一些统计学原理进行行为分析,从而找到想要挖掘的点。

行为偏好分析

行为偏好就是利用用户画像来分析用户的个人习惯以及对内容的偏好,从而为其提供更好的个性化推荐服务。在基于热度的召回这一节中我们有讲过,一个内容的热度实际上跟这个内容收到多少个阅读、点赞、收藏、评论、转发等信息有关。我们可以为每一个行为设置一个权重(不同的权重代表重要程度不同),然后再用权重去乘以数量,最后把所有的权重求和就得到了内容的热度。这里内容的热度是作用于内容画像的,但是我们来反推这个经过,实际上这里面的每一个步骤,就是一个用户画像中的行为。

我们可以通过用户对内容的操作知道用户对内容的喜好程度,这个喜好程度可以关联到内容的类别、关键词等信息中,从而实现对用户行为偏好的分析。几乎所有的推荐算法中都会用到行为偏好分析的数据,比如说后面会讲到的排序算法中的GBDT+LR。

搜索行为分析

搜索行为分析实际上和基于关键词的召回相辅相成。搜索行为分析可以帮助我们了解用户的搜索行为,从而为他们提供更好的搜索结果和搜索体验。我们可以通过分析用户在搜索过程中的搜索词、搜索结果、点击率等行为,了解他们的搜索意图和偏好,从而更好地优化搜索引擎和推荐算法。

通过对用户行为的精准分析可以很好地提高推荐精度,同时还可以及时发现和修正推荐算法和模型中的不足之处,提高用户的黏性。有了用户行为分析,我们可以很好地发现内容的不足和产品的不足,从而改善产品的质量。

利用用户信息搭建一个基础用户画像

最后,我们来搭建一个基础的用户画像。

我们目前只是把召回集的内容以时间召回的形式推荐了出去,还没有完成用户的注册、登录等基本信息,因此还无法收集用户的行为记录。在本节课中,我们先来搭建一个以用户注册信息为导向的基础的用户画像。

一般来讲,用户的基础信息多为结构化的数据,并且这类数据一旦注册后就很难改变,因此在这里我建议使用结构化关系型数据库进行存储。在推荐系统或者说整个软件系统的架构中,常见的关系型数据库有MySQL、Oracle、SqlServer等,在这里,我们使用MySQL数据库作为用户信息的存储数据库。

在选择版本上面,我建议使用MySQL Community Server版本,尤其是开发时在Windows系统上,该版本非常适合。

我们可以使用这个网址来下载MySQL Community Server安装包,在这里我选择的版本为5.7.41,选择ZIP Archive后面的Download进行下载,在Windows上可以直接下载MSI版本,如图所示。

图片

然后选择使用之前的版本,如图所示。

图片

然后进行下载MSI版本的安装程序。

图片

下载完成后,双击进入安装程序,这个时候,我们会进入到一个版本选择的界面。

图片

一般来讲,如果是用作本机开发,可以直接选择开发版,也就是Developer Default,因为这个版本里除了包含Server之外,还包含了开发界面、远程调试的shell等等。如果是只用作服务的话,可以选择Server only,这个时候,我们需要自己去下载一个其他的连接客户端用于MySQL数据库的连接。当然,如果你的内存和电脑的空间很大,也可以无脑选Full。Custom是自定义,就是根据你自己的需要来进行组件的安装。在这里我选择Developer Default,然后点击Next。

图片

当全部安装完成之后,一路点击Next,来到下面这个界面。

图片

在这里我们需要为MySQL的root用户设置一个密码,由于是开发机,我直接设置成123456,然后一路点击下一步,直到安装完成。如果是在服务器上,建议可以设置比较复杂的密码,并且在下面新建一个单独的MySQL账户。安装完成后,弹出如下界面。

图片

我们可以点击下面默认的连接,如果能正常进入,则说明安装服务正常。

接下来,我们尝试在这里新建一个数据库,名为recommendation,我们可以直接在连接里点击上面的Create a new schema in the connected Server创建新的数据库,如图所示。

图片

然后输入数据库名进行创建,这里我们用的数据库名叫做recommendation。

图片

这里必须要注意的一点就是,字符集一定要改为utf8,否则中文会报错。然后点击Apply进行创建。

下面就是要做用户注册的服务端了,我把事情分成了四步。

  1. 在我们的服务端程序里写MySQL连接的程序,然后连接数据库。
  2. 建立数据表和实体,这里我们用的是SQLAlchemy。
  3. 写注册和登录的service服务,并将注册的用户信息存储到MySQL数据库中。
  4. 使用Postman试一下。

下面我们一步一步来。

第一步是要连接MySQL,我们要先在环境中安装SQLAlchemy库,在Python中想调用MySQL的话,还需要安装一个PyMySQL的库。

首先可以通过控制台使用如下命令激活虚拟环境。

activate recommendation-service

然后使用下面的命令来安装PyMySQL库。

pip install pymsql

然后再通过如下命令安装SQLAlchemy库。

pip install sqlalchemy

等待安装完成即可。

接着打开Webservice程序,即recommendation-service项目,然后在dao目录中新建mysql_db.py文件,并向里面写入下面的代码。

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
 
class Mysql(object):
    def __init__(self):
        self.engine = create_engine('mysql+pymysql://root:123456@127.0.0.1:3306/recommendation')
        self._DBSession = sessionmaker(bind=self.engine)

这段代码实际上和我们之前写的Redis数据库以及MongoDB数据库的连接方法非常类似,就是创建了一个连接的方法,然后将用户名、密码、Host、数据库名等信息加入进去,然后进行连接。

在Python中,向MySQL插入数据有一个非常简单的方法,就是利用ORM映射。我们在根目录下新建一个目录,名为entity,专门用来存放各种实体。在这里我们需要存放的是用于MySQL的用户表的实体,因此,我们在entity目录下再建立一个名为user.py的文件,此时的目录结构如下。

图片

然后再在里面写入以下代码。

from sqlalchemy import Column, String, Integer
from sqlalchemy.ext.declarative import declarative_base
from dao.mysql_db import Mysql
 
Base = declarative_base()
class User(Base):
    __tablename__ = 'User'
    id = Column(Integer(), primary_key=True)
    username = Column(String(20))
    password = Column(String(500))
    nick = Column(String(20))
    gender = Column(String(10))
    age = Column(String(2))
    city = Column(String(10))
 
    def __init__(self):
        mysql = Mysql()
        engine = mysql.engine
        Base.metadata.create_all(engine)

在这段代码中,我们引入了sqlalchemy和刚刚创建的MySQL连接程序,然后使用declarative_base()函数创建了一个 BaseModel 类,这个类的子类可以自动与一个表关联。
在User类中,我们首先使用__tablename__ = 'User’创建了一个表,表的名字叫做User,然后再在User表里面定义了一些字段,如下表格所示。

图片

这里需要注意的是,password之所以设置了很长的字符,是因为我们要对密码进行加密。根据加密方式的不同长度也会不同,在这里我就设置的相对长一点。age这个字段其实可以用int来表示,但是为了方便后面的处理,我这里直接使用了String类型。

最后,使用__init__函数将MySQL类和引擎进行初始化。

到现在为止,可以说是万事俱备只欠东风,接下来我们来写服务。服务依然写在app.py这个文件中,我们在这个文件中加入两个函数,分别是register()和login()。

register()函数。

@app.route("/recommendation/register", methods=['POST'])
def register():
    if request.method == 'POST':
        req_json = request.get_data()
        rec_obj = json.loads(req_json)
        user = User()
        user.username = rec_obj['username']
        user.nick = rec_obj['nick']
        user.age = rec_obj['age']
        user.gender = rec_obj['gender']
        user.city = rec_obj['city']
        user.password = str(hashlib.md5(rec_obj['password'].encode()).hexdigest())
    try:
        mysql = Mysql()
        sess = mysql._DBSession()
        if sess.query(User.id).filter(User.username == user.username).count() > 0:
            return jsonify({"code": 1000, "msg": "用户已存在"})
        sess.add(user)
        sess.commit()
        sess.close()
 
        result = jsonify({"code": 0, "msg": "注册成功"})
        return result
    except Exception as e:
        print(str(e))
        return jsonify({"code": 2000, "msg": "error"})

login()函数。

@app.route("/recommendation/login", methods=['POST'])
def login():
    if request.method == 'POST':
        req_json = request.get_data()
        rec_obj = json.loads(req_json)
        username = rec_obj['username']
        password = str(hashlib.md5(rec_obj['password'].encode()).hexdigest())
    try:
        mysql = Mysql()
        sess = mysql._DBSession()
        res = sess.query(User.id).filter(User.username == username, User.password == password)
        if res.count() > 0:
            for x in res.all():
                data = {"userid": str(x[0])}
                info = jsonify({"code": 0, "msg": "登录成功", "data":data})
                return info
        else:
            return jsonify({"code": 1000, "msg": "用户名或密码错误"})
    except Exception as e:
        print(str(e))
        return jsonify({"code": 2000, "msg": "error"})

我们来解析下这两个函数。
这两个函数分别是注册和登录。在注册函数中,首先确定注册所接收的请求为POST请求,于是,我们从前端接收注册时所传来的参数。参数有用户名、密码、昵称、年龄、性别和城市,其中密码使用MD5的方式进行加密,然后把所有接收到的数据传到MySQL数据库中。

在传入MySQL数据库之前,我们首先会通过用户名来进行查询,看看数据库里是不是已经有这个用户名了。如果查到的用户名数量大于0,说明已经有这个用户了,这个时候就会返回用户已存在,否则就正常注册提交提示注册成功。这个时候,我们所执行的session.commit()方法就会把用户信息插入到MySQL数据库中,当然,还会出现服务端报错的现象,这个时候就要抛出异常。

再来说说登录函数。登录函数实际上就是利用注册函数插入数据库中的内容进行校验,将用户名和密码在插入的user表中进行查询,匹配成功则正常登录,否则就会提示用户名和密码错误。

在登录中要注意,我们会同时校验用户名和密码,由于MD5是不可逆的加密方式,因此校验方法是将用户输入的密码再一次进行MD5加密,然后再和数据库中的密码进行比对。如果比对成功,并且用户名比对也是成功的,则说明登录正常,否则就是登录异常。

运行程序后,得到如下界面。

图片

接下来,用Postman请求一下注册端口,试试能否注册成功。

图片

可以发现,现在已经能够正常地使用接口进行注册了。接下来同样的参数,我们再提交一次看看会发生什么?

图片

当我们再点击一次,会发现服务端已经返回用户已存在,说明注册是成功的。我们来看看数据库里有没有一条新的数据增加,可以使用如下命令来查询一下。

SELECT * FROM recommendation.user;

得到了下面的内容。
图片

可以看到,用户数据已经插入到数据库中了,并且已经是我们希望得到的值了。

接下来再试试登录接口,同样是利用Postman来测试一下。

图片

调用一下登录接口,输入用户名和密码,返回登录成功。这里需要注意的是,在登录时返回了一个userid,这样以后再发其他请求的时候,就可以用userid来作为唯一的标识了。

到这里,注册和登录就已经全部搞定了。

虽然这只是一个用户的基本信息,但是也确实是一个最基本的用户画像了。在接下来的课程中,我们会逐渐对这个用户画像进行内容的填充,使其更加丰富。

总结

到这里,我们本节课的内容就已经全部讲完了,我来对这节课的内容做一个总结,学完本节课你应该知道下面五个要点。

  1. 什么是用户画像,以及用户画像在推荐系统中的作用和地位是什么?
  2. 对用户行为分析的方法有很多种,比较常见的有行为路径分析、行为偏好分析和搜索行为分析。
  3. 熟悉如何使用Python搭建一个Webservice服务,通过注册的方式收集最基础的用户画像。
  4. 知道如何安装MySQL数据库,以及如何利用Python来操作它。
  5. 我们可以通过Python来创建MySQL数据库、插入数据,并且写一个Webservice接口,使用Postman进行模拟调用。

课后题

学完本节课,给你布置两个小作业。

  1. 完成本节课的环境搭建以及代码编写。
  2. 想一想,还可以收集哪些用户信息?欢迎你在评论区留言,也可以通过代码实现它们。

欢迎你在留言区与我交流讨论,如果这节课对你有帮助,也欢迎你推荐给朋友一起学习。

精选留言(6)
  • 静心 👍(0) 💬(1)

    当用户不存在时,执行了sess.close(),当用户已存在时没有执行sess.close(),不会资源泄漏吗?

    2023-08-28

  • Geek_ccc0fd 👍(0) 💬(1)

    "将每个用户从开始到结束的所有行为保存成一条记录,然后利用一些统计学原理进行行为分析,从而找到想要挖掘的点" 老师这块可以举例详细说说嘛,基于哪些统计学原理,能够挖掘什么数据

    2023-05-23

  • xjt 👍(11) 💬(0)

    好水。装个数据库就半篇文。

    2023-07-02

  • 张正伟 👍(4) 💬(0)

    太简单了,demo中的demo。。。

    2023-06-24

  • 悟尘 👍(2) 💬(0)

    pip install pymsql 有误,应该是pip install pymysql

    2023-12-13

  • peter 👍(0) 💬(1)

    Q1:用户画像,从数据结构的角度看,是怎么存储的? Q2:文中提到的“webservice”是什么意思? 是普通的“网站服务”,没有特殊含义吗?还是指一种特殊的协议?我记得有一种协议叫“webservice”,好像挺复杂的。

    2023-05-22