机器学习-第七章 贝叶斯分类器

7.1 贝叶斯决策论

1.相关概率

1)先验概率:在事情发生之前事情发生的概率。是根据以往经验和分析得到的概率。可以表示为样本空间中各类样本的占比。
如:抛硬币时正面朝上的概率是0.5,这就是一种先验概率。在抛硬币前,我们只有常识。这个时候事情还没发生,我们进行概率判断,对事情发生可能性进行数学的猜测。
2)后验概率:事情已经发生,发生原因很多,判断事情发生由哪个原因引起的概率
如:今天小明上班迟到,这件事情已经发生了,同事认为小明可能因为公交故障、睡晚或扶老奶奶过马路而迟到,分别推测迟到是由于这三个原因造成的概率。

由于交通故障而迟到的概率,其他原因也类似
公式如下:
P(A|B)表示在B发生的条件下A发生的概率。
其中,P(AB)称为联合概率。
3)条件概率
条件概率是指在某一件事发生的情况下,另一件事发生的概率。虽然与后验概率很相似,但是条件概率的两件事情不一定有因果关系。
如:小明迟到了,求小红迟到的概率。假设小明迟到为事件B,概率为P(B),小红迟到为事件A,概率为P(A),小红和小明都迟到的概率为P(AB)。则公式如下:
在事件B发生的情况下,事件A发生的概率

4)全概率:指某个事件A的发生可能由n种原因(B1,B2…Bn)造成,每一种原因发生的概率乘以该原因发生后该事件也发生的概率的累加和即为全概率。

全概率公式

5)贝叶斯公式

贝叶斯公式
事件Bi发生的概率为P(Bi),事件Bi已发生条件下事件A的概率为P(A│Bi),事件A发生条件下事件Bi的概率为P(Bi│A)。
我们也可以理解为Bi为原因,A是结果。P(Bi│A)就是已知结果找到原因,而公式最后的部分就是已知原因推出结果。

举例:已知在男人中有30%会脱发,女子中有5%会脱发,随机抽取一个脱发的人,这个人为男人的概率是多少?

由已知可设A表示抽到男人,B代表抽到女人,C表示脱发。

2.贝叶斯决策论

贝叶斯决策论是概率框架下实施决策的基本方法。对于分类任务,在所有相关概率都已知的情况下,贝叶斯决策论考虑如何基于这些概率和误判损失来选择最优的类别标记。
以多分类任务来解释其原理。
假设有N种类别标记Y={c1,c2,……,cN},λij是指将一个真实标记为cj的样本错误分类为ci所产生的损失。基于后验概率P(ci|x)可获得样本误分类为ci所产生的期望损失,或者说样本x上的"条件风险"

条件风险

  • 贝叶斯判定准则
    我们的目标是最小化总体风险。寻找一个方法h,对于每个样本x,使得条件风险最小化,这样就可以是总体风险最小化。为最小化总体风险,只需在每个样本上选择那个能使得条件风险R(c|x)最小化的类别标记c,即

    判定准则h使得每个样本条件风险最小
    这就是贝叶斯判定准则。h*称为贝叶斯最优分类器,与之对应,总风险R(h*)称为贝叶斯风险。1-R(h*)分类器所能达到的最好性能。

    当损失λij表示为:样本被错误分类时,λij=1;没有错误分类时,λij=0。
    R(c|x)表示样本被错误分类的概率,即错误分类率,P(c|x)是后验概率。
    可以看出,我们的目标是最小化错误分类率,则此时条件风险为

    条件风险

    那么,我们可以将最小化条件风险的目标转化为最大化后验概率,于是,贝叶斯最优分类器变为
    而对于P(c|x)有两种策略求得:
    ① 判别式模型:给定x,通过直接建模P(c|x)来预测c。如:决策树、BP神经网络、支持向量机。
    ② 生成式模型:先对联合概率分布P(x,c)建模,然后再由此得到P(x|c)。如:贝叶斯分类器。
    则通过一开始的相关概率中的几个概率可以知道,贝叶斯最优分类器可以变为
    其中
    P(x)与类标记c无关,因此在最后一步中从最大化目标中略去。

    P(c)为类先验概率,其表示样本空间中各类样本所占比例,根据大数定律,当训练集包含足够的样本时,P(c)可通过各类样本频数进行估计;

    P(x|c)为样本x关于类别c的类条件概率,或者称为"似然"。它涉及关于x所有属性的联合概率,如果直接用样本出现的频率来估计将会十分困难。因此对于类条件概率,我们使用极大似然估计来估计。

