《统计学习方法》第 4 章“朴素贝叶斯法”学习笔记

“朴素贝叶斯”算法主要内容

概率有向图模型

朴素贝叶斯也是最简单的概率有向图模型。

朴素贝叶斯模型的图模型表示

生成模型与判别模型

朴素贝叶斯方法实际上学习到的是生成数据的机制。

1、关于生成模型和判别模型,我一开始也很迷糊,后来我发现只要记住一点:生成模型首先是概率模型,要计算后验概率,但不是直接计算后验概率,得先通过计算联合概率,然后比较联合概率的大小,间接比较(得到)后验概率的大小。

2、判别模型则直接对条件概率建模,有点判别模型不是概率模型,直接给出分类的方法。

3、典型是判别模型,同样概率模型的有:逻辑回归模型、决策树模型,它们压根没有联合概率什么事,直接计算 P(Y|X) 的。

关于判别模型和生成模型,可以参考李航《统计学习方法》第 12 章统计学习方法总结。

频率学派和贝叶斯学派

频率学派:认为概率是一个常数,是固定值,虽然未知但是是客观的,频率学派重点研究样本的分布。
贝叶斯学派:认为概率是人的主观概念,代表了对事件发生的相信程度,贝叶斯学派重点研究参数的分布。

期望风险最小化

李航《统计学习方法》第 4 章介绍“朴素贝叶斯法”有一节的标题是“后验概率最大化的含义”。这一节指出了:

“后验概率最大化”等价于“期望风险最小化”。

下面我解释一下这一节要表达的意思。“朴素贝叶斯算法”的执行过程是“后验概率最大化”,而机器学习的一般套路是“期望风险最小化”,这一部分揭示了二者的等价性,即“后验概率最大化”就相当于“期望风险最小化”,即“朴素贝叶斯算法”是有效的。

解释“期望风险最小化”

1、风险,可以理解为损失,这里损失函数定义为 0-1 损失函数,即:分对的时候不计损失(记为 0),分错的时候,才计算损失(记为 1)。

2、那么如何计算损失呢?可以针对所有训练数据计算损失,最后再除以训练样本总数,这是很自然的。为了理论的推导,我们假设在大量数据的情况下,使用大数定理,等价于对联合概率分布 P(X,Y) 计算期望。

期望可以理解为加权平均,跟上面的所有数据的损失加起来,除以训练数据是一样的。

3、机器学习的一般流程是这样的:定义损失函数,找一个决策函数或者条件概率分布使得损失函数最小的那个决策函数或者条件概率分布就是最好的模型。

如果分对的那个概率特别大,分错的概率之和就会最小。这是李航《统计学习方法》P49 那一连串等式要表达的意思。因此“后验概率最大化”等价于“期望风险最小化”。写出来就是比较文绉绉的。

“后验概率最大化”等价于“期望风险最小化”

手写笔记:

image-20190222095742269
image-20190219164217365

理解这部分的叙述可以看这篇文章 《朴素贝叶斯 后验概率最大化的含义》

是一种分类方法

朴素贝叶斯(Naive Bayes)是一种基于概率统计的分类方法。预测的是条件概率,进而用于分类。由条件概率表示的模型为概率模型。

把随机变量 X 看成已知数据,Y 是已知数据 X 的类标,要求的是条件概率 P(Y|X),可以利用贝叶斯公式计算。

贝叶斯公式

在本科《概率论与数理统计》的教材上,你会看到下面的公式:

P(B_i|A) = \frac{P(B_i)P(A|B_i)}{\sum_{j=1}^{n}P(B_j)P(A|B_j)}
但其实,你要你懂得条件概率与联合概率,用分步乘法原理就能够自己推出贝叶斯公式,上面右边式子中,分母是全概率公式。

从贝叶斯公式中得出先验概率(两个先验概率,其中一个是标准化常量,因为它作为分母)、后验概率、条件概率、似然的定义。

随机变量 XY 同时发生的概率 P(X,Y) 可以写成:

P(X,Y) = P(X)P(Y|X)

也可以写成:

P(X,Y) = P(Y)P(X|Y)

把它们合在一起:
P(X)P(Y|X)= P(Y)P(X|Y)

于是就有:
P(Y|X) = \cfrac{P(Y)P(X|Y)}{P(X)}

这就是朴素贝叶斯公式,我们利用这个公式计算条件概率(后验概率)。这个公式告诉我们:计算条件概率的时候,已知和结果可以反过来。P(Y|X) 是一个条件概率,我们称之为后验概率,即知道了一些信息以后认为其属于某一类的概率,后验概率是我们要学习的。

