LDA主题模型试验

前段时间研究了一下爬虫,正好用它从csdn主页“大数据”、“移动开发”、“软件开发”三个栏目下爬取了一些技术资讯文章,从每个栏目下各取20片文档,看看能否用用LDA主题模型从中提取一些有意义的关键词,三个栏目下的文章都放在文本文件里,部分内容如下图所示

LDA主题模型试验_第1张图片

LDA主题模型试验_第2张图片

LDA主题模型试验_第3张图片

参考 《LDA漫游指南》以及论文《Parameter estimation for text analysis》,自己尝试实现了LDA模型参数估计的Gibbs抽样算法,代码如下 :

lda.py

#coding=utf-8
from __future__ import division
import random
import copy

class ldaModel:
    def __init__(self, documents = None, V = 0):
        self.documents = documents
        self.V = V # 词的总数
        self.K = 0 # 主题总数
        self.iterations = 10000 # Gibbs抽样迭代次数
        self.burnIn = 2000
        self.interval = 100 # Gibbs抽样的预烧期
        self.theta = None # 文档-主题分布律矩阵
        self.phi = None # 主题-词分布律矩阵
        self.Z = [] # 文档中词的主题

    # 配置参数
    def configure(self, iterations, burnIn, interval):
        self.iterations = iterations
        self.burnIn = burnIn
        self.interval = interval
        
    # Gibbs抽样
    def gibbsSampling(self, K, alpha, beta):
        self.K = K
        M = len(self.documents)
        numStats = 0
        nw = [[0 for col in range(self.V)] for row in range(self.K)]
        nwSum = [0 for row in range(self.K)]
        nd = [[0 for col in range(self.K)] for row in range(M)]
        ndSum = [0 for row in range(M)]
        thetaSum = [[0 for col in range(self.K)] for row in range(M)]
        phiSum = [[0 for col in range(self.V)] for row in range(self.K)]
        self.initialState(nw, nwSum, nd, ndSum)
        for i in range(self.iterations):
            for m in range(M):
                for n in range(len(self.documents[m])):
                    k = self.Z[m][n]
                    t = self.documents[m][n]
                    nw[k][t] = nw[k][t] - 1
                    nwSum[k] = nwSum[k] -1
                    nd[m][k] = nd[m][k] - 1
                    ndSum[m] = ndSum[m] -1
                    k1 = self.reSampling(m, t, alpha, beta, nw, nwSum, nd, ndSum)
                    self.Z[m][n] = k1
                    nw[k1][t] = nw[k1][t] + 1
                    nwSum[k1] = nwSum[k1] + 1
                    nd[m][k1] = nd[m][k1] + 1
                    ndSum[m] = ndSum[m] + 1
            if ((i > self.burnIn) and ((i - self.burnIn) % self.interval == 0)):
                for m in range(len(self.documents)):
                    for k in range(self.K):
                        # thetaSum[m][k] += (nd[m][k] + alpha) / (ndSum[m] + alpha * self.K)
                        thetaSum[m][k] = (nd[m][k] + alpha) / (ndSum[m] + alpha * self.K)
                for k in range(self.K):
                    for t in range(self.V):
                        # phiSum[k][t] += (nw[k][t] + beta) / (nwSum[k] + beta * self.V)
                        phiSum[k][t] = (nw[k][t] + beta) / (nwSum[k] + beta * self.V)
                # numStats = numStats + 1
        numStats = numStats + 1
        self.updatePara(thetaSum, phiSum, numStats)
        return nw, nwSum # 返回值,在预测新文档的主题分布时需要用到这两个量
        
    def initialState(self, nw, nwSum, nd, ndSum):
        M = len(self.documents)
        self.theta = [[0 for col in range(self.K)] for row in range(M)]
        self.phi = [[0 for col in range(self.V)] for row in range(self.K)]
        for m in range(M):
            N = len(self.documents[m])
            self.Z.append([])
            for n in range(N):
                k = random.choice(range(self.K)) # 随机生成第m篇文档中第n个词的主题编号
                self.Z[m].append(k)
                t = self.documents[m][n]
                nw[k][t] = nw[k][t] + 1
                nwSum[k] = nwSum[k] + 1
                nd[m][k] = nd[m][k] + 1
                ndSum[m] = ndSum[m] + 1
                
    def reSampling(self, m, t, alpha, beta, nw, nwSum, nd, ndSum):
        p = [0 for i in range(self.K)]
        for k in range(self.K):
            p[k] = (nw[k][t] + beta) * (nd[m][k] + alpha) / ((nwSum[k] + beta*self.V) * (ndSum[m] + alpha*self.K))
        for i in range(1, self.K):
            p[i] = p[i] + p[i-1]
        u = random.random() * p[self.K - 1]
        k1 = 0
        for i in range(self.K):
            if (u <= p[i]):
                k1 = i
                break
        return k1
    
    def updatePara(self, thetaSum, phiSum, numStats):
        for m in range(len(self.documents)):
            for k in range(self.K):
                self.theta[m][k] = thetaSum[m][k] / numStats
        for k in range(self.K):
            for t in range(self.V):
                self.phi[k][t] = phiSum[k][t] / numStats

    def get_top_words(self, vocabulary, N):
        topics_dic = {}
        k = -1
        for topic_words in self.phi:
            k += 1
            dic = {}
            for i in range(len(topic_words)):
                dic[i] = topic_words[i]
            word_prob_list = sorted(dic.iteritems(), key = lambda d:d[1], reverse = True)
            topics_dic["topic" + str(k)] = word_prob_list
            print "topic"+str(k),
            for word_prob in word_prob_list[0:N]:
                print vocabulary[word_prob[0]],
            print "\n"
        return topics_dic

    def get_top_topics(self, corpus):
        docs_dic = {}
        m = -1
        for doc_topics in self.theta:
            m += 1
            dic = {}
            for k in range(len(doc_topics)):
                dic[k] = doc_topics[k]
            topic_prob_list = sorted(dic.iteritems(), key = lambda d:d[1], reverse = True)
            docs_dic[(corpus.keys())[m]] = topic_prob_list
            for topic_prob in topic_prob_list[0:10]:
                print "topic" + topic_prob[0],
            print "\n"
        return docs_dic

    def predict(self, new_document, nw, nwSum, alpha, beta):
        # 预测新文档的主题分布
        # new_document是由词在总词表中的编号构成的列表,按出现顺序排列
        new_theta = [0 for col in range(self.K)]
        # new_phi = [0 for col in range(self.V)]
        new_nd = [0 for col in range(self.K)]
        new_ndSum = 0
        new_nw = copy.deepcopy(nw)
        new_nwSum = copy.deepcopy(nwSum)
        N = len(new_document)
        new_z = []
        for n in range(N):
            k = random.choice(range(self.K))
            new_z.append(k)
            t = new_document[n]
            new_nw[k][t] = new_nw[k][t] + 1
            new_nwSum[k] = new_nwSum[k] + 1
            new_nd[k] = new_nd[k] + 1
            new_ndSum = new_ndSum + 1
        for i in range(self.iterations):
            for n in range(N):
                k = new_z[n]
                t = new_document[n]
                new_nw[k][t] = new_nw[k][t] - 1
                new_nwSum[k] = new_nwSum[k] - 1
                new_nd[k] = new_nd[k] - 1
                new_ndSum = new_ndSum - 1
                p = [0 for i in range(self.K)]
                for j in range(self.K):
                    p[j] = (new_nw[j][t] + beta) * (new_nd[j] + alpha) / ((new_nwSum[j] + beta*self.V) * (new_ndSum + alpha*self.K))
                for j in range(1, self.K):
                    p[j] = p[j] + p[j-1]
                u = random.random() * p[self.K - 1]
                k1 = 0
                for j in range(self.K):
                    if (u <= p[j]):
                        k1 = j
                        break
                new_z[n] = k1
                new_nw[k1][t] = new_nw[k1][t] + 1
                new_nwSum[k1] = new_nwSum[k1] + 1
                new_nd[k1] = new_nd[k1] + 1
                new_ndSum = new_ndSum + 1
        for k in range(self.K):
            new_theta[k] += (new_nd[k] + alpha) / (new_ndSum + alpha * self.K)
        # for t in range(self.V):
        #     new_phi[t] += (new_nw[k][t] + beta) / (new_nwSum[k] + beta * self.V)
        return new_theta, new_z
