从评论中构建可解释的意见图

论文标题:Constructing Explainable Opinion Graphs from Reviews
论文链接:https://arxiv.org/abs/2006.00119
论文来源:WWW 2021

一、概述

网络上存在一些事实的和主观的信息,近几年,在提取“主-谓-宾”三元组和构建这些事实的知识库方面有了重大进展。相比之下,组织意见(opinion)知识库的研究非常少,而意见中包含大量的主观信息,如评论(review)和推文(tweet)等。研究表明,意见对于用户来说是重要的,绝大多数用户会根据评论来决定购买等行为,因此一个问题应运而生:是否有一种系统的方法将意见组织到知识库中,使客户更容易理解主观数据中的意见?

现有的一些意见挖掘(opinion mining)的方法主要关注于提高意见抽取的准确性,以及在一组预定义的方面(aspect)之上对抽取的意见进行基于方面的情感分析,然而这些方法:
①不能决定意见之间的关系,举例来说,当有一个提取的意见为“very good location”,这些方法不能解释为什么“location”是“very good”的;
②简单地收集所有提取的意见会导致大量冗余,也可能导致错误的结论,举例来说,对于以下意见 {“quiet room”, “very noisy street”, “loud neighborhood”, “horrible city noise”, “quiet room”},如果意见没有按照相似度进行组织,人们可能会错误地认为“quiet room”是最受欢迎的意见。

基于以上现状,本文致力于解决以下问题:我们能否超越意见挖掘,将意见及其之间的关系统一表示到知识库中?为了理解如何最好地将意见组织成知识库,本文通过一系列注释任务分析了评论中主观信息的属性,并证实了以下几点:
①意见用短语表示,换句话说,意见是简短的,按照(opinion term, aspect term)这种形式表示,比如(“very good”,“location”),大多数意见以这种形式存在;
②解释(explanation)或推理(inference)是评论中相互关联的观点之间最常见的关系;
③许多意见和意见之间的关系是围绕特定实体的,而不是跨多个实体的,举例来说评论“Our room was very noisy as it is close to the main street”中意见“close to main street”解释意见“very noisy room”,这些意见是围绕评论讨论的这个特定的旅馆而非任意的旅馆。

在此基础上,我们提出了一种组织意见的图表示,称为意见图(Opinion Graph),它根据特定实体的评论,围绕解释关系组织意见。图的节点是一个以(opinion term, aspect term)这种形式存在的意见,并且由所有根据语义相似度与节点相近的意见组成。两个节点uv之间的边(u,v)代表u解释v。我们发现这是一个组织评论意见的通用结构,这是因为:
①意见图是大量评论中意见的简洁和结构化表示;
②节点可以聚合并以不同的粒度表示意见;
③边根据评论中出现的意见来解释其他意见;
④节点中意见的来源可以追溯到提取意见的评论;
⑤意见图是一个有用的抽象,它支持一系列下游应用程序,从生成可解释的评论摘要到促进对意见短语或标准的搜索。

一个意见图的例子如下:

意见图

本文提出的构建意见图的方法为EXPLAINIT,主要包括以下4个步骤:
①挖掘意见短语;
②决定意见短语之间的解释关系;
③标准化语义相似的意见短语到一个意见簇中(聚类);
④从前面得出的的解释关系和意见簇为实体生成意见图。

注意这里是给每个特定的实体生成一个意见图,也就是说如果有多个旅馆,那么就要根据对每个旅馆的所有评论生成每个旅馆的意见图,这是由于前面所说的意见只针对特定的实体。

二、概念

一个意见短语用p=(o,a)o是opinion term,ao相关的aspect term。举例来说,上图评论“Cons: extremely noisy room with paper thin walls”,包含两个意见p_1=(“extremely\; noisy”, “room”)p_2=(“paper\; thin”, “walls”)。一个解释e=(p_i,p_j)是两个意见短语之间的关系,代表p_i解释p_j,举例来说(“paper\; thin\; walls”\rightarrow “extremely\; noisy\; room”)(“close\; to\; attractions”\rightarrow “great\; location”)是两个合理的解释。

一个意见短语集合S对应的意见图为G=(N,E),满足:
①每个意见短语p\in S都属于一个节点n\in N
②每个节点n\in N由语义一致的意见短语组成;
③一条边(n_{i}\rightarrow n_{j})\in E代表n_{i}n_{j}的解释关系,意味着n_{i}的成员短语解释n_{j}的成员短语。