7.2 极大似然估计

极大似然估计在概率论中学过,可以复习一下,过程不难。
极大似然估计求解
极大似然估计PPT以及例题

极大似然估计源自于频率主义学派,他们认为参数虽然未知,但却是客观存在的规定值,因此,可以通过优化似然函数等准则确定参数数值。本节使用极大似然估计对条件概率进行估计。

令Dc表示训练集D中第c类样本组成的集合,假设这些样本是独立同分布的,则参数θcc是确定条件概率P(x|c)的唯一参数向量)对数据集Dc的似然为

似然估计
似然函数可以记为
似然函数

对θc进行极大似然估计,就是寻找能最大化似然P(Dcc)的参数值θ^c

由于似然函数连乘易造成问题,因此对上述的似然函数对数化,对数化似然函数之后如下

对数化之后的似然函数
因此求得θc的极大似然估计θ^c
使用极大似然估计方法估计参数虽然简单,但是其结果的准确性严重依赖于每个问题所假设的概率分布形式是否符合潜在的真实数据分布,不符合的话很可能产生误导性的结果。
求解极大似然估计的步骤

7.3 朴素贝叶斯分类器

从前面的讲解可知,使用贝叶斯公式来估计后验概率的困难是难以从现有的训练样本中准确的估计出条件概率P(x|c)的概率分布。朴素贝叶斯分类器为了避开这个障碍,朴素贝叶斯方法对条件概率分布作了条件独立性的假设。具体地,条件独立性假设是

有了条件概率的简化条件之后,贝叶斯准则改写为
这就是朴素贝叶斯分类器的表达式。

下面对先验概率P(c)条件概率P(xi|c)进行极大似然估计求得后验概率。

  • 对先验概率P(c)容易求出
    P(c)
  • 条件概率
    1)对离散属性而言,令Dc,xi表示Dc中在第i个属性上取值为xi的样本组成的集合,则条件概率P(xi|c)的似然估计为

    离散属性的条件概率

    2)对连输属性需要考虑其密度函数。如p(xi|c)服从正态分布N(μc,i,o2c,i),则有

    连续属性的条件概率

朴素贝爷器分类器的求解步骤
朴素贝叶斯分类器的步骤

下面让我们由西瓜数据集来训练一个朴素贝叶斯分类器,让它对样本进行分类。(虽然这里的样本只有17个,不足以进行有意义的概率估计,但这里仅仅只是做一个简单演示。)
训练集如下

训练集
测试样本如下,
测试样本
首先,估计先验概率P(c),显然有
P(c)
接着,为每个属性估计概率P(x|c):
求出P(c)和P(x|c),就可以得到后验概率
后验概率
由于0.038>6.80x10-5,因此,上面的测试样例"测1"将被分类为"好瓜"。

需要注意,若某个属性值在训练集中没有与某个类同时出现过,若直接计算类条件概率,再根据后验概率进行判别将出现问题。

如对于上述的贝叶斯分类器判别一个"敲声=清脆"的测试样本,其对于的条件概率为
再代入后验概率的求解公式中,可以发现因为是一个连乘的操作,所有后验概率为0,因此"敲声=清脆"的测试样本将被判别为"好瓜=否",也就是无论这个瓜其他属性明显像好瓜,也会判为坏瓜,这显然不合理。

我们使用拉普拉斯修正来解决这种使用极大似然估计可能会出现所要估计的概率值为0,这样会影响到后验概率的结果,最终使得推荐分类产生偏差的情况。使用拉普拉斯修正之后,先验概率和条件概率公式变为:


其中,N表示类别数,如好瓜和坏瓜,N=2;Ni表示第i个属性可能的取值数,如第3个属性敲声取"浊响","沉闷","清脆"三个属性值,则N3=3。
那么例子中的先验概率变为
而类条件概率变为
拉普拉斯修正避免了因训练集样本不充分而导致概率估值为零的问题,
并且在训练集变大时,修正过程所引入的先验的影响也会逐渐变得可忽略,使得估值渐趋向于实际概率值。

编程实现拉普拉斯修正的朴素贝叶斯分类器,并以西瓜数据集3.0为例(P84),对P151的测试样本1进行判别。

import math
import numpy as np
import pandas as pd
 