下面的代码用来生成语料库,

tetx_clean.py

#coding=utf-8
from __future__ import division
import jieba

def extract_structed_data(corpus, documents_tf, doc_name, doc_content, stop_words):
    # corpus是个字典,key是文档名,value是该文档中所有词(允许重复)构成的列表
    # documents_tf是个字典,key是文档名,value是以词为key,以tf值为key的字典
    # doc_name是文档名
    # doc_content是文档的内容(可能需要作编码转换,以及删除一些非文字符号)
    words_list = jieba.cut(doc_content) # 可能需要事先添加一些符合业务场景的专有词,不然结巴分词无法识别
    corpus[doc_name] = []
    documents_tf[doc_name] = {}
    for word in words_list:
        if not(word.strip() in stop_words) and len(word.strip()) > 1:
            corpus[doc_name].append(word)
            documents_tf[doc_name].setdefault(word, 0)
            documents_tf[doc_name][word] += 1

def clean_words(corpus, documents_tf, tf_min):
    # documents是LDA模型的输入参数之一
    # vocabulary是清理文档中的低频词之后得到的词语列表
    # m是文档在corpus.keys()中的索引
    # documents[m][n]的值是第m个文档中第n个词在vocabulary中的索引
    # tf_min是词在文档中出现次数的临界值
    # 在文档中出现次数太少的词对于阐述文档的主题没有意义,将这些词剔除
    new_documents_tf = dict(documents_tf)
    for doc_name in documents_tf.keys():
        for word in documents_tf[doc_name].keys():
            if documents_tf[doc_name][word] < tf_min:
                new_documents_tf[doc_name].pop(word)
    # 剔除掉低频词之后,将所有的词整合进总词表vocabulary中
    vocabulary = []
    for doc_name in new_documents_tf.keys():
        for word in new_documents_tf[doc_name].keys():
            if not (word in vocabulary):
                vocabulary.append(word)
    # 构建documents矩阵
    documents = []
    m = -1
    for doc_name in new_documents_tf.keys():
        documents.append([])
        m += 1
        for word in corpus[doc_name]:
            if word in vocabulary:
                documents[m].append(vocabulary.index(word))
    return vocabulary, documents
