2018年招商银行FinTech精英训练营复赛

赛题背景    

财经新闻作为重要却海量的投资数据,无时无刻不在影响着投资者们的投资决策,为了更好地提示客户当下新闻事件对应的投资机会和投资风险,本课以研发“历史事件连连看”为目的,旨在根据当前新闻内容从历史事件中搜索出相似新闻报道,后期可以结合事件与行情,辅助客户采取相应投资策略。    

该赛题是让参赛者为每一条测试集数据寻找其最相似的TOP 20条新闻,我们会根据参赛者提交的结果和实际的数据进行对比,采用mAP值作为评价指标。

具体实现

该题是一道文本相似度的题目,(我想也可以理解看成聚类啊,分类,具体如何操作我尚未试验)

讲一个小思路:

获取数据(读取中文文本)-->分词-->数据清洗(去掉停用词)-->计算tfidf--构建词袋模型转换为向量-->计算余弦相似度-->获取最相似的20条

额,这是一个baseline 的思路,比赛官方的结果还没有给出,我就先贴上自己baseline 的代码吧,其实还有很多要优化的地方,比如L:tfidf并不适合短文本,这样关键词提取上会出问题;另外VSM模型并不是计算相似性的最佳模型,个人见解,欢迎讨论.

科普一下:

常见的距离度量方法:

(1)欧式距离(2)Pearson相关性(3)cos余弦距离

注意注意!在推荐系统最常用的其实是第二种。

下面是我的一个计算文本相似性的简单代码啦:

# -*- coding: utf-8 -*-
"""
Created on Fri Apr 27 21:49:31 2018

@author: susuxuer
"""

import jieba
import jieba.posseg as pseg
from gensim import corpora,models,similarities
import pandas as pd
import re
import time

# 加载数据集
'''
加载训练集方式:
    loadDataSet('train_data.csv', 'UTF-8')
    
加载测试集方式:
    loadDataSet('test_data.csv', 'gbk')
    
'''
def loadDataSet(filename,encode):
    dataSet = pd.read_csv(filename, encoding = encode)
    m,n = dataSet.shape
    data = dataSet.values[:,-1]
    dataId = dataSet.values[:,0]
    return data.reshape((m,1)), dataId.reshape((m,1))

# numpy 数组转化为 list
def ndarrayToList(dataArr):
    dataList = []
    m,n = dataArr.shape
    for i in range(m):
        for j in range(n):
            dataList.append(dataArr[i,j])
    return dataList

# 创建停用词list  
def stopwordslist(filePath):  
    stopwords = [line.strip() for line in open(filePath, 'r', encoding='UTF-8').readlines()]  
    return stopwords  

# 去掉字符串特殊符号
def removeStr(listData):
    strData = "".join(listData)  
    r1 = u'[0-9’!"#$%&\'()*+,-./:;<=>?@,。?★、…【】《》?“”‘’![\\]^_`{|}~]+'
    removeStrData = re.sub(r1, "",strData)
    return removeStrData

# 对数据集分词
def wordSplit(data):
    stopword = stopwordslist('ChineseStopWords.txt')
    word = ndarrayToList(data)
    
    m = len(word)
    wordList = []  # 保存分词结果
    for i in range(m):
        rowListRemoveStr = removeStr(word[i])
        rowList = [eachWord for eachWord in jieba.cut(rowListRemoveStr)] # 对每一行分词
        wordRmoveList = []
        
        for oneword in rowList:
            if oneword not in stopword and word != '\t' and word != ' ':
                wordRmoveList.append(oneword)
    
        wordList.append(wordRmoveList)
    return wordList


if __name__ == "__main__":
    
    start = time.clock()
    
    with open("result.txt","a") as fr:
        fr.write('source_id')
        fr.write('\t')
        fr.write('target_id')
        fr.close
        
    # 加载训练集与测试集
    trainData,trainDataId = loadDataSet('train_data.csv', 'UTF-8')
    testData,testDataId = loadDataSet('test_data.csv', 'gbk')
    print('训练集、测试集加载完成')
    
    # 对训练集与测试集分词
    trainDataSplit = wordSplit(trainData)
    print('训练集分词完成')
    testDataSplit = wordSplit(testData)
    print('测试集分词完成')

 
    # 制作语料库
    dictionary = corpora.Dictionary(trainDataSplit)  # 获取词袋
    corpus = [dictionary.doc2bow(doc) for doc in trainDataSplit]  # 制作语料库
    print('语料库制作完成')
    
    # 使用 TF-IDF 模型对语料库建模
    tfidf = models.TfidfModel(corpus)
    m = len(testDataSplit)

    for i in range(m):
        print('测试第%d条数据' %i)
        testVec = dictionary.doc2bow(testDataSplit[i])
        index = similarities.SparseMatrixSimilarity(tfidf[corpus], num_features=len(dictionary.keys()))
        sim = index[tfidf[testVec]]
        simNumList = sorted(enumerate(sim), key=lambda item: -item[1])
        
        with open("result.txt","a") as fr:
            for j in range(21):
                if str(int(testDataId[i])) == str(int(simNumList[j][0]+1)):
                    continue
                fr.write('\n')
                fr.write(str(int(testDataId[i])))
                fr.write('\t')
                fr.write(str(int(simNumList[j][0]+1)))
                
    elapsed = (time.clock() - start)
    print('Time use', elapsed)


还望大神们勿喷,这是第一版本,后面版本尚不能公开,此版本Python 3.6可以运行,python2.7可能会出现编码错误。

我之前用的python 2.7 ,Unicode ,GBK,UTF-8,ASCII把我搞得很懵逼,总是出错,给大家科普一下编码:

ASCII:最开始只在美国使用,是一个字节,前128个为标准ASCII码,后128个称为扩展ASCII码。许多基于x86的系统都支持使用扩展(或“高”)ASCII。扩展ASCII 码允许将每个字符的第8 位用于确定附加的128 个特殊符号字符、外来语字母和图形符号。

Unicode 是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案,又称统一码。

GBK编码:是指中国的中文字符,其它它包含了简体中文与繁体中文字符,另外还有一种字符“gb2312”,这种字符仅能存储简体中文字符。

UTF-8:是万国码,UTF8编码格式很强大,支持所有国家的语言,正是因为它的强大,才会导致它占用的空间大小要比GBK大,对于网站打开速度而言,也是有一定影响的。

阅读更多
个人分类: NLP
上一篇LTSA 改进版本,和经典LTSA类似
下一篇八皇后问题--递归回溯算法(Python实现)
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