D_keys = {
    '色泽': ['青绿', '乌黑', '浅白'], 
    '根蒂': ['蜷缩', '硬挺', '稍蜷'], 
    '敲声': ['清脆', '沉闷', '浊响'], 
    '纹理': ['稍糊', '模糊', '清晰'], 
    '脐部': ['凹陷', '稍凹', '平坦'], 
    '触感': ['软粘', '硬滑'], 
}
Class, labels = '好瓜', ['是', '否']
 
# 读取数据
def loadData(filename):
    dataSet = pd.read_csv(filename)
    dataSet.drop(columns=['编号'], inplace=True)
    return dataSet
 
# 配置测1数据
def load_data_test():
    array = ['青绿', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', 0.697, 0.460, '']
    dic = {a: b for a, b in zip(dataSet.columns, array)}
    return dic
 
def calculate_D(dataSet):
    D = []
    for label in labels:
        temp = dataSet.loc[dataSet[Class]==label]
        D.append(temp)
 
    return D
 
def calculate_Pc(Dc, D):
    D_size = D.shape[0]
    Dc_size = Dc.shape[0]
    N = len(labels)
    return (Dc_size+1) / (D_size+N)
 
def calculate_Pcx_D(key, value, Dc):
    Dc_size = Dc.shape[0]
    Dcx_size = Dc[key].value_counts()[value]
    Ni = len(D_keys[key])
    return (Dcx_size+1) / (Dc_size+Ni)
 
def calculate_Pcx_C(key, value, Dc):
    mean, var = Dc[key].mean(), Dc[key].var()
    exponent = math.exp(-(math.pow(value-mean, 2) / (2*var)))
    return (1 / (math.sqrt(2*math.pi*var)) * exponent)
 
def calculate_probability(label, Dc, dataSet, data_test):
    prob = calculate_Pc(Dc, dataSet)
    for key in Dc.columns[:-1]:
        value = data_test[key]
        if key in D_keys:
            prob *= calculate_Pcx_D(key, value, Dc)
        else:
            prob *= calculate_Pcx_C(key, value, Dc)
 
    return prob
 
def predict(dataSet, data_test):
    # mu, sigma = dataSet.mean(), dataSet.var()
    Dcs = calculate_D(dataSet)
    max_prob = -1
    for label, Dc in zip(labels, Dcs):
        prob = calculate_probability(label, Dc, dataSet, data_test)
 
        if prob > max_prob:
            best_label = label
            max_prob = prob
 
        print(label, prob)
 
    return best_label
 
 
if __name__ == '__main__':
    # 读取数据
    filename = 'data_3.txt'
    dataSet = loadData(filename)
    data_test = load_data_test()
    label = predict(dataSet, data_test)
    print('预测结果:', label)

参考链接:https://blog.csdn.net/weixin_37922777/article/details/89454697

7.4 半朴素贝叶斯分类器

朴素贝叶斯分类器的属性条件独立性假设,在现实任务中往往难以成立,因为各属性之间可能存在依赖关系。因此,对这个假设进行一定的放松,由此产生了"半朴素贝叶斯分类器"的学习方法。

"半朴素贝叶斯分类器"的基本思路是适当考虑一部分属性之间的相互依赖关系,从而既不需要完全联合概率计算,又不至于彻底忽略了比较强的属性依赖关系。
独立依赖估计(ODE)是半朴素贝叶斯分类器最常用的一种策略,就是假设每个属性在类别之外最多依赖于一个其他属性,即

ODE
其中pai为xi所依赖的属性,称为xi的父属性。对于每个属性xi,若已知父属性pai,则可以用朴素贝叶斯分类器中修正过后的类条件概率公式求解P(xi|c,pai)。于是,问题的关键就转化为如何确定每个属性的父属性,不同的做法产生不同的独立依赖分类器有下面三种做法:

  • SPODE
    SPODE(Super-Parent ODE)做法是最直接的做法,它假设所有属性都依赖于同一个属性,该属性为父属性,称为"超父",然后通过交叉验证等模型方法来确定超父属性。如下图,x1为超父属性。

    SPODE

  • TAN
    TAN(Tree Augmented naive Bayes)做法是在最大权生成树的基础上,首先通过计算两两属性之间的条件互信息,求出各个边的权值,然后构建完全图的最大带权生成树,最后加入类别结点y,增加从y到每个属性的有向边。

    将属性间依赖关系约间为生成树的步骤
    条件互信息刻画了属性xi和xj在已知类别情况下的相关性,通过最大生成树算法,TAN仅保留了强相关属性之间的依懒性。
    最终得到如下树形结构

  • AODE
    AODE(Averaged ODE)是一种集成学习机制,它尝试将每个属性作为超父来构建SPODE,然后将那些具有足够训练数据支撑的SPODE集成作为最终结果。即

    Dxi是在第i个属性上取值为xi的样本的集合,m' 为阈值常数。可见,AODE需要估计P(c,xi)和P(xj|c,xi),如下
    其中Ni是第i个属性可能的取值数,Nj是第j个属性可能的取值数,Dc,xi是类别为c且在第i个属性上取值为xi的样本集合,Dc,xi,xj是类别为c且在第i和第j个属性上取值分别为xi和xj的样本集合。如以上面的西瓜数据集为例

    这就是以上三种做法。

需注意的是,当依赖属性个数变多时,需要的训练样本数量将以指数增加。因此,若训练数据非常充分,泛化性能能有可能提升;但在有限样本条件下,则又会陷入估计高阶联合概率的问题。

7.5 贝叶斯网

贝叶斯网借助有向无环图(没有回路)来刻画属性之间的依赖关系,并使用条件概率表来描述属性的联合概率分布。

贝叶斯网B由结构G和参数Θ两部分构成,即B= <G,Θ>。
结构G是一个有向无环图,其每个结点对应于一个属性。若两个属性有直接依赖关系,则它们的直接依赖关系由一条边连接起来表示;
参数Θ定量描述这种依赖关系,其包含了每个属性的条件概率表。
假设xi在G中的父结点集合为πi,则Θ包含了每个属性的条件概率表
θxi|πi=PB(xii)
如,

贝叶斯网
上图是贝叶斯网和属性"根蒂"的条件概率表。
从图中可以看出,"色泽"直接依赖于"好瓜"和"甜度",而"根蒂"依赖于"甜度"。进一步,我们可以得到属性的条件概率表,从中量化它们的依赖关系,如从"根蒂"的条件概率表中能得到"根蒂"对"甜度"量化依赖关系,如P(根蒂=硬挺 | 甜度=高) = 0.1。

1.结构

贝叶斯网中,给定父结点集,假设每个属性与它的非后裔属性独立,也就是说不存在依赖关系的属性相互独立,于是属性x1,x2,……,xd的联合概率定义为

贝叶斯网中,属性的联合概率
如,上图中的属性联合概率为
也就是,x1和x2独立,而x3和x4在给定x1时独立,x4和x5在给定x2时独立,记为x3⊥x4|x1,x4⊥x5|x2

在贝叶斯网中,三个变量之间典型的依赖关系,分别为
同父结构,V型结构,顺序结构。

三个变量之间典型的依赖关系

同父结构中,给定父结点x1,则x3与x4条件独立。
顺序结构中,给点结点x,则y与z条件独立。
V型结构中,给定结点x4,则x1和x2不条件独立,反而是当x4的取值未知时,x1和x2条件独立,验证如下
这种独立性,叫做"边际独立性",记为x1 _||_ x2
可以看出,一个变量取值是否确定,能对另外两个变量间的独立性发生影响。如同父结构,若x1的值未知,则x3和x4就不独立,即x3 _||_ x4不成立。

我们可以将有向图转化为无向图,来分析有向图中变量间的条件独立性。步骤如下
有向图转化为无向图

无向图称为道德图,父结点相连的过程叫做道德化。最后得到的图如下
道德图

2.学习

贝叶斯学习的首要任务是根据训练数据集找出结构最恰当的贝叶斯网。
"评分搜索"来解决这个问题。
具体是先定义一个评分函数,以此评估贝叶斯网与训练数据的契合程度,然后基于这个函数来寻找结构最优的贝叶斯网。这个评分函数由我们希望获得什么样的贝叶斯网而确定。


  • 得到一个什么样的贝叶斯网是合理的呢?

    信息论准则将学习问题看作一个数据压缩的问题,目标是找到以最短编码长度描述训练数据的模型。编码长度包括描述模型自身所需的字节长度和描述数据所需的字节长度。常用评分函数基于上述准则。

    对于贝叶斯网学习,评分函数基于"最小描述长度"准则:选择综合编码长度最短的贝叶斯网
    贝叶斯学习得到的模型是一个贝叶斯网,每个贝叶斯网描述了训练数据上的概率分布,有一套编码机制使得经常出现的样本有更短的编码。
    因此,选择综合编码长度(包括描述网络和编码数据)最短的贝叶斯网

  • 贝叶斯网的评分函数
    有了上面的准则,就可以给出贝叶斯网的评分函数了。
    给定训练集D={x1,x2,……,xm},贝叶斯网B=(G,Θ)在D上的评分函数为

    第一项f(θ)|B|是计算编码贝叶斯网B所需的字节数,其中|B|是贝叶斯网的参数个数;f(θ)表示描述每个参数θ所需的字节数。

    第二项是计算B所对应的概率分布PB需多少字节来描述D:其中LL(B|D)指的是贝叶斯网B的对数似然

由此可把学习任务转化为一个优化任务:寻找一个贝叶斯网B使得评分函数s(B|D)最小。其中,当f(θ)的取值分布为1、1/2logm、0时有

若贝叶斯网的结构G固定,则评分函数第一项为常数,此时最小化评分函数等价于对于参数Θ的极大似然估计,通过下两式子
联合概率
对数似然
可知,参数θxi|πi能直接在训练数据D上通过经验估计得到,即
其中P^D是D上的经验分布,即事件在训练集上出现的频率。因此为了最小化评分函数 s(BID) 只需对网络结构进行搜索,而候选结构的最优参数可直接在训练集上计算得到。

然而从所有可能的网络结构空间搜索最优贝叶斯网结构是一个NP难问题,有两种策略在有限时间内求得近似解:
1)贪心算法:例如从某个网络结构出发,每次调整一条边(增加、删除或改变方向),直到评分函数值不再降低为止。
2)通过给网络结构施加约束来削减搜索空间,例如将网络结构限定为树形结构。