下面的代码对文本文件进行处理并调用text_clean模块中的方法生成语料库

corpus = {}
documents_tf = {}
# 提取article_crawler_result_1.txt中存储的前20篇文档,大数据相关文章
file_bigdata = open("D:/article_crawler_result_1.txt", "r")
k = 0
for line in file_bigdata:
    k += 1
    if k > 20:
        break
    line_elements = line.split("\t")
    doc_name = line_elements[1]
    doc_content = line_elements[7]
    text_clean.extract_structed_data(corpus, documents_tf, doc_name, doc_content, stop_list)
# 提取article_crawler_result_2.txt中存储的前20篇文档,移动开发相关文章
file_mobile = open("D:/article_crawler_result_2.txt", "r")
k = 0
for line in file_mobile:
    k += 1
    if k > 20:
        break
    line_elements = line.split("\t")
    doc_name = line_elements[1]
    doc_content = line_elements[7]
    text_clean.extract_structed_data(corpus, documents_tf, doc_name, doc_content, stop_list)    
# 提取article_crawler_result_3.txt中存储的前20篇文档,软件开发相关文章
file_sd = open("D:/article_crawler_result_3.txt", "r")
k = 0
for line in file_sd:
    k += 1
    if k > 20:
        break
    line_elements = line.split("\t")
    doc_name = line_elements[1]
    doc_content = line_elements[7]
    text_clean.extract_structed_data(corpus, documents_tf, doc_name, doc_content, stop_list)    
file_bigdata.close()
file_mobile.close()
file_sd.close()
# 将每篇文章中出现次数低于5的词全部剔除
vocabulary, documents = text_clean.clean_words(corpus, documents_tf, 5)
有了所有词语构成的列表vocabulary以及文档矩阵documents,可以开始训练LDA主题模型了,

alpha = 0.5
beta = 0.1
new_lda = lda.ldaModel(documents = documents, V = len(vocabulary))
new_lda.configure(300, 100, 5)
nw, nwSum = new_lda.gibbsSampling(30, alpha, beta) #  取30个主题
LDA主题模型的Gibbs抽样算法的训练相当耗时,经过将近5分钟的运行之后,可以得到训练好的模型,

