半监督学习在金融文本分类上的探索和实践

垂直领域内的自然语言处理任务往往面临着标注数据缺乏的问题,而近年来快速发展的半监督学习技术为此类问题提供了有希望的解决方案。文本以 Google 在 2019 年提出的 UDA 框架为研究主体,详细探索该技术在熵简科技真实业务场景中的实践效果。

本文主要有三方面的贡献。第一,以金融文本分类为案例,探索了 UDA 在真实场景中的效果和不足;第二,探索了 UDA 在轻量级模型上的效果;第三,增加了原始 UDA 论文中未披露或未完成的研究,如领域外数据的影响,错误标记数据的影响。

1背景

2金融领域的问题为什么需要半监督技术

3 UDA技术介绍及特性

3.1 UDA技术的基本框架和核心思想

3.2在少量标签数据上的表现,by Google 团队

3.3在领域外数据上的表现,by 熵简团队

3.4在错误数据上的表现,by 熵简团队

4 UDA技术在金融文本分类上的实践

4.1案例背景及数据集特点

4.2实验方案

4.3主要实验结果及分析

4.3.1有标签数据的数据量对于模型的影响

4.3.2对比不同的增强方案

4.3.3 CNN与 BERT 的对比实验

5总结

1 背景

前段时间我们团队针对深度学习时代的半监督学习技术进行了梳理,详细介绍了半监督技术的发展历程,以及各技术在核心思想、方法论上的演进,感兴趣的朋友可以查看原文:

我们真的需要那么多标注数据吗?半监督学习技术近年来的发展历程及典型算法框架的演进 - 知乎

从文中我们似乎看出,当前的半监督技术似乎已经具备了与监督学习相比拟的优势。那么在真实场景中,半监督技术是否依然可以如实验室中的表现,可以在真实问题上发挥出独特的优势,降低我们对于标签数据的需求。

本文基于熵简NLP团队在真实业务场景上的实践经验,从垂直领域对于半监督技术的需求出发,详细介绍半监督学习中最新的代表技术之一UDA 算法的特性,以及在金融文本分类任务上的落地实践。

借此,我们可以在2020年这个时间点,初窥半监督技术对于真实场景问题的价值。

2 金融领域的问题为什么需要半监督技术

我们在前面一篇文章已经提到,金融领域内的自然语言处理问题属于典型的垂直领域问题,在面对特定任务场景时,常常面临的一个重要挑战就是少样本。这主要体现在两个方面:

1、可收集到数据总量少,数据收集的时间成本很高,尤其在从0到1的立项初期。曾经在某个项目上,我们用了三周时间才搜集到1000多条有效样本。

2、数据的人工标注成本很高。由于自然语言处理任务大部分属于认知层面的任务,因而数据标注的难度和不确定性显著高于感知层面的任务,例如图像识别、语音识别等。而对于金融领域的问题,往往需要资深金融分析师的参与才能实现相对准确的数据标注,满足业务需求。这不仅增大了标注的成本,也会显著延长标注的时间。因为在实际中,金融分析师很难有大块的时间来协助标注,这往往会延长项目周期。

对于第一点,我们可以通过文本增强、迁移学习、few-shot learning 以及元学习等等技术或者思想来尝试解决。对于特定的任务,我们目前已经取得一些较好的成果,由于不属于本文的讨论范围,这里就不再详细展开,有兴趣的同学可以查看专栏的其他相关文章。

对于第二点,为了让大家有更直观的感受,下面给出一个实例。对于金融文本,为了方便阅读和快速筛选,往往需要对文本按照内容分为不同的类型,比如公司点评、公司深度、行业点评、行业深度等等。如下案例所示:

文本1:非银金融周观察:坚守长期价值,优选个股。

文本2:生猪养殖行业专题报告三十六:当下养殖板块投资的核心矛盾是什么?

对于上述的两个文本,到底哪个文本属于行业点评,哪个属于行业深度呢?(具体答案可查看 4.1 节) 显然,只有金融领域相关的专业人士才能做出比较准确的标注。

因此,对于人工标注成本高的问题,我们希望能够找到这样的解决方案:

首先由人类专家对数据进行少量标注,在这个基础上,算法同时利用少量标注的有标签数据和还没有标注的大量无标签数据进行学习,最终也能达到较好的性能,满足业务需求。

这一目标正是半监督学习核心想要达成的目标。接下来,我们开始分享团队在探索半监督技术 UDA 算法过程中的具体收获和重要结果。