理解贝叶斯公式

P(Y|X) = \cfrac{P(Y)P(X|Y)}{P(X)}

1、X 是输入,一般而言是一个向量,这个向量的每个分量表示一个特征;

2、公式右边的分母 P(X)Y 无关,可以认为是后验概率的归一化因子,这部分对于所有的数据都是一样的,所以我们可以不用计算它;

3、Y 是输出,是一个类别变量(标量),P(Y) 是先验概率,即不知道任何信息的时候,我们对于一个类别变量的概率的估计,如果不是很能理解“先验概率”这个定义,可以参考本科《概率论与数理统计》教材相关章节,即相对于知道了某些信息的后验概率 P(Y|X) ,什么都不知道的时候 P(Y) 就是先验概率;

4、P(X|Y) 是条件概率,是在类别确定的时候,出现特征 X 的概率,特征的条件独立假设就应用在这里。

特征的条件独立假设

1、我们首先来看为什么会提出“特征的条件独立假设”。

假设一个数据有 3 个特征,概率 P(x_1,x_2,x_3|y) 是很难估计的,因为要在训练数据里找到同时满足 3 个特征的数据的个数是很少的,当特征越来越多的时候,尤其是这样。而且即使估计出来了,在新数据也未必就能在训练样本中找到 P(x_1,x_2,x_3|y),把它定义为 0 就更不合适了。但是分别估计 P(x_1|y)P(x_2|y)P(x_3|y) 就比较容易。

2、一般情况下,一个数据的各个特征是有关系的,例如一个人的身高和体重,但是朴素贝叶斯假设它们是独立的,虽然有悖于我们的认知,但是基于这个假设,在很多问题上都能有很好的效果。

假设一个数据 X3 个特征,即 X = (x_1,x_2,x_3)^T,那么在类别 y 确定的条件下,数据 X 的各个特征相互独立,用公式写出来就是:
P(X|y) = P(x_1,x_2,x_3|y) = P(x_1|y) P(x_2|y) P(x_3|y)

如果你使用贝叶斯定理去做一次垃圾短信分类或者垃圾邮件分类的任务,你就会发现 P(x_1,x_2,x_3|y) 不好算,因为要判断 3 个特征是否同时出现在一个数据里,甚至 P(x_1,x_2,x_3|y) 这个值是很小的,引入条件独立性假设是为了方便计算,因为单独的特征的条件概率 P(x_1|y)P(x_2|y)P(x_3|y) 好算,只用计数就可以了。

如何用于分类

朴素贝叶斯用于分类就是从训练数据集中,先统计出类别的先验分布 P(Y) 和 条件概率分布 P(X|Y) ,然后就可以统计出联合概率分布 P(X,Y)=P(Y)P(X|Y)因为分母一样大,仅仅计算出贝叶斯公式分子的部分,然后比较分子的大小就可以了,联合概率大的,后验概率肯定也大。后验概率最大的类作为 x 的输出(即每一个类别的概率都要算一遍,然后取概率最大的):
P(Y=c_k|X=x),
所以,朴素贝叶斯分类器可以表示为:
y = f(x) = \arg \max_{c_k} \frac{P(Y=c_k)\prod_{j}P(X^{(j)}=x^{(j)}|Y=c_k)}{\sum_k P(Y=c_k)\prod_{j}P(X^{(j)}=x^{(j)}|Y=c_k)}

选择后验概率最大的类作为 x 的输出,即每一个类别的概率都要算一遍,然后取概率最大的类作为输出:

y = f(x) = \arg \max_{c_k} P(Y=c_k)\prod_{j}P(X^{(j)}=x^{(j)}|Y=c_k)
概率估计的方法可以是极大似然估计(其实就是数数字)或者贝叶斯估计(在数数字的基础上加上了拉普拉斯平滑)。

其实到这里,朴素贝叶斯的基本内容就介绍完了,不过朴素贝叶斯不论是从理论还是在实践中,都还能有很多扩展。

极大似然估计

做概率估计的方法是极大似然估计(其实就是数数字)和贝叶斯估计(在数数字的基础上加上了拉普拉斯平滑)。

理论上在做朴素贝叶斯的时候,先验概率和条件概率就是简单的数数字就可以完成了,这里用样本概率估计总体概率的方法叫做极大似然估计(即我们通过样本得到的概率值,就作为我们先验概率和条件概率的估计值)