首先查看主题-词语矩阵,每个主题按照概率降序显示前20个关键词,

topics_dic = new_lda.get_top_words(vocabulary, 20)

topic0 VR HTC Vive 游戏 开发者 虚拟现实 制作 内容 体验 用户 场景 交互 demo 12 Valve 眩晕 平台 设计 王雪红 游戏设计 
topic1 软件 ca 研发 设计 推荐系统 核心 实践 My 海量 商品 借助 应对 简单 流量 京东 案例 JavaScript 分享 架构 成员 
topic2 编程语言 排行榜 榜单 Java TIOBE Objective 2015 专访 借助 推出 简单 Swift 形态 发布 Facebook 编程 定时 数量 年度 BDTC 
topic3 CSDN 移动开发 平台 开发工具及服务 评选 年度 大奖 机器 形态 订阅 产品 策略 2015 技术架构 企业 近匠 生态 参与 信息 解读 
topic4 架构 业务 数据 架构师 模块 广告 工作 服务 系统 设计 技术 研发 公司 广告平台 负责 媒体 挑战 思路 算法 提升 
topic5 自动化 选择 运维 查询 AWS 方案 时间 日志 更新 管理 服务器 master 产品 python puppet 证书 架构 工作 国内 监控 
topic6 HTML5 App 流应用 原生 产业 JS 手机 Facebook 体验 OS 微信 强化 Native 360 React 推出 下载 优势 助手 公司 
topic7 超图软件 企业 Confluence 员工 企业级应用 图表 工作效率 发布 企业级 FishEye 数量 移动应用 来源 提高 内部网 GIS 原因 提升 信息 程序 
topic8 团队 工具 工作 产品 效率 成员 沟通 解决 功能 代码 设计 项目 情况 管理 在线 最终 包括 文档 需求 未来 
topic9 算法 搜索 用户 查询 介绍 推荐 系统 2015 主题 一种 大规模 思路 实践 计算 提升 典型 画像 专场 优化 实时 
topic10 大数据 数据 发展 互联网 系统 企业 能力 潘柱廷 领域 云计算 工业 技术 支持 调研 决策 老百姓 可视化 生态 产业 推动 
topic11 视频 机构 流程 活动 大规模 策略 Docker 容器 特性 ca 响应 CEO 监控 辨识 搜索 编写 列表 创建 需求 多个 
topic12 方案 日志 数据 高可用 同步 HDR 节点 逻辑 SDS GBase 数据库 8t 提供 故障 业务 多个 RSS 容灾 集群 连接 
topic13 VR Nibiru 交互 领域 虚拟现实 SDK 近匠 曹峻 开发者 硬件 负责 一体机 ROM 未来 发布 推动 世界 优化 企业 联合 
topic14 企业 微信 需求 互联网 生态 连接 行业 企业号 时间 IBOS 公众号 定制 场景 产品 营销 机会 数量 分享 媒体 电商 
topic15 系统 数据 存储 服务 商业 查询 分布式 内存 搜狗 缓存 平台 数据库 体系 架构 功能 计算 访问 业务 延迟 服务化 
topic16 project property 仓库 gradle ca 插件 properties li task 工程 Maven 构建 Gradle java android 构件 发布 plugin SDK sdk 
topic17 游戏 任天堂 Ouya 游戏产业 收购 YouTube 岩田 主机 公司 主播 动视暴雪 承诺 雷蛇 视频 移动市场 总裁 Razer 全球 厂商 FTC 
topic18 深度学习 神经网络 模型 学习 系统 方法 ca 工作 简单 计算机 提出 对话 记忆 自然语言处理 准确率 人脑 研究 数据 Neural 参数 
topic19 识别 文字 自动 语音识别 深度 特征 客服 2015 深度学习 哈希 依赖 检测 介绍 场景 模型 Learning 压缩 计算 BDTC 两个 
topic20 数据 大数据 实时 平台 分析 信息 分享 挖掘 领域 互联网 技术 获取 模型 出行 融合 决策 包括 机器翻译 引擎 政府 
topic21 Android Studio 项目 依赖 gradle ADT build 文件 介绍 project 迁移 版本 tags 功能 模块 代码 IDE jar compile bug 
topic22 图标 设计 尝试 图标设计 用户 视频 标的 可扩展性 App 确保 案例 文字 相关 东西 想到 背景 包含 尺寸 核心 简单 
topic23 作业 job 服务器 系统 分片 代码 elastic 功能 框架 开源 分布式 中心 张亮 模式 ddframe 注册 定时 分配 Zookeeper 运行 
topic24 文件 oat 运行 dex 文件夹 ART 反编译 framework 虚拟机 Android Dalvik arm 过程 翻译 boot 5.0 机器码 Google 生成 核心 
topic25 大数据 2015 题目 分享 教育 百度 教师 学习 12 BDTC 关注 语音 跟谁学 英语流利说 关系 云计算 识别 光量子 拓维信息 论坛 
topic26 流程 工具 创建 一种 发送 消息 模型 策略 全球 内容 互联网 对话 监督 更好 思路 释放 个性化 在线 游戏 社区 
topic27 大数据 广告 机器学习 数据 算法 推荐 微博 演讲 模型 百度 论坛 分享 预测 测量 PPT 包括 特征 2015 信息 BDTC 
topic28 采用 这方面 实践 国内 Hadoop VR Facebook 建立 世界 交互 关系 信息 特征 购买 未来 节点 知识 构建 开发 列表 
topic29 京东 技术 推荐 模型 美团 专家 推荐系统 数据 排序 学习 演讲 在线 场景 联盟 存储 采用 学院 中国互联网技术联盟 商品 企业 
topic30 App 开发者 Store 搜索 描述 ASO100 下载 关键字 优化 用户 应用商店 下载量 Play 选择 名称 数据 iOS ASO Google Apple 
topic31 Docker 云计算 容器 延迟 甲骨文 StackEngine 配置 网络 购买 虚拟化 部署 内存 Linux 管理 宿主机 提升 选择 网卡 员工 控制 
topic32 数据 星图 崔仑 双十一 采集 主持人 数据处理 提升 资料 直播 渠道 搜索 Kafka 淘宝 搜索引擎 互联网 Spark 阿里 CEO CTO讲堂 
topic33 CSDN Atlassian JIRA 产品 中国 公司 开发者 Paul Conroy 敏捷 销售 2015 论坛 董家昌 国内 Avangate 亚太区 Confluence 软件开发 专访 
topic34 验证 极验验证 网站 验证码 张振宇 用户 开发者 行为式验证 技术 框架 传统 用户体验 近匠 特征 服务 互联网 识别 安全性 基础 痛点 
topic35 性能 方法 安装 产品 大数据 信息 Java 越来越 社交 调度 架构 数字 企业 推出 集群 项目 IT 利用 解决 配置 
topic36 分布式 SQL HBase 数据库 事务 TiDB 选择 KV Google MySQL 优化 协议 过程 F1 拥有 Spanner 内部 Percolator 迁移 业务 
topic37 CSDN 相关 技术 推荐 2015 文章 数据库 书籍 下载 架构 方式 最新 程序员 Android 关注 订阅 HTML5 CTO Swift iOS 
topic38 技术 产品 发展 公司 提供 系统 CTO 创始人 行业 团队 时间 联合 企业 介绍 方向 业务 云计算 发现 研究 10 
topic39 主题 信息 GC 订阅 消息 用户 更新 世界 服务 设备 API NPR 数量 开发者 功能 个性化 定制 半年 通知 发送 
topic40 游戏 API 视频 开发者 文档 Games 数据 公司 Google Guild 内容 Online 论坛 网页 玩家 盘点 网站 在线 Facebook Twitch 
topic41 迁移 订阅 启动 标准 计算 新浪微博 数据库 功能 指标 MySQL Hadoop 自动 腾讯 OpenStack 架构设计 思路 一种 阿里 规模 探索 
topic42 内存 Node.js 程序 LLVM Swift 代码 V8 函数 垃圾回收 运行 类型 内存泄漏 执行 导致 文件 JavaScript ca 创建 机制 释放 
topic43 EC2 VPC AWS 实例 迁移 CloudEndure 复制 Classic 创建 安装 过程 Amazon 代理 服务器 时间 选择 负荷 云计算 最新 账户 
topic44 OpenStack 服务 节点 网络 高可用 HA 云计算 架构 存储 方案 核心 设计 Cinder 接入 Rabbitmq Router Nova 基础 DHCP Neutron 
topic45 AWS 亚马逊 服务 云计算 数据库 中国 数据分析 快速 公有云 提供 未来 数据 威格尔 开发者 永康 沃纳 企业 Amazon 大会 无处不在 
topic46 Oracle 数据库 技术 RAC 工作 高斌 特性 Exadata ca 切换 提供 节点 功能 故障 SQL 实例 专访 版本 存储 语句 
topic47 数据 分析 大数据 ODPS 客户 明略数据 日志 墨迹 任鑫琦 优化 DB 墨迹天气 Mongo SCOPA 12 专访 Fluentd 统计 导入 2015 
topic48 云智慧 APM 请求 监控 高驰涛 架构 用户 分析 管理 数据 服务 主持人 IT 领域 事务 客户 准确 互联网 关注 App 
topic49 Maps GIS Polymaps 数据挖掘 高可用 系统 管理 开发者 技术支持 底层 监控 深度 下载 创建 保证 多个 涉及 cto tion 海量 
topic50 Worktile 产品 王涛 服务 文件 实时 团队协作 选择 Web 消息 协议 变化 时代 客户端 协作 数据 创业 近匠 页面 AngularJS 
topic51 机器学习 算法 Java 大数据 用于 框架 Apache 面向 数据挖掘 Spark 25 编写 工具 知识 ML 研究 提供 API 分布式 分类 
topic52 公司 产品 特性 解读 账号 对话 微博 优秀 App 发布 协议 配置 包含 两个 工具 插件 总监 能力 思路 1.2 
topic53 密码 洋葱 企业 吴洪声 身份验证 验证 解决 口令 创始人 生物识别 环节 管理 主持人 创业 方式 员工 DNSPod 账号 泄露 登陆 
topic54 网络 数据中心 微软 虚拟 SDN 硬件 技术 企业 物理 方式 连接 Greenberg Albert 设备 控制器 运行 客户 改变 部署 Azure 
topic55 Anypoint 功能 消息传递 异步 发布 MuleSoft MQ 包含 企业 解决方案 事件 语言 趋势 包括 微博 管理 iOS 推出 方案 主题 
topic56 SQL Hadoop 孙元浩 技术 星环 OS 关系 市场 科技 取代 性能 TDH 部署 BDTC 架构 Spark 数据仓库 基础 数据分析 定位 
topic57 大数据 优化 推出 知识 环节 操作 成本 变化 提高 服务端 开源 最新 实时 联合 公司 案例 自动 方法 需求 提出 
topic58 企业 大数据 数据 行业 发展 互联网 传统 云计算 普元 焦烈焱 数字化 公司 业务 时代 提供 核心 一篇 模式 变化 利用 
topic59 语言 Rust Go C++ github https 项目 http 社区 rs 取代 代码 一点 挑战 一种 优势 编程 语法 工程 org