3 UDA 技术介绍及特性

3.1 UDA 技术的基本框架和核心思想

UDA 算法是由 Google 团队在 2019 年提出的半监督技术,超越了包括同年提出的 MixMatch 在内的一众半监督算法,达到了当时的 SOTA 水平。

上图即是 UDA 算法的基本框架,该框架对于模型网络本身并没有特别的要求,核心是对目标函数进行了改造。从图中可以看出,UDA 的目标函数共包括两个部分,分别是有监督损失项和无监督损失项:

1、有监督损失项(Supervised Cross-entropy Loss):用来计算有标签数据的误差,采用了常用的交叉熵作为目标。

2、无监督损失项(Unsupervised Consistency Loss):用来计算无标签数据的误差。具体的方式是,对于任何一个无标签数据,首先运用数据增强技术对于该数据进行一次变换操作。接下来,利用模型对于增强前后的数据分别进行预测,从而获取到模型对于同一条数据在增强前后的不同结果。最后,利用 KL 散度来度量这两个预测结果的距离。整个训练的过程就是要让这个距离尽可能小。

对于整个UDA算法,其中最核心部分就是一致性假设,即模型在输入数据的附近空间应该是平坦的,即使输入数据发生微弱变化或者发生语义不变而仅仅是形式变化时,模型的输出也能够基本保持不变。这本质上是传递了模型设计者对于模型的一种先验信念。

3.2 在少量标签数据上的表现,by Google 团队

接下来我们看一下原始论文中,对于 UDA 算法的实验结果,本文主要展示 NLP 相关的实验。

上面一张表分别展示了 UDA 算法在 IMDb,Yelp-2,Yelp-5,Amazon-2,Amzon-5 以及 DBpedia 这几个数据集上的实验结果。整张表分别上下两个部分,其中上面部分展示了各个数据集在完整数据集下的SOTA表现,作为参照组来对比 UDA 的效果。

下面部分则展示了不同网络模型在仅有少量标签数据下,是否采用 UDA 框架,对于模型最终性能的影响。从表中我们至少可以得出三方面的结论:

1、UDA 框架可以帮助模型在仅有很少有标签数据下接近或超过 SOTA 表现。对比 IMDb 下 BERT_large 在 20 条有标签数据和 2.5 万有标签数据下的表现,二者在错误率上仅差 0.2%。类似的结果在其他数据集下也能看到;

2、在少标签场景下,UDA 框架可以帮助模型显著提升性能。对比 BERT_base 在 5 个数据集下(除 DBpedia 以外)的表现,UDA 的引入给模型均带来了 10个 百分点以上的提升;

3、UDA 框架给模型带来的提升大小与数据集分布相关。对比 Random 在 Yelp-2 和 Yelp-5 上的表现,UDA 给模型带来的提升与数据集分布以及具体任务难度相关。

原始论文的研究由于采用了标准数据集,因此停留在实验室理想条件,而实际情况往往没有这么理想。接下来,我们团队进一步研究,UDA 在遇到真实场景中两类典型问题时的表现。

3.3 在领域外数据上的表现,by 熵简团队

我们知道,如果要采用半监督技术,那就意味着需要引入大量无标签的数据,而在真实场景中,无标签数据由于没有经过人工筛选或者只能进行粗筛选,那么必然会混入类别外或领域外的数据。这类数据是否会对模型的表现带来负面影响?

3.3.1 实验一:在 IMDb 数据集中混入 Yelp-2 数据

Yelp 数据集整理自 Yelp 网站(美国版大众点评)上的用户评论,其中的文本是与 IMDb 数据集类似的点评类短文本,区别在于二者所涉及的领域不太一样,IMDb 主要集中在影视相关的评论,而 Yelp 涉及的领域则更为广泛,可参考国内的大众点评上的评论。

在保持 IMDb 的有标签数据仍然为 20 条的情况下,我们随机从 Yelp 挑选一定数据量的数据混入无标签数据。在混入数据量占整体无标签数据量的比例分别为 5% - 30% 等五种不同条件下,我们在 BERT_base 上进行了实验。

实验结果如上表所示,从表中可以发现,Yelp 数据集的引入并没有给模型带来负面影响,大多数情况下,反而给模型带来了1 百分点左右的额外提升。这背后的原因或许是,Yelp 数据集虽然所涉及的领域与 IMDb 有所差异,但是其本身所蕴含的情感表现方式与 IMDb 数据集类似。因此从文本情感这个角度来看,二者在分布上是类似的,这一点对于情感分类这样的监督任务是有益的。