3.推断

贝叶斯网训练好之后,可以通过一些属性变量的观测值来推测其他属性变量的取值。如,我们观测到西瓜色泽青绿、敲声浊响、根蒂蜷缩,想知道它是否成熟、甜度如何。
通过已知变量观测值来推测待查询的过程称为"推断",已知变量观测值称为"证据"。

当网络结点较多、连接稠密时,难以进行精确推断,得到后验概率,需要借助"近似推断",通过降低精度要求,求得近似解。
贝叶斯网的近似推断常使用吉布斯采样来完成,这是一种随机采用法,接下来看它如何工作。

令Q={Q1,Q2,……,Qn}表示待查询变量,q={q1,q2,……,qn}是待查询变量的一组取值;E={E1,E2,……,Ek}为证据变量,其取值为e={e1,e2,……,ek}。
目标是计算后验概率P(Q=q|E=e)。
如,西瓜问题,待查询变量为Q={好瓜,甜度},证据变量E={色泽,敲声,根蒂}且已知其取值为e={青绿,浊响,蜷缩},查询目标值是q={是,高},即这是好瓜且甜度高的概率有多大。以下是吉布斯采样的流程


总结一下它的步骤:
①先随机产生一个证据E=e一致的样本q0作为初始点;
②每步从当前样本出发产生下一个样本,具体来说:在第t次采样中,对非证据变量逐个进行采样改变其取值,采样概率根据贝叶斯网B和其他变量的当前取值(即Z=z)计算获得,再将qt = qt-1
③若新生成的qt与我们要进行预测的q一致,则n加一;
④重复以上②、③步骤,通过T次计算之后得到的与q一致的样本一共有n个,其后验概率约为n/T。

7.6 EM算法

以上的例子中,我们总是假设训练样本都是完整的。但实际上,训练样本往往是有所缺失的。例如,由于西瓜的根蒂脱落,无法看出其根蒂的属性值。这种"未观测"变量,称为"隐变量"

令X表示已观测变量集(属性值都知道),Z表示隐变量集,Θ表示模型参数。对Θ进行极大似然估计,即最大化对数似然函数


由于Z是隐变量,无法直接计算,因此我们使用EM(Expectation-Maximization)算法来估计隐变量。
我们可以对Z计算期望,来最大化已观测数据的对数边际似然

EM算法的基本思想:若参数Θ己知,则可根据训练数据推断出最优隐变量Z的值(E步);反之,若Z的值已知,则可方便地对参数Θ做极大似然估计(M步)。步骤如下

第一步(E步):用当前估计的参数值求对数似然的期望值;
第二步(M步):寻找参数最大似然估计:寻找能使E步产生的似然期望最大化的参数值,然后该参数值重新被用于E步。
不断重复第一、第二步直到收敛到局部最优解。

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

推荐阅读更多精彩内容