观察上方的主题-词矩阵,发现有些主题的含义还是很明显的,比如说:topic56代表数据仓库,topic51代表机器学习,topic30代表移动开发,topic27代表算法,topic18代表深度学习,topic0代表虚拟现实。当然有些主题还是很难概括的,这应该和训练数据的质量有关。

利用文档-主题矩阵可以查看与每篇文档关联度最大的主题,代码如下:

document_id = 11
print unicode(documents_tf.keys()[document_id], "utf-8")
dic = {}
for k in range(len(new_lda.theta[document_id])):
    dic[k] = new_lda.theta[document_id][k]
topic_prob_list = sorted(dic.items(), key = lambda d:d[1], reverse = True)
for topic_prob in topic_prob_list[0:1]:
    topic_id = topic_prob[0]
    print "topic" + str(topic_id),
    topic_words = new_lda.phi[topic_id]
    dic = {}
    for i in range(len(topic_words)):
        dic[i] = topic_words[i]
    word_prob_list = sorted(dic.iteritems(), key = lambda d:d[1], reverse = True)
    for word_prob in word_prob_list[0:20]:
        print vocabulary[word_prob[0]],
    print "\n"
运行结果如下

 
  
【BDTC 2015】深度学习分论坛:DL的图像识别、语音识别应用进展及MxNet开源框架...
topic19 识别 文字 自动 语音识别 深度 特征 客服 2015 深度学习 哈希 依赖 检测 介绍 场景 模型 Learning 压缩 计算 BDTC 两个 
可以看出,训练出来的模型比较准确地概括出了一片与深度学习应用有关的文档的主题,

