开发者社区> 致Great_VIP> 正文

神策杯 2018高校算法大师赛(个人、top2、top6)方案总结(上)

简介: 神策杯 2018高校算法大师赛(个人、top2、top6)方案总结(上)
+关注继续查看

1 竞赛背景


神策数据推荐系统是基于神策分析平台的智能推荐系统。它针对客户需求和业务特点,并基于神策分析采集的用户行为数据使用机器学习算法来进行咨询、视频、商品等进行个性化推荐,为客户提供不同场景下的智能应用,如优化产品体验,提升点击率等核心的业务指标。


神策推荐系统是一个完整的学习闭环。采集的基础数据,通过机器学习的算法模型形成应用。效果实时验证,从而指导添加数据源,算法优化反馈形成一个全流程、实时、自动、可快速迭代的推荐闭环。


本次竞赛是模拟业务场景,以新闻文本的核心词提取为目的,最终结果达到提升推荐和用户画像的效果。


比赛链接:https://js.dclab.run/v2/cmptDetail.html?id=242

数据集
数据地址:[https://pan.baidu.com/s/1LBfqT86y7TEf4hDNCU6DpA](https://pan.baidu.com/s/1LBfqT86y7TEf4hDNCU6DpA)
密码:qa2u


2 任务


个性化推荐系统是神策智能系统的一个重要方面,精准的理解资讯的主题,是提升推荐系统效果的重要手段。 神策数据以一个真实的业务案例作为依托,提供了上千篇资讯文章及其关键词,参赛者需要训练出一个”关键词提取”的模型,提取10万篇资讯文章的关键词。


3 数据


备注:报名参赛或加入队伍后,可获取数据下载权限。

提供下载的数据集包括两个部分: 1. all_docs.txt,108295篇资讯文章数据,数据格式为:ID 文章标题 文章正文,中间由\001分割。 2. train_docs_keywords.txt,1000篇文章的关键词标注结果,数据格式为:ID 关键词列表,中间由\t分割。

说明: 标注数据中每篇文章的关键词不超过5个。关键词都在文章的标题或正文中出现过。需要注意的是,“训练集文章的关键词构成的集合”与“测试集文章的关键词构成的集合”,这两个集合可能存在交集,但不一定存在包含与被包含的关系。


4 个人初赛第十一名方案


基于NLP中的无监督学习方法来提取关键词,这也是自己第一次参加比赛,当时刚接触NLP,所以对这次比赛印象深刻,在此给大家分享出来

神策杯”2018高校算法大师赛 B榜排名(13/583)


4.1 得分情况


  • 01_snow_textrank.py:暂定
  • 02_jieba_tfidf.py:377.5|415(custom)
  • 03_jieba_textrank.py:204.5
  • 04_jieba_postag.py:425.0
  • 05_jieba_postag.py:334.5
  • 06_jieba_ensemble.py:515
  • analysis_for_06.py:607.5


4.2 数据分析:


  • 1-40000:影视新闻
  • 40001-44060:体育新闻
  • 44061-54060:健康新闻
  • 54061-64060:军事新闻
  • 64061-74060:正文文本
  • 74061-84060:教育新闻
  • 98296-108295:饮食菜谱


4.3 提升技巧


  • 词性相同的情况下,选取长度大的关键词
    已解决,效果有明显提升,这也符合常理,词长度在3-5之间,一般在一个标题中是一个重要词汇
  • 存在错别字
  • 无“手机品牌”字典
    已解决:尝试增加这部分词典
  • 像“杰森·斯坦森”、“《摇曳庄的幽奈小姐:蒸汽迷宫》”这些词,jieba分词存在缺陷
    已解决:需要对包含特殊符号的句子做处理,效果有提升
  • 标题中没有关键词待提升:发现这种标题的规律,需要从正文中提取这种标题一般有个特点就是:含有标点符号,比如:
    • 老公遭曝光?邓莎回应质疑:他身材比我好散了吧
    • 亚姐出身被前夫冷落?过档TVB专门“搞事”,视后非她莫属了?
    • 高秋梓100斤是真的吗?小姐姐托举黄渤很容易,却举不起她!
    • 哺乳期间怎么忌口?真的没有那么复杂
  • 词性标错

这个是导致tf-idf提取关键字误差较大的原因



4.5 核心代码:

# -*- 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.


以下整理来自国内大佬无私的风向


5 “神策杯”2018高校算法大师赛第二名代码


代码链接:https://github.com/bigzhao/Keyword_Extraction

文章链接:https://bigzhao.github.io/2018/10/26/keyword-exaction/

队伍:发SCI才能毕业


5.1 目录说明


  • jieba:修改过的jieba库。
  • 字典:存放jieba词库。PS:词库来源于搜狗百度输入法词库、爬虫获取的明星词条和LSTM命名实体识别结果。
  • all_docs.txt: 训练语料库
  • train_docs_keywords.txt:我把明显错误的一些关键词改回来了,例如D039180梁静茹->贾静雯、D011909泰荣君->泰容君等
  • classes_doc2vec.npy:gensim默认参数的doc2vec+Kmeans对语料库的聚类结果。
  • my_idf.txt:计算得来的语料库的idf文件。
  • lgb_sub_9524764012949717.npy LGB的某一次预测值,用于特征生成
  • stopword.txt:停用词
  • Get_Feature.ipynb:特征生成notebook,对训练集和测试集生成对应的文件
  • lgb_predict.py:预测并输出结果的脚本。需要train_df_v7.csv和test_df_v7.csv。
  • train_df_v7.csv,test_df_v7.csv:Get_Feature.ipynb 跑出来的结果,notebook有详细特征说明
  • word2vec模型下载地址:https://pan.baidu.com/s/1krH0ThIqvldmF5gfOZ6s7A 提取码:tw0m。
  • doc2vec模型下载地址:链接:https://pan.baidu.com/s/17ZYAbTeqsXXq-hE3z3QqmA 提取码:0ciw.


5.2 运行说明


  1. 运行Get_Feature.ipynb获取train_df_v7.csv和test_df_v7.csv.
  2. 运行lgb_predict.py 获取结果sub.csv。


依赖包

numpy 1.14.0rc1
pandas 0.23.0
sklearn 0.19.0
lightgbm 2.0.5
scipy 1.0.0


5.3 解题思路方案说明


  1. 利用jieba的tfidf方法筛选出Top20的候选关键词
  2. 针对每条样本的候选关键词提取相应的特征,把关键词提取当作是普通二分类问题。特征可以分为以下两类:
  • 样本文档自身特征:例如文本的长度、句子数、聚类结果等;
  • 候选关键词自身特征:关键词的长度、逆词频等;
  • 样本文本和候选关键词的交互特征:词频、头词频、tfidf、主题相似度等;
  • 候选关键词之间的特征:主要是关键词之间的相似度特征。
  • 候选关键词与其他样本文档的交互特征:这里有两个非常强的特征,第一是在整个数据集里被当成候选关键词的频率,第二个与点击率类似,算在整个文档中预测为正样本的概率结果大于0.5的数量(在提这个特征的时候我大概率以为会过拟合,但是效果出乎意料的好,所以也没有做相应的平滑,或许是因为结果只选Top2的关键词,这里概率选0.5会有一定的平滑效果,具体操作请看lgb_predict.py的31-42行)。
  1. 利用LightGBM解决上述二分类问题,然后根据LightGBM的结果为每条文本选出预测概率Top2的词作为关键词输出即可。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
如何设置阿里云服务器安全组?阿里云安全组规则详细解说
阿里云安全组设置详细图文教程(收藏起来) 阿里云服务器安全组设置规则分享,阿里云服务器安全组如何放行端口设置教程。阿里云会要求客户设置安全组,如果不设置,阿里云会指定默认的安全组。那么,这个安全组是什么呢?顾名思义,就是为了服务器安全设置的。安全组其实就是一个虚拟的防火墙,可以让用户从端口、IP的维度来筛选对应服务器的访问者,从而形成一个云上的安全域。
21047 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
30433 0
阿里云服务器安全组设置内网互通的方法
虽然0.0.0.0/0使用非常方便,但是发现很多同学使用它来做内网互通,这是有安全风险的,实例有可能会在经典网络被内网IP访问到。下面介绍一下四种安全的内网互联设置方法。 购买前请先:领取阿里云幸运券,有很多优惠,可到下文中领取。
23157 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
21363 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
17517 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
14929 0
使用OpenApi弹性释放和设置云服务器ECS释放
云服务器ECS的一个重要特性就是按需创建资源。您可以在业务高峰期按需弹性的自定义规则进行资源创建,在完成业务计算的时候释放资源。本篇将提供几个Tips帮助您更加容易和自动化的完成云服务器的释放和弹性设置。
20943 0
+关注
400
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载