关于任务二(用户兴趣标注)的总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_30843221/article/details/78111957

前言

听完smp比赛各队伍的技术分享后, 回来实验室后用了一周的时间去复刻第一名,第二名关于任务二的做法.任务二的研究对象为csdn技术论坛的用户,根据他们的博客行为和博客内容,以及用户与用户之间的关系,分析用户的主要兴趣点。比赛给定的兴趣标签空间为42个兴趣类别,兴趣类别之间呈现明显的不平衡分布。在这个过程中, 我学习到了非常多的东西. 不过遗憾的是, 到最后也无法达到他们训练出来的效果, 估计某些地方的特征构造和参数调整方面有问题.

第一名的思路

先说第一名的方法, 其主要是利用stacking的思想, 做了两层模型的预测. 第一层先对每个类别做了各自的逻辑回归预测, 通过10-折校验方法产生了10个不同的逻辑回归模型, 加上不同的类别,一共产生了420个逻辑模型, 对用户的特征向量输入(word2vec, doc2vec)分别了做不同类别的逻辑回归预测然后取平均, 最终得到了42维的概率特征向量.做一个图也许比较容易理解:
step1

在第二层中, 利用42维的概率特征向量,构建三层神经网络模型, 输出模型用softmax函数.而三层神经网络也是用了10-折模型做平均输出.
这里写图片描述
由于比赛的时候, 我是采用了lsi模型训练出博客的向量表示, 所以我直接用这个向量作为原始向量输入, 但发现第二层常常出现过拟合的情况(即都预测大类), 后来将神经网络改为了随机森林, 模型预测为的准确率为0.412,效果不太理想.

第二名的做法

第二名的方法十分简洁有效, 该方法直接用了原始的向量(lda向量)做三层神经网络模型, 没有交叉验证.我直接套用他的思想, 用keras训练神经网络模型, 200维的lsi博客向量作原始输入, 预测的结果极其有效,一下子就0.438, 超过我当时比赛的最好水平(0.434),真是感叹自己的见识少得离谱.

相关代码

这里附上, 我当时是如何训练lsi模型的代码, 以及后期训练三层神经网络模型和预测用户兴趣.

训练lsi模型

def train_lsi_model(blog_content_list):
    documents = blog_content_list   ## 每篇博客, 以及做好分词,去除无关标点符号
    texts = [[word for word in document] for document in documents] ## 将博客构建列表形式
    dictonary = corpora.Dictionary(texts)  ## 统计博客的出现的词项
    dictonary.save('../dictionary.model')
    corpus = [dictonary.doc2bow(text) for text in texts]  ## 将博客转化为BOW形式
    tfidf = models.TfidfModel(corpus)  ## 提炼tfidf模型
    tfidf.save('../tfidf.model')
    corpus_tfidf = tfidf[corpus]
    corpus_tfidf.save('../corpus_tfidf.model')
    lsi = models.LsiModel(corpus_tfidf, id2word=dictonary,num_topics=num_topics)  ## 训练lsi模型, 隐式主题为num_topics
    lsi.save('../lsi.model')
    corpus_lsi = lsi[corpus_tfidf]
    corpus_lsi.save('../corpus_lsi.model')
    index = similarities.MatrixSimilarity(lsi[corpus]) ## 用于计算博客相似度
    index.save('../index.model')

lsi主题映射

blog_content = open(blog_content_file).read().lower().strip().split('/')
            query_bow = dictonary.doc2bow(blog_content) ## 转化为bow模型
            query_lsi = lsi[query_bow]

训练三层神经网络

from keras.models import Sequential
from keras.layers.core import Dense, Activation, Dropout
from keras.utils import np_utils

## one_hot映射
def one_hot_encode_object_array(arr):
    uniques, ids = np.unique(arr, return_inverse=True)
    return np_utils.to_categorical(ids, len(uniques))

def network_train(X, y):  ## X为特征向量, y为目标属性

    train_y_ohe = one_hot_encode_object_array(y)
    model = Sequential()
    model.add(Dense(60, input_shape=(200,)))
    model.add(Activation('sigmoid'))
    model.add(Dropout(0.02))  ## 避免过拟合
    model.add(Dense(42))
    model.add(Activation('softmax'))
    model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=["accuracy"])
    model.fit(X, train_y_ohe, nb_epoch=100, batch_size=1, verbose=1)
    return model

神经网络预测用户标签

def predict(X, model):
    predict_y = []
    result = model.predict_proba(X) ## 预测概率
    for i in range(0,result.__len__(), 1):
        result[i] = np.array(result[i])
        topk = result[i][np.argpartition(result[i],-3)[-3:]] ## 取概率最大的前三个标签
        predict = []
        for j in range(0,42,1):
            if result[i][j] in topk:
                predict.append(j)
        predict_y.append(predict)
    return predict_y

猜你喜欢

转载自blog.csdn.net/qq_30843221/article/details/78111957