“贝叶斯估计”即比起原来的数数字的方法而言,分子都加上 1,分母都加上的是这个类别的个数。

实际应用朴素贝叶斯会遇到的问题

具体在工程中,会遇到两个问题:

问题1:计算概率的乘积会使得很多小数连乘,最后得到的数值越来越小。

这是工程上遇到的问题,计算机中很多小数相乘会越来越小,以致于最后的结果不准确。解决方案是:我们通常对概率取对数(以 e 为底,其实只要是大于 1 的数作为底数都是可以的),取对数的好处是:

1、对最终结果没有影响,原来大的数,取对数以后仍然大;

2、取对数以后,连乘变连加。

问题2:有的特征的取值,在某些特定的类别上并不出现,即会出现了概率为 0 的情况。

如果出现了概率为 0 的情况,就要使用贝叶斯估计了:常常取一个 \lambda=1 ,在分子分母同时做加法,使得分子分母都不为 0。这个做法叫拉普拉斯修正(Laplacian correction)。

例如:在“非垃圾邮件中”,不会出现单词“国务院”。这时就要使用贝叶斯估计了:我们常常取 \lambda=1 ,在分子分母同时做加法,使得分子分母都不为 0,并且满足加和为 1。这一步也叫拉普拉斯修正(Laplacian correction)。
1、先验概率的贝叶斯估计
P_{\lambda} (Y=c_k) = \frac{\sum_{i=1}^{N}I(y_i=c_k)+\lambda}{N+K\lambda}

数数字,用样本概率估计总体概率的方法叫做极大似然估计,即我们通过样本得到的频率作为概率的估计,下面的“条件概率的贝叶斯估计”也是如此。

2、条件概率的贝叶斯估计
P_{\lambda} (X^{(j)}=a_{jl}|Y=c_k) = \frac{\sum_{i=1}^{N}I(x_i^{(j)}=a_{jl},y_i=c_k)+\lambda}{\sum_{i=1}^{N} I(y_i=c_k)+S_j\lambda}

S_j 表示第 j 个特征 unique 以后得到的数,即第 j 个特征的不同取值的个数。满足非负性和归一性,因此是概率分布。二者的形式非常像。比起原来的数数字的方法而言,分子都加上 1,分母都加上的是这个类别的个数(去掉了重复),可以看看《统计学习方法》 P52 例 2,一下子就看懂了。因为分母对所有的 c_k 都是相同的,所以,只看分子就好了。

伯努利贝叶斯、高斯朴素贝叶斯、多项式朴素贝叶斯

在 scikit-learn 中,一共有 3 个朴素贝叶斯的分类算法类。分别是 GaussianNBMultinomialNBBernoulliNB

1、 GaussianNB 就是先验为高斯分布的朴素贝叶斯;

高斯朴素贝叶斯(Gaussian naive Bayes):假设每个标签的数据都服从简单的高斯分布。

数值型特征的处理:假设这个连续性特征呈现出高斯分布,先计算均值和标准差,然后代入公式计算得到条件概率,作为这个类别前提下特征的条件概率的估计值。

下面是一个例子,使用高斯贝叶斯对鸢尾花数据进行分类。

<iframe src="https://nbviewer.jupyter.org/github/liweiwei1419/Machine-Learning-is-Fun/blob/master/Naive-Bayes-learning/notebook/%E4%BD%BF%E7%94%A8%E9%AB%98%E6%96%AF%E6%9C%B4%E7%B4%A0%E8%B4%9D%E5%8F%B6%E6%96%AF%E7%AE%97%E6%B3%95%E5%AF%B9%E9%B8%A2%E5%B0%BE%E8%8A%B1%E6%95%B0%E6%8D%AE%E9%9B%86%E8%BF%9B%E8%A1%8C%E5%88%86%E7%B1%BB.ipynb" width="800" height="700"></iframe>

2、MultinomialNB 就是先验为多项式分布的朴素贝叶斯;

多项式分布是指满足类别分布的实验,连续做 n 次以后,每种类别出现的特定次数组合的概率分布情况。

多项式朴素贝叶斯(Multinomial naive Bayes):假设特征是由一个简单的多项式分布生成的。在词频统计这件事情上,使用多项式分布作为概率估计是合理的。

scikit-learn 官方文档多项式贝叶斯部分:
http://scikit-learn.org/stable/modules/generated/sklearn.naive_bayes.MultinomialNB.html