再换一篇文档试一下,

document_id = 22
OpenStack高可用核心架构分析
topic44 OpenStack 服务 节点 网络 高可用 HA 云计算 架构 存储 方案 核心 设计 Cinder 接入 Rabbitmq Router Nova 基础 DHCP Neutron 

发现训练好的模型对这两篇文档的主题的概括还是比较准确的,但也有例外

 
     
document_id = 29
【BDTC专访间】星环科技创始人兼CTO孙元浩:分布式必将替代关系型数据库topic9 算法 搜索 用户 查询 介绍 推荐 系统 2015 主题 一种 大规模 思路 实践 计算 提升 典型 画像 专场 优化 实时
文章的主题应该是与数据仓库有关的,但是模型得到的主题却无法反映这篇文档的内容,

可以看一下这篇文档的高频词,

29 【BDTC专访间】星环科技创始人兼CTO孙元浩:分布式必将替代关系型数据库
技术:20 大数据:14 SQL:13 Hadoop:11 数据库:10 孙元浩:10 星环:9 CSDN:8 发展:7 Spark:7 架构:7 市场:7 产品:6 未来:6 OS:6 云计算:5 实时:5 取代:5 TDH:5 数据仓库:5 
感觉这篇文章的很多高频词与数据仓库的关联度并不大,这应该是模型得到的主题却无法反映这篇文档的内容的原因,