3.3.2 实验二:在 IMDb 数据集中混入 20 Newsgroups 数据

20 Newsgroups 数据集包含有 20 个不同主题的新闻类文本,其中的文本不论是在文本内容、语言表达方式以及涉及的领域上都与 IMDb 数据集中的文本存在明显差异。

我们在 20 Newsgroups 上做了与上述 Yelp 类似的实验。同样地,我们从 20 Newsgroups 数据集的 20 个类别中随机选择一定数据量的文本混入无标签数据中。同时,将混入比例最高调整到了 100%,这对应着在无标签数据完全采用 20 Newsgroups 的数据。

从上表的实验结果中,我们至少可以得出三方面的结论:

第一,20 Newsgroups 作为无标签数据加入训练,可以帮助模型带来近1个百分点的提升。这似乎说明了,即使是领域外甚至其他类型的文本加入,这部分数据依然可以通过一致性正则来帮助模型进行更好地学习;

第二,当 20 Newsgroups 的比例为 100% 时,模型的表现几乎与随机预测一样(对于二分类,随机预测的准确率是 50%)。这说明在 UDA 框架中,无标签数据同样可以给监督任务提供较强的学习信号;

第三,综合前两项结果,我们可以知道,在 UDA 框架中,无标签数据同时提供着两类学习信号。一方面,通过一致性正则提供无监督的学习信号,从约束模型对输入的变化不敏感;另一方面,也为有监督任务提供学习信号。

从前面两个实验中,我们是否可以得出结论,在半监督学习中,无标签数据即使混入领域外的数据,对于模型的训练也不会产生负面的影响。

我们认为这样的结论是不成立的。之所以在本实验中表现出类似的现象,是因为这两个实验所加入的其他数据集,其与 IMDb 的区别主要体现在文本形式、文本内容的主题等特征上,这与情感分类这个监督任务所需要的特征不在同一个维度上,因而不会产生干扰。

换言之,如果加入的其他数据集与当前数据集在特征上的差异与监督任务所重点关注的特征是正交的,那么这个数据集就不会对模型的训练带来负面影响

3.4 在错误数据上的表现,by 熵简团队

在真实场景中,另一类不可避免的问题是,数据的标签很难保证绝对的正确。接下来,我们通过实验验证,当有标签数据中存在部分错误标记时,模型在 UDA 框架下的表现。

在实验中,我们从 IMDb 数据中选取 200 条数据作为有标签数据,剩下的数据作为无标签数据。同时,对于有标签数据,按照一定比例对于其标签进行打乱。

从上表的结果可以发现,当错误标签比例为 10% 时,原生 BERT 的准确率下降了 6 个百分点(相对下降率约为 9%),而 UDA BERT 只下降了一个百分点(相对下降率约为 1%);而错误比例增大到 20%时,原生BERT的下降了近七个百分点,而 UDA BERT 则下降了4个百分点。

因此,无论从绝对下降值还是下降率来看,UDA 框架对于错误标签具备有一定的抑制作用。尤其当错误比例较低时,UDA 可以保证模型的准确率基本不受错误标签的影响。这无疑是一项吸引人的特性,而背后的原因或许来自于 UDA 中的锐化操作,即要求模型的分割平面不穿过数据分布密度较高的区域。而更深层的原因则需要更深入的研究分析。

4 UDA 技术在金融文本分类上的实践

了解了 UDA 的基本特性以及在实验室条件下的优良表现之后,本节将以金融资管领域中的一类金融文本分类问题作为实际任务,用来验证 UDA 算法在真实任务场景中的表现。

4.1 案例背景及数据集特点

此案例来自于熵简科技信息流相关的产品,其核心任务是对金融类短文本按照文本内容进行类型分类,打上标签,从而方便用户更及时、更精准地触达感兴趣的内容。

我们对原任务进行了简化,从原始的 15个类别中抽离出最典型的 6个类别,分别为:公司深度分析类、公司点评类、行业深度分析类、行业点评类、固收报告类以及宏观策略类。

为了更直观地感受数据,这里展示了几个类别的典型样本:

公司深度:本文详细测算了AWP龙头制造商的产能、销售规模情况;龙头租赁商的保有量、采购计划和主要合作厂商;同时测算了目前的终端租金对应的回报率水平。依然重点推荐 xx科技。

公司点评:【xx科技】市场位势上移驱动业绩超预期,未来估值继续向一线龙头靠齐。今日公司股价大涨 xx%,主要由于其发布盈喜公告19年净利润超xx亿,显著超出市场预期。

行业深度:生猪养殖行业专题报告三十六:当下养殖板块投资的核心矛盾是什么?

行业点评:空调价格竞争或已步入后半程,基于对历史上空调行业价格竞争的对比分析,判断11月大概率为近期空调均价同比降幅极值所在,本轮价格竞争或已步入后半程。

在接下来的实验中,我们按照时间顺序选取各类别样本共约 1.5 万条作为训练集,1200 条数据作为测试集:

1、在训练集中,有标签样本约为 1200 条,各类别基本均衡。剩余的 1.4 万条数据为无标签数据,各类别按照时间顺序采集,分布并不均衡。粗略估计,公司点评的数量最多,而行业深度的数量最少,二者比例约为 4:1(由于这部分数据无标签,只能做粗略估计);

2、在测试集中,各类别数据基本均衡。

4.2 实验方案

4.2.1 分类模型

在实验中,我们在 UDA 的框架基础上,分别采用了 BERT_base 和 TextCNN 作为分类模型。采用 TextCNN 有两方面的原因:

第一,作为对照实验,验证 UDA 框架是否对于轻量级模型也具有价值;

第二,考虑到实际线上部署的需求,我们更倾向于采用 TextCNN 类似较为轻量的模型;

对于 BERT_base,采用了与 google 原始论文相同的网络结构,仅仅将二分类调整为六分类。同时,我们将 BERT 在 1000 多万条金融领域的研报及公告上进行了二次预训练,以使得 BERT 能够在金融领域相关的任务表现更好。

对于 TextCNN,其 embedding 层在各门户网站的新闻语料、各机构发布的研报、百度百科等文本构成的数亿规模的语料进行了预训练。卷积核的窗口大小和数目为实验中优化参数。

4.2.2 主要目标

如前所述,我们将 UDA 技术运用到实际项目中包括两方面的目标:

核心目标:希望将无标签数据的价值充分发挥出来,即:通过 UDA 的框架,利用无标签数据让现有模型在原本的性能基础上能够进一步提升。

研究目标:通过在真实场景中的实验设计,来进一步了解 UDA 框架的特性,为后续应用提供基础。这些实验包括:

  1、不同数据增强方案对于半监督学习效果的影响;

  2、在不同有标签数据量下的提升效果;

  3、在轻量级模型下的效果;

  4、与其他早期半监督学习算法的效果对比,如 self-traning 方法;

4.3 主要实验结果及分析

4.3.1 有标签数据的数据量对于模型的影响

上表所示为不同有标签数据量下,是否采用 UDA 框架对于模型准确率的影响。从表中至少可以得到以下三方面的重要结论:

1、UDA 可以帮助模型有效利用无标签数据的信息,从而帮助现有模型在原本的性能基础上能够进一步提升。从表中可以看出,有标签数据量为 600 时,如果采用 UDA 框架,可以使得模型具有与有标签数据扩大一倍(即 1200 条)时的模型相当的表现。这相当于免费地获得了近一倍的额外标签数据。

2、随着有标签数据的增加,UDA 框架带来的额外提升效果会逐渐降低。在 60 条有标签数据时,可以使得模型提升近 30%;而在全数据下,只能帮助模型提升 1%。

3、UDA 的表现并没有想象中的好,增加有标签数据量仍然是最直接最稳定提升模型的方法。在 UDA 原始论文中,google 团队仅用 20 条有标签数据,就让模型达到了与 SOTA 接近的性能。但从我们的实验中可以看出,当有标签数据较少时(如 60 条),模型相对于最好结果仍然具有较大的差距。

整体而言,UDA 算法确实是一种有效利用无标签数据的半监督学习技术,但还不无法在少量标签下真正让模型达到最佳表现。

4.3.2 对比不同的增强方案

随着这两年半监督技术和自监督技术的发展,大家已经意识到,数据增强技术除了用于解决少样本场景下的样本稀缺的问题,也同样在半监督技术和自监督技术中扮演中重要作用。很多研究已经证明了,数据增强技术的优劣很多时候决定了最终半监督技术的最终效果。