说明:我开始学习时候,不明白多项式分布是如何作用在朴素贝叶斯算法上的,后来看了 scikit-learn 的文档以后才明白,原来公式和李航书上介绍的是一样的。并且文档指出了:多项式朴素贝叶斯分类器适用于具有离散特征的分类(例如用于文本分类的字数)。多项分布通常需要整数特征计数。然而在实践中,诸如 TF-IDF 的分数计数也可以起作用。

参数 alpha 表示平滑参数,其值越小,越容易过拟合,值太大容易造成欠拟合。

3、 BernoulliNB 就是先验为伯努利分布的朴素贝叶斯。

TF(Term Frequency)

用于衡量一个词在一个文档中的出现频率。因为每个文档的长度的差别可以很大,因而一个词在某个文档中出现的次数可能远远大于另一个文档,所以词频通常就是一个词出现的次数除以文档的总长度,相当于是做了一次归一化。
TF(term) = \cfrac{词 \; term \; 在文档中出现的总次数}{这一篇文档的 \; term \; 总数}

IDF(逆向文档频率)

用于衡量一个词(term)的重要性。计算词频 TF 的时候,所有的词语都被当做一样重要的,但是某些词,比如 is、 of、 that 很可能在很多文档中都出现过,它们不是关键字,因此我们需要减轻在多个文档中都频繁出现的词的权重。

IDF(term) = \log \cfrac{总文档数}{词 \; term \; 出现的文档数}

上面两个乘起来,就是 TF-IDF

TF-IDF = TF \times IDF

TfidfVectorizerCountVectorizerTfidfTransformer 合并起来,直接生成 tfidf 值。

TfidfVectorizer 的关键参数:

max_df 这个给定特征可以应用在 tf-idf 矩阵中,用以描述单词在文档中的最高出现率。假设一个词(term)在 80\% 的文档中都出现过了,那它也许(在剧情简介的语境里)只携带非常少信息。
min_df 可以是一个整数(例如 5 ),意味着单词必须在 5 个以上的文档中出现才会被纳入考虑。可以设置为 0.2;即单词至少在 20\% 的文档中出现 。
ngram_range 这个参数将用来观察一元模型(unigrams),二元模型( bigrams) 和三元模型(trigrams)。参考 n 元模型 (n-grams)。

get_feature_names() :可看到所有文本的关键字。
vocabulary_:可看到所有文本的关键字和其位置。
toarray():可看到词频矩阵的结果。

使用 gensim 的 corpora 和 models 也可以实现类似的功能。

朴素贝叶斯算法优点

1、对大数量训练和查询时具有较高的速度。即使使用超大规模的训练集,针对每个项目通常也只会有相对较少的特征数,并且对项目的训练和分类也仅仅是特征概率的数学运算而已。分类效果稳健,特别适合于大规模的数据集;

2、支持增量式运算。即可以实时的对新增的样本进行训练;

3、朴素贝叶斯对结果解释容易理解;

4、天然地支持多分类任务;

5、和逻辑回归一样,它天生支持计算样本属于某个标签的概率;

6、对缺失的数据和噪声数据都不敏感;

7、训练和预测的速度非常快;

8、可调参数(如果有的话)非常少;

9、我们的假设与数据是匹配的,因为我们在应用朴素贝叶斯的时候,其实是用了比较强的假设的;

10、高维数据,在高维的空间中,数据分得比较开,所以朴素贝叶斯这个简单的模型有可能运作得比价好。

朴素贝叶斯算法缺点

1、朴素贝叶斯分类器对数据有严格的假设,因此它的训练效果通常比复杂的模型差;

2、由于使用了样本属性独立性的假设,所以如果样本属性有关联时其效果不好。特征之间的相互独立的假设在实际应用中往往是不成立的,在特征个数比较多或者特征之间相关性较大的时候,分类效果一般;

3、需要知道先验概率,而先验概率很多时候取决于假设,假设的模型可以有很多种,因此在某些时候会由于假设的先验模型的原因导致预测效果不佳;

4、对输入数据的表达形式很敏感,应用在含有大量的数值特征的数据集的时候并不理想。

朴素贝叶斯算法的应用场景

本文分类、文本情感预测。

1、欺诈检测中使用较多;

2、一封电子邮件是否是垃圾邮件;

3、一篇文章应该分到科技、政治,还是体育类;

4、一段文字表达的是积极的情绪还是消极的情绪。

案例

案例1:使用朴素贝叶斯对 20 类新闻数据进行类别预测

