[2017.4-5]; 自然语言处理课程项目
本来是上届师兄参加的比赛——SMP CUP微博用户画像大赛,这次作为我们 NLP 课程的项目
- 利用给定的新浪微博数据(包括用户个人信息、用户微博文本以及用户粉丝列表,详见数据描述部分),进行微博用户画像,具体包括以下三个任务:
- 任务1:推断用户的年龄(共3个标签:-1979/1980-1989/1990+)
- 任务2:推断用户的性别(共2个标签:男/女)
- 任务3:推断用户的地域(共8个标签:东北/华北/华中/华东/西北/西南/华南/境外)
- 形式上是一个多分类问题,特征工程是关键
当时刚刚接触机器学习,没有这个意识,大部分时间都用来熟悉模型了
- 停用词处理
- 对词频排序,手动筛选停用词
- 对未分词数据用 jieba 分词
- 关闭“新词发现”
- 扩充词典(网络收集,微博语料新词发现+人工筛选)
- 提取表情符
- 默认系列:
[微笑]
等
- 默认系列:
- 缺失值处理
- 根据缺失数据的比例决定填充还是丢弃
- 构建地域映射表(任务3)
- 基本特征
- 粉丝数量,微博数量,发布平台(来源),发布时间段(离散化),...
- 统计特征
- 平均每条微博的评论/转发人数,
- 最大/最小的评论/转发数,
- 博文中出现的地区数量,
- 每个时间段的发帖量(每小时,早中晚),...
- 交叉特征/特征组合
- 特征组合的种类
[A x A]
—— 对单个特征的值求平方形成的组合特征。[A X B]
—— 将两个特征的值相乘形成的组合特征。[A x B x C x ...]
—— 将多个特征的值相乘形成的组合特征。
- 组合 Ont-Hot 编码
-
组合两个
1*3
的编码可以得到一个1*9
的编码 -
比如组合发帖时间和发布平台
[早, 中, 晚]
x[手机, 电脑, 平板]
->[早+手机, 中+手机, 晚+手机, 早+电脑, ...]
-
- 特征组合的种类
- 词向量 word2vec
特征选择
- 使用 XGBoost 进行特征选择
params = {...} xgtrain = xgb.DMatrix(X, label=y) bst = xgb.train(params, xgtrain) importance = bst.get_fscore() importance = sorted(importance.items(), key=lambda x: x[1]) importance_df = pd.DataFrame(importance, columns=['feature', 'fscore']) importance_df.plot(kind='barh', x='feature', y='fscore')
[2017.7-9]; 第一届“讯飞杯”中文机器阅读理解评测 - CMRC 2017
- 由哈工大与讯飞联合举办的第一届“讯飞杯”中文机器阅读理解评测
- 数据集和任务格式是哈工大去年提出的。
工大去年的论文
[1607.02250]
研究了另一个相同形式的数据集。
-
以单个词为答案的填空类问题、用户提问类问题。答案会在上下文中出现。
只做了填空类问题
-
数据格式
篇章:由若干个连续的句子组成的一个文本段落,但文中缺少某一个词,标记为 XXXXX 问题:缺少的词 XXXXX 所在的句子 答案:缺少的词 XXXXX
-
示例
- 填空类问题
答案
1 ||| 工商 协进会 报告 , 12月 消费者 信心 上升 到 78.1 , 明显 高于 11月 的 72 。 2 ||| 另 据 《 华尔街 日报 》 报道 , 2013年 是 1995年 以来 美国 股市 表现 最 好 的 一 年 。 3 ||| 这 一 年 里 , 投资 美国 股市 的 明智 做法 是 追 着 “ 傻钱 ” 跑 。 4 ||| 所谓 的 “ 傻钱 ” XXXXX , 其实 就 是 买 入 并 持有 美国 股票 这样 的 普通 组合 。 5 ||| 这个 策略 要 比 对冲 基金 和 其它 专业 投资者 使用 的 更为 复杂 的 投资 方法 效果 好 得 多 。 <qid_1> ||| 所谓 的 “ 傻钱 ” XXXXX , 其实 就 是 买 入 并 持有 美国 股票 这样 的 普通 组合 。
<qid_1> ||| 策略
- 提问类问题
答案
1 ||| 工商 协进会 报告 , 12月 消费者 信心 上升 到 78.1 , 明显 高于 11月 的 72 。 2 ||| 另 据 《 华尔街 日报 》 报道 , 2013年 是 1995年 以来 美国 股市 表现 最 好 的 一 年 。 3 ||| 这 一 年 里 , 投资 美国 股市 的 明智 做法 是 追 着 “ 傻钱 ” 跑 。 4 ||| 所谓 的 “ 傻钱 ” 策略 , 其实 就 是 买 入 并 持有 美国 股票 这样 的 普通 组合 。 5 ||| 这个 策略 要 比 对冲 基金 和 其它 专业 投资者 使用 的 更为 复杂 的 投资 方法 效果 好 得 多 。 <qid_1> ||| 哪 一 年 是 美国 股市 表现 最 好 的 一 年 ?
<qid_1> ||| 2013年
- 填空类问题
- 类似语言模型的思路:
- 语言模型是根据前 n 个词从整个词表中预测下一个词;
- 这里是根据上下文并从中挑选正确的答案
- 可以采用 encoder-decoder 框架,这里相当于 "seq2word"
- 对语言建模来说,LSTM 的效果更好;
- 为了更好的获取全局的语义信息,可以使用多层 bi-LSTM 对上下文进行编码;
- Encoder 部分是一个2 层 bi-LSTM;因为语料不大,所以层数不多
TODO: LSTM
- 以答案断开材料,分为上文和下文;两者共享同一个 Encoder,即参数共享
为什么共享参数?——模拟人在做完形填空的过程,上下文会共同影响结果。
- 拼接 bi-LSTM 的两段输出向量得到上下文各自的特征向量;然后对上下文的特征向量求平均作为全局特征。
-
为了实现在上下文中搜索目标词,而不是在整个词表中:
控制 Encoder 的输出向量,即全局特征,与词向量的维度相同,然后计算其与段落中的每个词的 cos 距离(即内积),然后通过 softmax 得到所有词的概率分布。
- 原材料已经经过分句和分词处理,实际只是用了分词信息。
- 因为每个词有可能多次出现,所以需要对所有相同词的概率求和作为该词的概率。
- 未登录词的处理:所有未登录词会映射到同一个词向量,并开放训练
- 其他词向量在前 n 轮不参与训练,在 n 轮后会加入微调
[2017.10-2018.1]; CIPS-SOGOU问答比赛
- CIPS-SOGOU问答比赛是由中国中文信息学会(CIPS)和搜狗搜索(SOGOU SEARCH)联合主办的一项开放域的智能问答评测比赛。
- 针对每个问题 q,给定与之对应的若干候选答案篇章 a1,a2,…,an,要求设计算法从候选篇章中抽取合适的词语、短语或句子,形成一段正确、完整、简洁的文本,作为预测答案 apred,目标是 apred 能够正确、完整、简洁地回答问题 q。
- 示例
问题: 中国最大的内陆盆地是哪个 答案:塔里木盆地 材料: 1. 中国新疆的塔里木盆地,是世界上最大的内陆盆地,东西长约1500公里,南北最宽处约600公里。盆地底部海拔1000米左右,面积53万平方公里。 2. 中国最大的固定、半固定沙漠天山与昆仑山之间又有塔里木盆地,面积53万平方公里,是世界最大的内陆盆地。盆地中部是塔克拉玛干大沙漠,面积33.7万平方公里,为世界第二大流动性沙漠。
-
参考模型:BiDAF https://allenai.github.io/bi-att-flow/
-
参考论文:[1607.06275]——百度利用百度知道等资源构建一个 WebQA 数据集,数据形式与本次评测基本一致;
论文使用的模型如下:
- 编码部分
- 首先,使用 LSTM 对问题编码,得到问题的特征向量
rq
(LSTM + Attention); - 然后将问题的特征向量、材料的词向量以及其他可选的人工特征(词的共现特征)构成新的输入,通过一个多层 LSTM 编码器,得到新的组合特征。
- 首先,使用 LSTM 对问题编码,得到问题的特征向量
- 解码部分
- 解码部分使用的是 CRF(条件随机场),相当于将寻找答案的过程当做一个序列标注问题。
- 最终得到答案的位置——
B, I, O
分别表示 Begin、Inside、Outside 答案。
- 值得一提的是,论文用到了两个共现特征——
Question-Evidence common word feature
和Evidence-Evidence common word feature
- 前者表示每个材料中的词是否在问题中出现,后者表示在该材料中出现的词是否在其他材料中出现。
- 前者出于这一直觉——在问题中出现的词往往不是答案的一部分;后者则相反,在不同材料中多次出现的词很可能是答案的一部分。
- 模型的结构与 WebQA 基本相同:分为 Encoder 和 Decoder 部分
- 但是 Encoder 部分使用的是 CNN,而不是 LSTM
- 首先使用 CNN 对问题编码得到问题向量,具体使用了“空洞卷积”与“门卷积”(卷积+门限单元)
- 然后将得到的问题向量拼接到材料的每一个词向量之后
- 为了保留词的顺序信息,加入每个词的位置向量(Position Embedding)
如何构造位置向量 - “Attention is All you Need”
- 最后添加人工提取的共现特征(
Q
表示问题 Question问题,E
表示材料 Evidence)-
Q - E
匹配——表示每个材料中的词是否在问题中出现,出现为1
,否则为0
-
E - E
匹配——表示每个材料中的词是否在其他材料中出现。与 WebQA 中略有不同的是,因为有多段材料,实际使用的是含有该词的材料数/总的材料数
。而不是0/1
值。注意:无论在其他材料中出现几次,都只计 1 次,以防一些停用词获得过高的权重。
-
字符级共现特征——以上两个特征都是以词为单位的,同时还可以以字为单位,然后将字的特征做平均作为词的特征。
示例:比如问题中出现了“表演者”,材料中为“演员”,如果以“词”为标准,两者的共现关系的为
0
;如果以“字符”为单位,那么“演员”可以提供0.5
的Q - E
匹配特征。 -
Jaccard相似度、相对编辑距离等
-
- Docoder 部分参考了由百度 PointerNet,使用双指针输出来标注答案的位置
- 解码部分是一个多层 bi-LSTM,该网络使用问题特征来初始化参数
- 然后使用该编码器对材料特征进行解码
- 最后对整个序列对两次 Softmax 来预测答案的首尾位置。
DuReader/pointer_net.py at master · baidu/DuReader
损失函数由多部分组成
- 首先是位置损失,包括首指针的位置和尾指针的位置;
- 其次是材料损失,指示该段材料中是否存在答案,该损失的权重要高于位置损失;
- 最后加上 L2 正则化项。
"Attention is All you Need"
-
公式
注意:无论奇偶,指数部分都是
2i/d_pos
-
Python 代码
n_pos = 3 # 序列长度 d_pos = 5 # 向量维度 pos_vec = [] for pos in range(n_pos): pos_embed = [] for i in range(d_pos): if i % 2 == 0: pos_embed.append(math.sin(pos / pow(10000, (i-i%2) / d_pos))) # (i-i%2) == 2*(i//2) else: pos_embed.append(math.cos(pos / pow(10000, (i-i%2) / d_pos))) pos_vec.append(pos_embed) # [[0.0, 1.0, 0.0, 1.0, 0.0], # [0.84147, 0.5403, 0.02512, 0.99968, 0.00063], # [0.9093, -0.41615, 0.05022, 0.99874, 0.00126]]
-
矢量化代码
pos_vec = np.array([ [pos / np.power(10000, (i-i%2) / d_pos) for i in range(d_pos)] # (i-i%2) == 2*(i//2) for pos in range(n_pos) ]) pos_vec[:, 0::2] = np.sin(pos_vec[:, 0::2]) # dim 2i pos_vec[:, 1::2] = np.cos(pos_vec[:, 1::2]) # dim 2i+1
- 分词使用 jieba 库,关闭新词发现,手动将所有单词和数字拆分为单个字符