神策数据推荐系统是基于神策分析平台的智能推荐系统。它针对客户需求和业务特点,并基于神策分析采集的用户行为数据使用机器学习算法来进行咨询、视频、商品等进行个性化推荐,为客户提供不同场景下的智能应用,如优化产品体验,提升点击率等核心的业务指标。 神策推荐系统是一个完整的学习闭环。采集的基础数据,通过机器学习的算法模型形成应用。效果实时验证,从而指导添加数据源,算法优化反馈形成一个全流程、实时、自动、可快速迭代的推荐闭环。
本次竞赛是模拟业务场景,以新闻文本的核心词提取为目的,最终结果达到提升推荐和用户画像的效果。
数据集
数据地址:[https://pan.baidu.com/s/1LBfqT86y7TEf4hDNCU6DpA](https://pan.baidu.com/s/1LBfqT86y7TEf4hDNCU6DpA)
密码:qa2u
个性化推荐系统是神策智能系统的一个重要方面,精准的理解资讯的主题,是提升推荐系统效果的重要手段。 神策数据以一个真实的业务案例作为依托,提供了上千篇资讯文章及其关键词,参赛者需要训练出一个”关键词提取”的模型,提取10万篇资讯文章的关键词。
备注:报名参赛或加入队伍后,可获取数据下载权限。
提供下载的数据集包括两个部分: 1. all_docs.txt,108295篇资讯文章数据,数据格式为:ID 文章标题 文章正文,中间由\001分割。 2. train_docs_keywords.txt,1000篇文章的关键词标注结果,数据格式为:ID 关键词列表,中间由\t分割。
说明: 标注数据中每篇文章的关键词不超过5个。关键词都在文章的标题或正文中出现过。需要注意的是,“训练集文章的关键词构成的集合”与“测试集文章的关键词构成的集合”,这两个集合可能存在交集,但不一定存在包含与被包含的关系。
基于NLP中的无监督学习方法来提取关键词,这也是自己第一次参加比赛,当时刚接触NLP,所以对这次比赛印象深刻,在此给大家分享出来
神策杯”2018高校算法大师赛 B榜排名(13/583)
已解决,效果有明显提升,这也符合常理,词长度在3-5之间,一般在一个标题中是一个重要词汇
已解决:尝试增加这部分词典
已解决:需要对包含特殊符号的句子做处理,效果有提升
待提升:发现这种标题的规律,需要从正文中提取
这种标题一般有个特点就是:含有标点符号,比如:
老公遭曝光?邓莎回应质疑:他身材比我好散了吧
亚姐出身被前夫冷落?过档TVB专门“搞事”,视后非她莫属了?
高秋梓100斤是真的吗?小姐姐托举黄渤很容易,却举不起她!
哺乳期间怎么忌口?真的没有那么复杂
这个是导致tf-idf提取关键字误差较大的原因
# -*- coding: utf-8 -*-
# @Author : quincyqiang
# @File : analysis_for_06.py
# @Time : 2018/9/5 14:17
import pickle
import pandas as pd
from tqdm import tqdm
from jieba.analyse import extract_tags,textrank # tf-idf
from jieba import posseg
import random
import jieba
jieba.analyse.set_stop_words('data/stop_words.txt') # 去除停用词
jieba.load_userdict('data/custom_dict.txt') # 设置词库
'''
nr 人名 nz 其他专名 ns 地名 nt 机构团体 n 名词 l 习用语 i 成语 a 形容词
nrt
v 动词 t 时间词
'''
test_data=pd.read_csv('data/test_docs.csv')
train_data=pd.read_csv('data/new_train_docs.csv')
allow_pos={'nr':1,'nz':2,'ns':3,'nt':4,'eng':5,'n':6,'l':7,'i':8,'a':9,'nrt':10,'v':11,'t':12}
# allow_pos={'nr':1,'nz':2,'ns':3,'nt':4,'eng':5,'nrt':10}
tf_pos = ['ns', 'n', 'vn', 'nr', 'nt', 'eng', 'nrt','v','a']
def generate_name(word_tags):
name_pos = ['ns', 'n', 'vn', 'nr', 'nt', 'eng', 'nrt']
for word_tag in word_tags:
if word_tag[0] == '·' or word_tag=='!':
index = word_tags.index(word_tag)
if (index+1)<len(word_tags):
prefix = word_tags[index - 1]
suffix = word_tags[index + 1]
if prefix[1] in name_pos and suffix[1] in name_pos:
name = prefix[0] + word_tags[index][0] + suffix[0]
word_tags = word_tags[index + 2:]
word_tags.insert(0, (name, 'nr'))
return word_tags
def extract_keyword_ensemble(test_data):
ids,titles=test_data['id'],test_data['title']
with open('data/test_doc.pkl','rb') as in_data:
test_docs=pickle.load(in_data)
labels_1 = []
labels_2 = []
use_idf=0
for title, doc in tqdm(zip(titles, test_docs)):
title_keywords = []
word_tags = [(word, pos) for word, pos in posseg.cut(title)] # 标题
# 判断是否存在特殊符号
if '·' in title:
word_tags = generate_name(word_tags)
for word_pos in word_tags:
if word_pos[1] in allow_pos:
title_keywords.append(word_pos)
title_keywords = [keyword for keyword in title_keywords if len(keyword[0]) > 1]
title_keywords = sorted(title_keywords, reverse=False, key=lambda x: (allow_pos[x[1]], -len(x[0])))
if '·' in title :
if len(title_keywords) >= 2:
key_1 = title_keywords[0][0]
key_2 = title_keywords[1][0]
else:
# print(keywords,title,word_tags)
key_1 = title_keywords[0][0]
key_2 = ''
labels_1.append(key_1)
labels_2.append(key_2)
else:
# 使用tf-idf
use_idf += 1
# ---------重要文本-----
primary_words = []
for keyword in title_keywords:
if keyword[1] == 'n':
primary_words.append(keyword[0])
if keyword[1] in ['nr', 'nz', 'nt', 'ns']:
primary_words.extend([keyword[0]] * len(keyword[0]))
abstract_text = "".join(doc.split(' ')[:15])
for word, tag in jieba.posseg.cut(abstract_text):
if tag == 'n':
primary_words.append(word)
if tag in ['nr', 'nz', 'ns']:
primary_words.extend([word] * len(word))
primary_text = "".join(primary_words)
# 拼接成最后的文本
text = primary_text * 2 + title * 6 + " ".join(doc.split(' ')[:15] * 2) + doc
# ---------重要文本-----
temp_keywords = [keyword for keyword in extract_tags(text, topK=2)]
if len(temp_keywords)>=2:
labels_1.append(temp_keywords[0])
labels_2.append(temp_keywords[1])
else:
labels_1.append(temp_keywords[0])
labels_2.append(' ')
data = {'id': ids,
'label1': labels_1,
'label2': labels_2}
df_data = pd.DataFrame(data, columns=['id', 'label1', 'label2'])
df_data.to_csv('result/06_jieba_ensemble.csv', index=False)
print("使用tf-idf提取的次数:",use_idf)
if __name__ == '__main__':
# evaluate()
extract_keyword_ensemble(test_data)
© 2021 GitHub, Inc.
以下整理来自国内大佬无私的风向
代码链接:https://github.com/bigzhao/Keyword_Extraction 文章链接:https://bigzhao.github.io/2018/10/26/keyword-exaction/
队伍:发SCI才能毕业
numpy 1.14.0rc1
pandas 0.23.0
sklearn 0.19.0
lightgbm 2.0.5
scipy 1.0.0
代码链接:https://github.com/RHKeng/ShenCeCup
(3)通过分析标题中的数据可以看到,如果标题中含有书名号或者是人名,95%以上都是对应文章的关键词。这个应该跟每个人的习惯(打标签人的习惯)有关,书名号中的内容通常会对应影片,电视剧,歌曲等的名称,这些名词和人名很大概率会在一开始吸引我么的注意,因此是关键词的概率就很大。
Vi表示某个网页,Vj表示链接到Vi的网页(即Vi的入链),S(Vi)表示网页Vi的PR值,In(Vi)表示网页Vi的所有入链的集合,Out(Vj)表示网页Vj链接到其他网页的数量,d表示阻尼系数,是用来克服这个公式中“d *”后面的部分的固有缺陷用的:如果仅仅有求和的部分,那么该公式将无法处理没有入链的网页的PR值,因为这时,根据该公式这些网页的PR值为0,但实际情况却不是这样,所有加入了一个阻尼系数来确保每个网页都有一个大于0的PR值,根据实验的结果,在0.85的阻尼系数下,大约100多次迭代PR值就能收敛到一个稳定的值,而当阻尼系数接近1时,需要的迭代次数会陡然增加很多,且排序不稳定。公式中S(Vj)前面的分数指的是Vj所有出链指向的网页应该平分Vj的PR值,这样才算是把自己的票分给了自己链接到的网页。
Wji是指Vi和Vj两个句子之间的相似度,可以采用编辑距离和余弦相似度等。当textrank应用到关键词提取时,与自动摘要提取不同:1)词与词之间的关联没有权重,即Wji是1;2)每个词不是与文档中所有词都有链接,而是通过设定固定长度滑动窗口形式,在窗口内的词语间有链接。
主题模型常用的方法是LSI(LSA)和LDA,其中LSI是采用SVD(奇异值分解)的方法进行暴力破解,而LDA则是通过贝叶斯学派方法对分布信息进行拟合。通过LSA或LDA算法,可以得到文档对主题的分布和主题对词的分布,可以根据主题对词的分布(贝叶斯方法)得到词对主题的分布,然后通过这个分布和文档对主题的分布计算文档与词的相似性,选择相似性高的词列表作为文档的关键词。
Umk代表了文档对主题的分布矩阵,Vnk的转置代表了主题对词语的分布矩阵。 LSA通过SVD将词、文档进行更本质地表达,映射到低维的空间,并在有限利用文本语义信息的同时,大大降低计算的代价,提高分析质量。但是计算复杂度非常高,特征空间维度较大的,计算效率十分低下。当一个新的文档进入已有特征空间时,需要对整个空间重新训练,才能得到新加入文档后的分布信息。此外,还存在对频率分布不敏感,物理解释性薄弱的问题。
我们可以根据数据的多项式分布和先验分布求出后验分布,然后将这个后验分布作为下一次的先验分布,不断迭代更新。求解方法一般有两种,第一种是基于Gibbs采样算法求解,第二种是基于变分推断EM算法求解。
(4)第二名是通过tfidf选20个候选集,然后再打标签,特色特征:在整个数据集里被当成候选关键词的频率,这个其实就是该候选词在整个数据集中tfidf在前20的频率 (5)第三名未引入外部词典,使用词的凝聚度和自由度从给定文档中发现新词。 (6)第五名使用pyhanlp包来进行命名实体识别,识别人名,据说准确度比较高。
这个任务属于短语挖掘或者关键词挖掘,在接触NLP期间有很多同学在研究如何从文本中挖掘关键词,经过NLP近几年技术的发展,大体总结有以下方法,其实也是贯穿上面分享的三个方案: