最近我们对我们平台的用户进行了一个用户标签提取,这中间的主要流程如下图3-1所示:
一、梳理做用户画像需要的数据
用户画像是基于业务数据而进行的,如果前期没有考虑好这一点,那么在真正实操时会发现做分析需要的数据存在不同的业务表里面,甚至有些数据根本没有保存。所以,在做用户画像之前最需要做的事就是梳理清楚到底需要哪些数据,如果业务上没有保存,那么就增加保存,如果数据非常分散,最好是集中保存下,否则后面随着数据越来越大,从多个业务表里面汇总数据也是一个非常麻烦的事。
如上图,如果我们要获取的是用户点赞、评论、分享、浏览的数据,那么可以使用AOP把用户做这些请求的数据记录到一个日志里面。例如:
字段名 | 字段说明 | 示例 |
---|---|---|
user_id | 用户id | 1 |
operation_type | 行为类型 | 1-点赞、2-评论、3-分享、4-浏览 |
operation_content_id | 内容idt | 1 |
operation_time | 操作时间 | 2018.4.17 |
接下来就是对内容id进行去重,可以直接使用Set去重,去重之后可以去内容表里面通过内容id获取到内容的URL地址,因为我们的内容是不保存在本地的,所以需要通过内容的URL去第三方平台拿信息。
二、通过URL获取内容的标题和正文
对于一篇文章来说,标题和正文是最有价值的,对于提取标签这个事来说,也是需要标题和正文的。提取的方式有很多,比如可以单独写针对不同平台的爬虫进行提取信息,但是这样的成本很大。为了保证提取的内容确实是正文,也不能简单的使用driver.find_element_by_xpath('//body').text
的方式,因为这样取出来的数据有很多干扰信息,会把整个页面的所有信息都获取出来当作正文,包括推荐的内容,包括广告...页面上呈现的所有内容。代码如下:
# 爬取文章内容
driver = chrome_dirver()
driver.set_page_load_timeout(20)
# 假设文章的URL存放在article.json文件中
with open('article.json') as f:
article = f.read()
article = json.loads(article)
for k, v in article.iteritems():
try:
article_id = k
article_url = v
driver.get(v)
article_title = driver.title
article_info = driver.find_element_by_xpath('//body').text
# 这里已经获取到文章标题和正文
except Exception as e:
print e
continue
driver.close()
driver.quit()
GitHub上有牛人写了一个基于行块分布函数的通用网页正文抽取算法的Python版本。我们通过测试发现准确性是还可以的,GitHub地址https://github.com/chrislinan/cx-extractor-python
三、通过百度的自然语言算法AipNlp计算出所有文章的标签及对应权重
获取到文章的标题和正文之后,就是需要提取这篇文章的标签以及标签的权重。当然我们可以自己使用开源的分词算法,但是如果没有“词语-有效标签”的库,就是把文章的分词做好之后也很难提取有效的标签。我们这边考虑的是使用百度的自然语言算法AipNlp来帮助我们做这个事。为什么使用百度云,而不使用腾讯云或者阿里云?因为腾讯的“词语-有效标签”库偏社交,阿里的“词语-有效标签”偏电商,百度就是库是最全的。
使用百度云中的自然语言处理SDK很简单,可以直接查看他的SDK文档,有Python、Java、PHP、Node各种语言的。
例如使用Java的,先增加maven依赖:
<dependency>
<groupId>com.baidu.aip</groupId>
<artifactId>java-sdk</artifactId>
<version>${version}</version>
</dependency>
再就是使用,最简单的样例如下:
public class Sample {
//设置APPID/AK/SK
public static final String APP_ID = "你的 App ID";
public static final String API_KEY = "你的 Api Key";
public static final String SECRET_KEY = "你的 Secret Key";
public static void main(String[] args) {
// 初始化一个AipNlp
AipNlp client = new AipNlp(APP_ID, API_KEY, SECRET_KEY);
// 调用接口
String title = "一面APP是一款非常有意思的社交APP";
String content = "一面是一款基于文字、视频、图片的形式,网罗各类资讯、音乐、运动、旅行、周边生活信息、打折促销等内容的社交平台。在一面上,你可以创建各种类型的主题,和家人、恋人、朋友、同事、同学、邻居、同伴等一起订阅专属信息。真正做到关心你关心的人关心的一切,让内容共享温暖我们的社交关系。";
JSONObject res = client.keyword(title, content);
}
}
Body请求示例:
{
"title":"一面APP是一款非常有意思的社交APP",
"content": "一面是一款基于文字、视频、图片的形式,网罗各类资讯、音乐、运动、旅行、周边生活信息、打折促销等内容的社交平台。在一面上,你可以创建各种类型的主题,和家人、恋人、朋友、同事、同学、邻居、同伴等一起订阅专属信息。真正做到关心你关心的人关心的一切,让内容共享温暖我们的社交关系。"
}
返回示例:
{
"log_id": 4457308639853058292,
"items": [
{
"score": 0.997762,
"tag": "社交"
},
{
"score": 0.861775,
"tag": "资讯"
},
{
"score": 0.845657,
"tag": "订阅"
}
]
}
四、通过用户、行为类型、文章的关系,计算出每个用户的标签及权重
例如:点赞权重为0.8、评论权重为0.9、分享权重为1.0、浏览权重为0.3。那就是根据这个用户对哪些文章以何种行为进行了关联,把该文章的标签关联到这个用户上即可,具体的算法我在用户画像(一)|计划制定讲过,大致如下:
3.6、总结
综合上述分析,用户画像的数据模型,可以概括为下面的公式:
用户标识 + 时间 + 行为类型 + 接触点(网址+内容)
某用户因为在什么时间、某个地点、对某个对象,做了什么事。所以会打上XX标签。
用户标签的权重可能随时间的增加而衰减,因此定义时间为衰减因子r,行为类型、网址决定了权重,内容决定了标签,进一步转换为公式:
标签权重=衰减因子×行为权重×位置权重
当然,很多时候标签本身也是有权重的。
如:用户A,昨天在发现频道浏览“2018年必看惊悚恐怖片之一:XXX电影”的主题内容。
我们为这个内容打的标签为:恐怖 0.6,电影 0.8
时间:因为是昨天的行为,假设衰减因子为:r=0.95
行为类型:浏览行为记为权重1
地点:在发现频道为 0.6(相比在我的-我创建的主题中的0.9)
则用户偏好标签是:电影,权重是0.95*0.6 * 1=0.57,即,用户A:恐怖 0.57、电影 0.57。最后再乘以标签自己的权重。上述模型权重值的选取只是举例参考,具体的权重值需要根据业务需求二次建模,这里强调的是如何从整体思考,去构建用户画像模型,进而能够逐步细化模型。