说明:这里使用 CountVectorizer 对文本数据向量化。使用多项式贝叶斯训练。

这里使用的是多项式贝叶斯。

<iframe src="https://nbviewer.jupyter.org/github/liweiwei1419/Machine-Learning-is-Fun/blob/master/Naive-Bayes-learning/notebook/%E4%BD%BF%E7%94%A8%E6%9C%B4%E7%B4%A0%E8%B4%9D%E5%8F%B6%E6%96%AF%E5%AF%B9%2020%20%E7%B1%BB%E6%96%B0%E9%97%BB%E6%95%B0%E6%8D%AE%E8%BF%9B%E8%A1%8C%E7%B1%BB%E5%88%AB%E9%A2%84%E6%B5%8B.ipynb" width="800" height="1000"></iframe>

案例2:利用朴素贝叶斯对名字进行性别预测

<iframe src="https://nbviewer.jupyter.org/github/liweiwei1419/Machine-Learning-is-Fun/blob/master/Naive-Bayes-learning/notebook/%E5%88%A9%E7%94%A8%E6%9C%B4%E7%B4%A0%E8%B4%9D%E5%8F%B6%E6%96%AF%E5%AF%B9%E5%90%8D%E5%AD%97%E8%BF%9B%E8%A1%8C%E6%80%A7%E5%88%AB%E9%A2%84%E6%B5%8B/%E5%88%A9%E7%94%A8%E6%9C%B4%E7%B4%A0%E8%B4%9D%E5%8F%B6%E6%96%AF%E5%AF%B9%E5%90%8D%E5%AD%97%E8%BF%9B%E8%A1%8C%E6%80%A7%E5%88%AB%E9%A2%84%E6%B5%8B.ipynb" width="800" height="1000"></iframe>

参考资料

[1] 李航. 统计学习方法(第 2 版)第 4 章“朴素贝叶斯法”. 北京:清华大学出版社,2019.

说明:这本书上给出了很好的例子,关键词:特征条件独立假设、贝叶斯估计、拉普拉斯平滑。

[2] 周志华. 机器学习(第 7 章第 3 节“朴素贝叶斯分类器”). 北京:清华大学出版社.

[3] scikit-learn 官方文档. https://scikit-learn.org/stable/modules/naive_bayes.html.

(本节完)


以下为草稿,我自己留着备用,读者可以忽略,欢迎大家批评指正。

参考资料

1、刘建平:

(1)朴素贝叶斯算法原理小结
地址: https://www.cnblogs.com/pinard/p/6069267.html
(2)scikit-learn 朴素贝叶斯类库使用小结
地址:https://www.cnblogs.com/pinard/p/6074222.html

2、wepon_ 的文章:朴素贝叶斯理论推导与三种常见模型
地址:http://wepon.me/2015/09/09/naive-bayes/

3、黄永昌:零基础学习朴素贝叶斯算法
地址:http://blog.kamidox.com/naive-bayes.html

4、参考资料:使用sklearn提取文本的tfidf特征

https://www.jianshu.com/p/c7e2771eccaa

5、贝叶斯估计和极大似然估计到底有何区别
https://blog.csdn.net/feilong_csdn/article/details/61633180

6、朴素贝叶斯分类器详解及中文文本舆情分析(附代码实践)
https://mp.weixin.qq.com/s/Pi30jA1xUbXg3dSdlvdU-g

7、深入理解朴素贝叶斯(Naive Bayes)
https://blog.csdn.net/li8zi8fa/article/details/76176597

8、张洋:算法杂货铺——分类算法之朴素贝叶斯分类(Naive Bayesian classification)
http://www.cnblogs.com/leoo2sk/archive/2010/09/17/1829190.html

9、扩展阅读:半朴素贝叶斯分类器

10、CountVectorizer, TfidfVectorizer, Predict Comments

https://www.kaggle.com/adamschroeder/countvectorizer-tfidfvectorizer-predict-comments

11、https://blog.csdn.net/ixuhangyi/article/details/51820328

12、sklearn: TfidfVectorizer 中文处理及一些使用参数

https://blog.csdn.net/blmoistawinde/article/details/80816179

13、NLP面试-最大似然估计与贝叶斯估计的区别
https://www.jianshu.com/p/ead99acd6437

14、贝叶斯估计详解
https://blog.csdn.net/zengxiantao1994/article/details/72889732

15、带你彻彻底底搞懂朴素贝叶斯公式
https://blog.csdn.net/fisherming/article/details/79509025

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