我们团队之前也系统地梳理过近几年半监督技术的发展情况,感兴趣的朋友可以查看:

给你的数据加上杠杆:文本增强技术的研究进展及应用实践 - 知乎

在这一部分,我们研究 UDA 框架在几类典型的文本增强技术下的表现,包括 EDA、回译和基于TF-IDF的非核心词替换,关于这三类方法的具体实现细节可参考我们之前梳理的那篇文章。

值得注意的是,回译和非核心词替换技术正是 UDA 原始论文中所用到的数据增强方式。

从表中可知,数据增强技术在此任务中的效果由高到低依次为 EDA、回译 和 非核心词替换。EDA 相对于 非核心词替换高出了一个多百分点,同时考虑到不采用 UDA 框架的 baseline (见 4.3.1 节中的表格)模型准确率也在 0.86 左右,这充分说明了数据增强技术的选择对于半监督学习的效果有重要影响。

这背后的原因或许是相对于非核心词替换,EDA 技术可以给文本带来更为丰富的形式变换,毕竟里面包含了五类不同的操作。而更丰富、更多变的文本变换,可以更好地告诉模型什么是语义不变性。

从研究角度而言,探索更有效的数据增强技术将是半监督技术发展的重要方向之一。

4.3.3 CNN 与 BERT 的对比实验

上表展示了当有标签数据量不同时,在 UDA 框架下采用重量级的预训练模型 BERT_base 和轻量级的 TextCNN 模型的准确率比较。从表中至少可以得出两方面的结论:

1、UDA 框架对于轻量级模型同样具有很好的效果。对比第三行和第四行的结果,UDA CNN 仅比 UDA BERT 低了一到两个百分点,这充分说明了 UDA 框架对于轻量级模型的有效性。同时,这一个百分点的准确率损失相对于预测效率的提高和机器资源的节省,在很多实际业务中是非常值得的。

2、在少标签数据下,UDA 带来的提升远大于预训练模型带来的提升。对比第二行和第四行的结果,UDA CNN 相比于直接采用 BERT 的情况,其准确率高了近 20 个百分点。这或许是由于 BERT 虽然在海量语料上进行了预训练,但学习到的大部分特征与当前的任务无关。而通过 UDA 从相应的无标签数据中获取信息则是可以直接为当前的监督任务作出贡献。

至此,对于 UDA 在真实场景中的效果以及特性,我们基本有了直观的了解,本文的主要内容也到此结果。由于篇幅所限,其他相关的实验,例如与其他半监督方法的对比、领域外数据的影响等,此处不再展开,后面有机会再做分享。

5 总结

本文针对 Google 提出的半监督学习框架 UDA 进行了详细地梳理和讨论,补充了原始论文没有披露或未考虑到的实验,如领域外数据的影响、错误标签的影响等。同时,我们将该技术应用到熵简科技的实际业务中,并以金融文本分类问题作为案例,分析了 UDA 框架在真实场景中的实际收益和存在问题。

最后,再简单做一下总结和讨论:

第一,无论是对于重量级的预训练模型还是轻量级的模型,UDA 框架都能够帮助模型从无标签数据中挖掘出学习信号,从而帮助模型在原有基础上进一步提升表现。尤其在标记数据稀缺的场景下,这一提升往往比较明显;

第二,当前的半监督技术在真实问题中还无法真正达到我们想象中的少标签学习的目标,需要和预训练模型、迁移学习等技术结合起来,协同解决低资源场景下的问题;

第三,数据增强技术对于半监督学习的效果具有重要的影响,我们认为这也是半监督的重要研究方向之一,值得深入探索。

参考文献

[1] Xie, Qizhe, et al. "Unsupervised data augmentation for consistency training." (2019).

[2] Oliver, Avital, et al. "Realistic evaluation of deep semi-supervised learning algorithms." Advances in Neural Information Processing Systems. 2018.

[3] Zhu, Xiaojin, and Andrew B. Goldberg. "Introduction to semi-supervised learning." Synthesis lectures on artificial intelligence and machine learning 3.1 (2009): 1-130.

[4] Kim, Yoon. "Convolutional neural networks for sentence classification." arXiv preprint arXiv:1408.5882 (2014).

[5] Devlin, Jacob, et al. "Bert: Pre-training of deep bidirectional transformers for language understanding." arXiv preprint arXiv:1810.04805 (2018).

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342