在一个意见图中,一个“完美的”节点将包含释义(paraphrase),这意味着两个完美节点所包含的意见短语之间两两相互解释,也就是说当且仅当(p_{i}\rightarrow p_{j})\; \forall p_{i}\in n_{i},p_{j}\in n_{j},这两个节点直接才会存在边(e_{i}\rightarrow e_{j})。然而在实际情况下,并不可能从评论中挖掘到两个节点之间短语的所有两两之间的解释,换句话说就是我们大多数时候要面对的是“不完美的”的节点,这些节点包含语义相似的短语,当两个节点之间很可能存在解释关系时,我们在两个节点之间添加一条边(当两个意见的观点之间存在大量的解释关系时)。

很难用单一的端到端模型生成一个意见图,因为需要挖掘意见短语及其关系,以及问题的规模,这通常涉及数千个评论。因此像大多数构建知识库的方法一样,我们将构建意见图的问题分解成几个子问题。

三、框架

构建意见图的过程分为下图中展示的4部分:

构建意见图的过程
  1. Opinion Mining

第一步需要从关于一个实体的评论集合中挖掘意见短语,我们利用Aspect-based Sentiment Analysis (ABSA)模型,在本文中使用这篇文章中的开源系统:Subjective Databases。这个系统同样预测每个意见短语的aspect类别和情感极性,我们利用这些额外的信号来改进意见短语标准化的过程。

  1. Explanation Mining

接着需要发现意见对之间的解释关系,我们使用众包来获取特定于某个domain的标准数据,并且开发了一个有监督的多任务分类器来发现两个意见短语之间的解释关系。

  1. Opinion Phrase Canonicalization

意见短语的规范化是指语义相似的意见短语被聚类在一起来组成意见图中的一个节点。这是必要的,因为评论在内容上有很大的重复,因此,包含许多相似的意见短语。为了规范化意见短语,我们开发了一个新的意见短语表示学习框架,该框架使用从前面步骤获得的弱监督来学习意见短语embedding,这些弱监督包括预测aspect类别、情感极性得分和解释关系。最后使用一个聚类算法来聚类学习到的意见短语embedding。

  1. Opinion Graph Generation

最后,我们提出了构建最终意见图的算法。该算法根据各节点意见短语之间的聚合解释关系来连接图节点以构建意见图。

四、 MINING EXPLANATIONS

  1. 概述

构建意见图的一个重要任务是确定一个意见短语何时能解释另一个。举例来说,“close to Muni bus stops”是“convenient location”的解释但不是“close to local attractions”的解释,“on a busy main thoroughfare”是“very noisy rooms”的解释但不是“convenient location”的解释。

从评论中挖掘意见短语的解释与两个任务相关:实体关系分类(entity relation classification)和识别文本蕴含(recognizing textual entailment,RTE)。

实体关系分类任务以文本序列和一个实体对作为输入,利用特定domain的训练数据学习对实体之间的关系进行分类。由于模型是由特定domain的任务训练和定制的,直接训练实体关系分类模型用于解释挖掘任务是不可行的。

识别文本蕴涵任务则考虑两个文本序列,通常称为前提和假设,并决定假设是否可以从前提推断出来。虽然它也考虑了两段文本之间的推理关系,但在通用文本上训练的RTE模型仍然不足以从评论中挖掘解释。这是由于两个原因:
①特定domain的知识对于理解意见关系的细微差别通常是必要的;
②在许多情况下,完整的评论对于判断可能的解释是至关重要的(如果RTE的两段输入文本是两个意见短语,那就相当于没有输入完整的评论)。

事实上在实验中直接应用从开放domain数据上训练的SOTA效果的RTE模型获得了很低的解释提取准确率(34.3%),后续实验又在评论domain上重新训练了实体关系分类和RTE模型,其效果仍然不及本文提出的方法。

  1. 数据

本文研究人员采用众包收集了旅馆和餐厅domain的实验数据集,包括对评论中的意见短语、意见短语相关性的标注(下图(a)),以及相关意见短语的关系的标注(下图(b))。下图展示了收集数据的方式:

收集数据
  1. Explanation Classifier

我们观察到意见短语周围的上下文和意见短语之间的逐词对齐(word-by-word alignment)对我们的解释挖掘任务非常有用。举例来说,“noisy room”和“right above Kearny St”可能看起来无关,由于一个关于房间是否安静,另一个是关于地理位置。然而,它们共现的评论上下文表明它们存在解释关系:“Our room was noisy. It is right above Kearny St.”。除了上下文,意见短语之间的逐字对齐也对解释挖掘非常有益。例如,两个短语““easy access to public transportation”和“convenient location”之间“easy access to”和“convenient”以及“public transportation”和“location”之间的逐词对齐使得更容易确定第一个短语解释后者。然而现有方法很少同时考虑这两种信息,实体关系分类模型关注上下文而RTE模型关注逐词对齐。