再看一下刚才被准确预测主题的那篇文章

11 【BDTC 2015】深度学习分论坛:DL的图像识别、语音识别应用进展及MxNet开源框架...
文字:21 识别:19 深度学习:17 哈希:15 客服:13 2015:13 数据:13 特征:13 分享:12 模型:12 语音识别:11 场景:11 深度:10 压缩:10 自动:9 依赖:9 BDTC:9 视觉:9 检测:9 两个:9 
应该可以得到一个结论:主题模型应用在主题比较集中的文档上才会取得较好的预测结果。

下面利用lda模块中的方法predict来预测新文档的主体分布

# 预测新文档的主体分布
document_id = 21
new_document = new_lda.documents[document_id]
print unicode(documents_tf.keys()[document_id], "utf-8")
new_theta, new_z = new_lda.predict(new_document, nw, nwSum, alpha, beta)
# 显示新文档的主题分布
dic = {}
for k in range(len(new_theta)):
    dic[k] = new_theta[k]
topic_prob_list = sorted(dic.items(), key = lambda d:d[1], reverse = True)
for topic_prob in topic_prob_list[0:1]:
    topic_id = topic_prob[0]
    print "topic" + str(topic_id),
    topic_words = new_lda.phi[topic_id]
    dic = {}
    for i in range(len(topic_words)):
        dic[i] = topic_words[i]
    word_prob_list = sorted(dic.iteritems(), key = lambda d:d[1], reverse = True)
    for word_prob in word_prob_list[0:20]:
        print vocabulary[word_prob[0]],
    print "\n"

深度学习的最新进展及诺亚方舟实验室的研究
topic18 深度学习 神经网络 模型 学习 系统 方法 ca 工作 简单 计算机 提出 对话 记忆 自然语言处理 准确率 人脑 研究 数据 Neural 参数 

document_id = 48
谷歌云推送服务(GCM)半年内增一倍,日处理1500亿条消息
topic39 主题 信息 GC 订阅 消息 用户 更新 世界 服务 设备 API NPR 数量 开发者 功能 个性化 定制 半年 通知 发送 

发现预测结果在部分文档上还是比较准确的。

通过这次实践,发现要想LDA模型取得较好的结果,最好满足以下条件:1.清理一些无法反映文档主题的词;2.文档的主题比较集中;3.设置较大的迭代次数,

由于LDA Gibbs抽样算法的复杂度较高,每次训练都要运行很长时间,导致没有时间去尝试其它的参数组合,也许尝试一些其它的参数组合会得到比本文更好的结果。

你可能感兴趣的:(数据挖掘与机器学习)