本文提出了一种多任务学习的模型叫做MaskedDualAttn,包括两个分类任务:
①评论分类:评论是否包含解释关系;
②解释分类:是否第一个意见短语解释第二个。

这种方法同时考虑上下文和逐词对齐两种信息。下图为MaskedDualAttn方法的架构图:

MaskedDualAttn

下图总结了本小节使用的符号:

符号
  • Input and Phrase Masks

分类器的输入包括一个评论r=(w_{1},\cdots ,w_{L}),其中包含L个词以及两个意见短语p_ip_j。对于每个意见短语p=(o,a),创建一个binary的maskm=(m_{1},\cdots ,m_{L}),这使得模型能够有选择的使用整个评论的部分编码:

m_{i}=\left\{\begin{matrix} 1,\; if\; w_{i}\in a\cup o\\ 0,\; otherwise. \end{matrix}\right.

p_ip_j的binary mask记作m_im_j

  • Encoding

首先使用一个embedding层来编码r的token,然后接一个BiLSTM层,BiLSTM层的输出记作H=[h_{1},\cdots ,h_{L}]\in \mathbb{R}^{k\times L}k是隐层维度。我们并不单独编码每个意见短语,而是使用m_im_j来对r的编码进行mask。注意这里的embedding层可以换成预训练语言模型,比如BERT,实验表明BERT能够进一步提升模型性能。

  • Self-attention

表达解释关系有一些通用的语言模式,比如“because”或者“due to”等,为了捕获这些语言模式,我们采用self-attention机制:

M=tanh(W^{H}H+b^{H})\; \; \; \; \; \; \; \; \; M\in \mathbb{R}^{k\times L}\\ \alpha =softmax(w^{T}M)\; \; \; \; \; \; \; \; \; \alpha \in \mathbb{R}^{L}\\ h_{r}^{*}=tanh(H\alpha ^{T})\; \; \; \; \; \; \; \; \; h_{r}^{*}\alpha \in \mathbb{R}^{k}

这里W^{H}\in \mathbb{R}^{k\times k},b^{H},w^{T}\in \mathbb{R}^{k}是训练参数。h_{r}^{*}是最终获得的句子表示。

  • Alignment attention

尽管自我注意机制具有处理语言模式的一般能力,但我们认为,要准确预测观点短语之间的解释关系是不够的。Alignment attention用来直接捕获意见短语的相似性。我们的alignment attention只关注意见短语的token。为了对齐p_ip_j,对于p_i的每个词w_{t}\in p_{i},我们都获得一个p_j的权重向量\alpha _{t}

d_{t}=U^{h}h_{t}+U^{r}r_{t-1}\; \; \; \; \; \; \; \; \; d_{t}\in \mathbb{R}^{k}\\ M_{t}=tanh(U^{H}H+\underset{L\; times}{\underbrace{[d_{t};\cdots ,d_{t}]}})\; \; \; \; \; \; \; \; \; M_{t}\in \mathbb{R}^{k\times L}\\ \alpha _{t}=softmax(u^{T}M_{t}-c\overline{m_{j}})\; \; \; \; \; \; \; \; \; \alpha _{t}\in \mathbb{R}^{L}\\ r_{t}=H\alpha _{t}+tanh(U^{t}r_{t-1})\; \; \; \; \; \; \; \; \; r_{t}\in \mathbb{R}^{k}

这里U^{H},U^{h},U^{r},U^{t}\in \mathbb{R}^{k\times k}以及u\in \mathbb{R}^{k}都是训练参数。\overline{m_{j}}p_j的反向mask。p_i的最终表示由p_i的最后一个隐状态h_{|p_{i}|}和最后一个输出向量r_{|p_{i}|}的非线性组合获得:

h_{i}^{*}=tanh(U^{x}r_{|p_{i}|}+U^{y}h_{|p_{i}|})\; \; \; \; \; \; \; \; \; h_{i}^{*}\in \mathbb{R}^{k}

这里U^{x},U^{y}\in \mathbb{R}^{k\times k}是训练参数。同样按照上述方式获得p_j的表示向量h_{j}^{*}

  • Prediction and Training

评论分类和解释分类的概率分布由两个softmax函数获得:

s_{r}=softmax(W^{r}h_{r}^{*}+b^{r})\; \; \; \; \; \; \; \; \; s_{r}\in \mathbb{R}^{2}\\ s_{e}=softmax(W^{e}h_{e}^{*}+b^{e})\; \; \; \; \; \; \; \; \; s_{e}\in \mathbb{R}^{2}

这里h_{e}^{*}[h_{r}^{*},h_{i}^{*},h_{j}^{*}]是句子和短语表示的拼接向量,W^{r},W^{e}\in \mathbb{R}^{2\times k},b^{r},b^{e}\in \mathbb{R}^{2}是训练参数。损失函数定义为:

J=J_{o}+\lambda J_{r}

J_{o}J_{r}是两个分类任务的交叉熵损失。

五、CANONICALIZING OPINION PHRASES

  1. 概述

这部分的目的是为了将重复或者相似的意见短语聚类以构建一个简洁的意见图。举例来说,“one block from beach”,“close to the pacific ocean”,“unbeatable beach access”,“very close to the sea”这些短语描述的都是同一个意见。

如果使用意见短语的平均word embedding来进行聚类,效果不会很好,这是因为某些短语共享同一个aspect term或者opinion term。举例来说,“very close to the ocean”与“very close to the trams”之间的相似度比与“2 mins walk to the beach”之间的相似度更高,更多的例子查看下图:

例子

为了使得意见短语的表示能够以语义相似度进行聚类,本文提出一种意见短语表示学习的方法来学习意见短语的表示。这种方法利用前面的步骤的结构来提供一种弱监督,包括意见挖掘阶段提供的短语的aspect类别和情感极性以及解释挖掘阶段得到的解释关系。最后使用现有的聚类方法来对意见短语的表示进行聚类。

  1. Opinion Phrase Representation Learning

本文提出的意见表示学习框架为Weakly-Supervised Opinion Phrase Embeddings (WS-OPE),有两个特性:
①意见词和aspect词分别使用不同的embedding,然后合并成意见短语embedding;
②使用弱监督来引入语义信息,包括前面步骤得到的短语的aspect类别和情感极性以及解释关系。

下图展示了WS-OPE的大体框架:

WS-OPE

下图总结了本小节使用的符号:

符号
  • Input

模型的输入是从关于某一个实体(比如一个旅馆)的评论中提取的N_p个意见短语P=\left \{p_{i}\right \}_{i=1}^{N},以及N_e个解释E_{e}=\left \{e_{i}\right \}_{i=1}^{N_{e}}。每个意见短语p=(o,a)包含两个序列(opinion term和aspect term),我们使用asppol来表示一个短语的aspect类别和情感极性标签,这些信息由意见挖掘阶段的ABSA模型提供。

  • Opinion Phrase Encoding

给定一个意见短语(o,a),首先我们使用一个embedding层和self-attention机制来计算一个aspect embeddingv_a和一个意见 embeddingv_o。aspect embeddingv_a的获得需要在所有aspect term的tokena=(w_{1},\cdots ,w_{n})上进行attention:

u_{i}=v_{w_{i}}^{T}W^{a}v_{a}^{'}\; \; \; \; \; \; \; \; \; u_{i}\in \mathbb{R}\\ c_{i}=\frac{exp(u_{i})}{\sum_{j=1}^{m}exp(u_{j})}\; \; \; \; \; \; \; \; \; c_{i}\in \mathbb{R}\\ v_{a}=\sum_{i=1}^{m}c_{i}v_{w_{i}}\; \; \; \; \; \; \; \; \; v_{a}\in \mathbb{R^{d}}

这里v_{w_{i}}\in \mathbb{R^{d}}是embedding层输出的w_i的word embedding,v_{a}^{'}\in \mathbb{R^{d}}a的平均word embedding,W^{a}\in \mathbb{R^{d\times d}}是训练参数。v_o也以同样的方式获得。然后拼接v_av_o得到意见短语embeddingv_p

v_{p}=[v_{a};v_{o}]\; \; \; \; \; \; \; \; \; v_{p}\in \mathbb{R^{2d}}

  • Reconstruction loss

auto-encoder的主要思想是在v_p上学习以使得其能够被矩阵R重构,我们设置RK行,即R\in \mathbb{R^{K\times 2d}},每一行代表聚类算法的一个聚类中心。为了重构v_p,首先使其通过一个softmax分类器:

s_{p}^{R}=softmax(W^{R}v_{p}+b^{R})\; \; \; \; \; \; \; \; \; s_{p}^{R}\in \mathbb{R^{K}}

这里W^{R}\in \mathbb{R^{K\times 2d}},b^{R}\in \mathbb{R^{K}}是训练参数。然后重构v_p以得到r_p

r_{p}=R^{T}s_{p}^{R}\; \; \; \; \; \; \; \; \; r_{p}\in \mathbb{R^{2d}}

我们使用triplet margin loss损失作为损失函数,这样可以使得v_pr_p更相近,同时使得与k_n个随机采样负样本更远:

J^{R}=\sum _{p\in P}\sum_{i=1}^{k_{n}}max(0,1-r_{p}v_{p}+r_{p}v_{n_{i}})

n_{i}\in P是随机采样负样本。采样过程试图按照s_{p}^{R}来采样与输入意见短语不相似的意见短语。对于一个其他意见短语p^{'},其被采样为p的负样本的概率与s_{p}^{R}s_{p^{'}}^{R}的余弦相似度成反比。

  • Aspect category and polarity loss

我们希望使用前面步骤得到的信息来学习更好的表示,举例来说,我们期望“friendly staff ”和“unfriendly staff”在embedding空间中不要太相近,因此我们整合aspect类别和情感极性信号来学习更好的意见短语embedding。在WS-OPE中添加两个分类任务来整合这些信息:

s_{p}^{asp}=softmax(W^{asp}v_{p}+b^{asp})\\ s_{p}^{pol}=softmax(W^{pol}v_{p}+b^{pol})

这两个分类任务的交叉熵损失记作J_{asp}J_{pol}

  • Intra-cluster explanation loss

如果两个解释p_ip_j有解释关系,那么它们不应该属于同一个簇,为了减少簇内解释关系,我们定义簇内解释loss,也就是概率分布s_{p_{i}}^{R}s_{p_{j}}^{R}的KL散度:

J_{E}=-\sum _{e\in E}KL(s_{p_{i}}^{R},s_{p_{j}}^{R}),\; e=(p_{i}\rightarrow p_{j})

E是挖掘的解释关系集合。

  • Training objective

WS-OPE的loss为:

J_{WS-OPE}=J_{R}+\lambda _{asp}J_{asp}+\lambda _{pol}J_{pol}+\lambda _{E}J_{E}

同时采用两种mini-batch方式。使用单个意见短语mini-batch来计算J_{R},J_{asp},J_{pol},使用解释mini-batch(意见短语对)来计算J_{E}

  1. Clustering Opinion Phrases

接着是对意见短语进行聚类以得到意见图的节点,并不限于任何聚类算法。我们不使用s_{p}^{R}来进行聚类,这是因为s_{p}^{R}只使用J_{R}进行更新,而意见短语embeddingv_p使用4种loss进行更新,因此使用v_p进行聚类。

六、GENERATING OPINION GRAPHS

直观的,如果一个意见短语解释另一个,那么释义(同一个簇)第一个的意见短语也应该能够解释释义第二个的意见短语,因此存在n_i的意见短语解释n_j的意见短语时,n_in_j之间就应该有一条边:

e=(n_{i}\rightarrow n_{j})\; is\; true,if\exists e=(p\rightarrow p^{'})\in E|p\in n_{i},p^{'}\in n_{j}

然而实际情况下,我们获得的解释关系和节点是不完美的,因此,如果使用前面的方法我们可能获得许多false positive的边。为了最小化false positive的边的数量,我们采用一种启发式的方法,主要思想是两组意见很少同时相互解释彼此:

e=(n_{i}\rightarrow n_{j})\; is\; true,if\sum _{e\in E_{ij}}p_{e}-\sum _{e^{'}\in E_{ji}}p_{e}^{'}>0

这里E_{ij}=\left \{e=(p_{i}\rightarrow p_{j})|p_{i}\in n_{i},p_{j}\in n_{j}\right \}E_{ji}=\left \{e=(p_{j}\rightarrow p_{i})|p_{i}\in n_{i},p_{j}\in n_{j}\right \}p_ep_{e}^{'}是由解释分类器得出的解释概率。

七、实验

  1. 解释挖掘

对比了包括实体关系分类和识别文本蕴含在内的多个baseline:

解释挖掘
  1. 意见短语标准化

对比了多种方法,并且实验表明本文的方法并不局限于何种聚类方法:

意见短语标准化
  1. 意见短语embedding的可视化

使用t-SNE可视化了平均word embedding和WS-OPE的意见短语embedding:

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

推荐阅读更多精彩内容