樸素貝葉斯(Naive Bayes)

一. 生成式(generative)學習算法

如果算法直接學習p(y|x)力九,或者嘗試學習從輸入空間X到類別\{0,1\}的映射關(guān)系的算法筐咧,稱為判別式(discriminative)學習算法误褪;比線性回歸(lineaar regression)的模型:
f(y|x;\theta) = h_{\theta}(x) + \theta_{0} + \theta_{1}x_1 + \theta_{2}x_2 + ... + \theta_{n}x_n

再比如邏輯回歸(logistic regression):
f(y|x;\theta) = h_{\theta}(x) = g(\theta^{T}x) = \frac{1}{1+e^{-\theta^{T}x}}
這里的g是sigmoid函數(shù)

而另外一種算法是建立p(x|y)(和p(y))的模型亭螟,這類算法稱為生成式(generative)學習算法,我們今天要討論的樸素貝葉斯算法即是其中一個榆俺。對p(y)(先驗 prior)和p(x|y)售躁,使用貝葉斯規(guī)則來推導給定xy的后驗(posterior)分布:

p(y|x) = \frac{p(x|y)p(y)}{p(x)}

其中分母可由全概率公式計算:

p(x) = p(x|y=1)p(y=1) + p(x|y=0)p(y=0)

實際上,我們在計算p(y|x)做預測時茴晋,可以不用計算分母p(x)陪捷,因為:
arg \ \max \limits_{y} \ p(y|x) = arg \ \max \limits_{y} \ \frac{p(x|y)p(y)}{p(x)} = arg \ \max \limits_{y} \ p(x|y)p(y)

二. 樸素貝葉斯(Naive Bayes)

2.1 樸素貝葉斯算法

假設(shè)我們想利用機器學習來構(gòu)建一個言論過濾器,希望對網(wǎng)站的留言評論自動區(qū)分是侮辱性言論诺擅,還是非侮辱性言論∈行洌現(xiàn)在已知一個訓練數(shù)據(jù)集(一些已經(jīng)標記為侮辱或者非侮辱的言論集合)如下:

"""
函數(shù)說明:創(chuàng)建實驗樣本

Parameters:
    無
Returns:
    postingList - 實驗樣本切分的詞條
    classVec - 類別標簽向量
"""
def loadDataSet():
    postingList = [['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],          # 切分的詞條
                   ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
                   ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
                   ['stop', 'posting', 'stupid', 'worthless', 'garbage'],
                   ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
                   ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
    classVec = [0, 1, 0, 1, 0, 1]           # 對應postingList中每個樣本的類別標簽向量,1代表侮辱性言論烁涌, 0代表非侮辱性言論
    return postingList, classVec

y 表示該言論是否是侮辱性言論:
y = \begin{cases} 1 & \mbox{侮辱性言論} \\ 0 & \mbox{非侮辱性言論} \end{cases}

接下來苍碟,我們將樣本數(shù)據(jù)蹂安,即postingList涎永,轉(zhuǎn)化成特征向量受扳,用 x 表示茫陆,其中包含單詞特征:
x_j = \begin{cases} 1 & \mbox{第 $j$ 個單詞出現(xiàn)} \\ 0 & \mbox{未出現(xiàn)} \end{cases}

編碼到向量中的單詞的集合稱為詞匯表痹升,例如“ my”拒课,“stupid”等等鳞骤,向量x的長度等于詞匯表的長度探颈。

注意继效,這里的詞匯表不是將英語詞典中單詞全部列出來症杏,通常是將訓練數(shù)據(jù)集中的所有單詞,即使僅出現(xiàn)過一次瑞信,放到詞匯表中厉颤。這樣做可以減少模型的詞匯數(shù)量,從而減少計算量凡简,節(jié)省空間逼友;還有個好處是能夠?qū)⒂⒄Z詞典中不會出現(xiàn)的詞,但會出現(xiàn)在留言評論中的詞秤涩,比如“2233”放到詞匯表中帜乞;同時還需要剔除一些高頻詞,比如 “the” “of” “and”筐眷,這些詞在很多的文本中都會出現(xiàn)黎烈,對區(qū)分是否是侮辱性言論沒有任何幫助。

特征向量x與詞匯表如下圖所示,言論中包含“a”照棋,“buy”资溃,不包含“aardvard”,“aardwolf”烈炭,“zygmurgy”:

創(chuàng)建詞匯表代碼如下:

"""
函數(shù)說明:將切分的實驗樣本詞條整理成不重復的詞條列表溶锭,也就是詞匯表

Parameters:
    dataSet - 樣本數(shù)據(jù)集 postingList
Returns:
    vocabSet - 返回不重復的詞條列表,也就是詞匯表
"""
def createVocabList(dataSet):
    vocabSet = set([])
    for document in dataSet:
        vocabSet = vocabSet | set(document)
    return list(vocabSet)

將樣本數(shù)據(jù)轉(zhuǎn)換成特征向量x代碼如下:

"""
函數(shù)說明:根據(jù)vocabList詞匯表符隙,將inputSet向量化趴捅,向量的每個元素為1或0

Parameters:
    vocabList - 詞匯表
    inputSet - 某條言論文檔
Returns:
    returnVec - 言論文檔向量
"""
def setOfWords2Vec(vocabList, inputSet):
    returnVec = [0] * len(vocabList)            # 創(chuàng)建一個其中所含元素都為0的向量
    for word in inputSet:                       # 遍歷每個詞條
        if word in vocabList:                   # 如果詞條存在于詞匯表中,則置1
            returnVec[vocabList.index(word)] = 1
        else:
            print("the word: %s is not in my vocabulary !" % word)
    return returnVec

現(xiàn)在我們來構(gòu)建p(x|y)霹疫。上面代碼示例中詞匯表中單詞較少驻售,但如果詞匯表中包含50000個單詞,那么x \in \{0, 1\rbrace^{50000}x是50000維0和1組成的向量)更米,如果我們直接用多項式來構(gòu)造x2^{50000}個可能的結(jié)果,那么多項式的參數(shù)向量有2^{50000} - 1維毫痕,顯然參數(shù)太多了征峦。

因此算法做了一個強假設(shè),即假設(shè)給定y的情況下x_j條件獨立消请,這個假設(shè)就稱為樸素貝葉斯假設(shè)栏笆,算法稱為樸素貝葉斯分類。例如臊泰,如果y=1表示侮辱性言論蛉加,“stupid”是第2087個單詞,“worthless”是第39831個單詞缸逃,那么我們假設(shè)如果已知y=1针饥,那么x_{2087}的值(“stupid”是否出現(xiàn)在言論中) 對x_{39831}的值(“worthless”是否出現(xiàn)在言論中)沒有任何影響。正式一點來描述需频,上述可以寫成p(x_{2087}|y) = p(x_{2087}|y,x_{39831})丁眼。需要注意的是,這里并不是說x_{2087}x_{39831}相互獨立昭殉,相互獨立表示為p(x_{2087}) = p(x_{2087}|x_{39831})苞七,而是僅假設(shè)x_{2087}x_{39831}在給定y的情況下條件獨立。根據(jù)上述假設(shè)挪丢,有如下等式成立:
\begin{eqnarray} p(x_1,...,x_{50000}|y) \\ &=& p(x_1|y)p(x_2|y,x_1)p(x_3|y,x_1,x_2)...p(x_{50000}|y,x1,...,x_{49999}) \\ &=& p(x_1|y)p(x_2|y)p(x_3|y)...p(x_{50000}|y) \\ &=& \prod_{j=1}^{n} p(x_j|y) \end{eqnarray}
第一個等式是概率的基本性質(zhì)蹂风,第二個等式用了樸素貝葉斯假設(shè)。

我們的模型中的參數(shù)為\phi_{j|y=1} = p(x_j = 1|y = 1)乾蓬,\phi_{j|y=0} = p(x_j = 1|y = 0)\phi_{y} = p(y = 1)惠啄,其中j為詞匯表中第j個單詞。給定一個訓練數(shù)據(jù)集\lbrace (x^{(i)}, y^{(i)}); i=1,...,m\rbrace,我們可以寫出似然函數(shù):

L(\phi_y, \phi_{j|y=0}, \phi_{j|y=1}) = \prod_{i=1}^{m} p(x^{ ( i )}, y^{ ( i )})

最大化關(guān)于參數(shù)\phi_y, \phi_{j|y=0}, \phi_{j|y=1}的上述似然函數(shù)礁阁,得到第j個單詞相關(guān)參數(shù)的極大似然估計:

\phi_{j|y=1} = \frac{\sum_{i=1}^{m} 1 \{ x_j^{(i)} = 1 \land y^{(i)} = 1 \rbrace }{\sum_{i=1}^{m} 1 \{ y^{(i)} = 1 \rbrace }
\phi_{j|y=1}即是對p(x_j|y=1)的估計巧号;

\phi_{j|y=0} = \frac{\sum_{i=1}^{m} 1 \{ x_j^{(i)} = 1 \land y^{(i)} = 0 \rbrace }{\sum_{i=1}^{m} 1 \{ y^{(i)} = 0 \rbrace }
\phi_{j|y=0}即是對p(x_j|y=0)的估計;

\phi_{y=1} = \frac{\sum_{i=1}^{m} 1 \{ y^{(i)} = 1 \rbrace }{m}
\phi_{y=1}即是對p(y=1)的估計姥闭;同理
\phi_{y=0} = \frac{\sum_{i=1}^{m} 1 \{ y^{(i)} = 0 \rbrace }{m}
\phi_{y=0}即是對p(y=0)的估計丹鸿;參數(shù)表達式中的 \land表示“與”。上面的參數(shù)不難理解棚品,\phi_{j|y=1}就是侮辱性言論(y=1)中單詞j出現(xiàn)的百分比靠欢。訓練階段代碼如下:

"""
函數(shù)說明:樸素貝葉斯分類器訓練函數(shù)

Parameters:
    trainMatrix - 訓練文檔矩陣,即setOfWords2Vec返回的returnVec構(gòu)成的矩陣
    trainCategory - 訓練類別標簽向量铜跑,即loadDataSet返回的classVec
Returns:
    p0Vect - 非侮辱類的條件概率數(shù)組
    p1Vect - 侮辱類的條件概率數(shù)組
    pAbusive - 文檔屬于侮辱類的概率
"""
def trainNB0(trainMatrix, trainCategory):
    numTrainDocs = len(trainMatrix)         #計算訓練的文檔數(shù)目
    numWords = len(trainMatrix[0])          #計算每篇文檔的詞條數(shù)
    pAbusive = sum(trainCategory)/float(numTrainDocs)  #文檔屬于侮辱類的概率
    p0Num = np.zeros(numWords)              #創(chuàng)建numpy.zeros數(shù)組,詞條出現(xiàn)數(shù)初始化為0
    p1Num = np.zeros(numWords)
    p0Denom = 0.0                           #分母初始化為0
    p1Denom = 0.0
    for i in range(numTrainDocs):
        if trainCategory[i] == 1:           #向量相加门怪,統(tǒng)計屬于侮辱類的條件概率所需的數(shù)據(jù),即P(w0|1),P(w1|1),P(w2|1)···
            p1Num += trainMatrix[i]
            p1Denom += sum(trainMatrix[i])
        else:                               #向量相加锅纺,統(tǒng)計屬于非侮辱類的條件概率所需的數(shù)據(jù)掷空,即P(w0|0),P(w1|0),P(w2|0)···
            p0Num += trainMatrix[i]
            p0Denom += sum(trainMatrix[i])

    p1Vect = p1Num/p1Denom
    p0Vect = p0Num/p0Denom
    return p0Vect, p1Vect, pAbusive         #返回屬于侮辱類的條件概率數(shù)組,屬于非侮辱類的條件概率數(shù)組囤锉,文檔屬于侮辱類的概率

已知參數(shù)估計之后坦弟,對一個特征向量x的新樣本計算是侮辱性言論的概率如下:
\begin{eqnarray} p(y=1|x) &=& \frac{p(x|y)p(y=1)} {p(x)} \\ &=& \frac{(\prod_{j=1}^{n} p(x_j | y=1))p(y=1)} {(\prod_{j=1}^{n} p(x_j | y= 1))p(y=1) + (\prod_{j=1}^{n} p(x_j | y= 0))p(y=0)} \end{eqnarray}
同樣,計算非侮辱性言論的概率如下:
\begin{eqnarray} p(y=0|x) &=& \frac{p(x|y)p(y=0)} {p(x)} \\ &=& \frac{(\prod_{j=1}^{n} p(x_j | y=0))p(y=0)} {(\prod_{j=1}^{n} p(x_j | y= 1))p(y=1) + (\prod_{j=1}^{n} p(x_j | y= 0))p(y=0)} \end{eqnarray}
如果計算得出p(y=1|x) > p(y=0|x)官地,則認為言論是侮辱性言論酿傍,反之是非侮辱性言論,預測代碼如下:

"""
函數(shù)說明:樸素貝葉斯分類器分類函數(shù)

Parameters:
    vec2Classify - 待分類的詞條數(shù)組
    p0Vec - 侮辱類的條件概率數(shù)組
    p1Vec -非侮辱類的條件概率數(shù)組
    pClass1 - 文檔屬于侮辱類的概率
Returns:
    0 - 屬于非侮辱類
    1 - 屬于侮辱類
"""
def classifyNB0(vec2Classify, p0Vec, p1Vec, pClass1):
    p1 = reduce(lambda x,y : x * y, vec2Classify * p1Vec) * pClass1             # 對應元素相乘
    p0 = reduce(lambda x,y : x * y, vec2Classify * p0Vec) * (1 - pClass1)
    print('p0:', p0)
    print('p1', p1)
    if p1 > p0:
        return p1
    else:
        return p0

2.2 下溢出與拉普拉斯平滑

2.1節(jié)中我們使用樸素貝葉斯算法構(gòu)造了言論分類器驱入,下面我們對算法進行測試:

"""
函數(shù)說明:測試樸素貝葉斯分類器

Parameters:
    無
Returns:
    無
"""
def testingNB0():
    listOPosts, classVec = loadDataSet()  # 創(chuàng)建實驗樣本

    myVocabList = createVocabList(listOPosts)  # 創(chuàng)建詞匯表

    # 打印中間結(jié)果
    print('myVocabList:\n', myVocabList)

    trainMat = []
    for postinDoc in listOPosts:
        trainMat.append(setOfWords2Vec(myVocabList, postinDoc))  # 將實驗樣本向量化
    p0V, p1V, pAb = trainNB0(np.array(trainMat), np.array(classVec))  # 訓練樸素貝葉斯分類器

    # 打印中間結(jié)果
    print('p0V:\n', p0V)
    print('p1V:\n', p1V)
    print('classVec:\n', classVec)
    print('pAb:\n', pAb)


    testEntry = ['love', 'my', 'dalmation']  # 測試樣本1
    thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry))  # 測試樣本向量化
    if classifyNB0(thisDoc, p0V, p1V, pAb):
        print(testEntry, '屬于侮辱類')  # 執(zhí)行分類并打印分類結(jié)果
    else:
        print(testEntry, '屬于非侮辱類')  # 執(zhí)行分類并打印分類結(jié)果

    testEntry = ['stupid', 'garbage']  # 測試樣本2
    thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry))  # 測試樣本向量化
    if classifyNB0(thisDoc, p0V, p1V, pAb):
        print(testEntry, '屬于侮辱類')  # 執(zhí)行分類并打印分類結(jié)果
    else:
        print(testEntry, '屬于非侮辱類')  # 執(zhí)行分類并打印分類結(jié)果

if __name__ == "__main__":
    testingNB0()

運行結(jié)果截圖如下:

小伙伴們赤炒,發(fā)現(xiàn)問題了嗎?顯然這個結(jié)果是不對的亏较。算法存在兩個問題:

  • 某些單詞0概率莺褒,導致整體乘積為0,例如“stupid”宴杀;
  • 下溢出(underflow):

對于第一個問題癣朗,我們通過打印中間結(jié)果可以看出:

又或者對一個訓練數(shù)據(jù)集中未出現(xiàn)的詞,概率也是0旺罢,顯然旷余,這樣是不合理的,因為訓練集有限扁达,不能因為訓練集中沒有出現(xiàn)正卧,就認為這個詞永遠不會出現(xiàn)。記得吳恩達老師在機器學習課上講了個段子跪解,斯坦福大學的新酰籃球隊接連輸了5場比賽,問下一場比賽贏的概率???連輸5場窘行,下一場肯定輸嗎饥追?合理的預測是有贏的概率,只是比較小罐盔,設(shè)置贏的概率為1/7吧??但绕。這種做法就叫做拉普拉斯平滑(Laplace Smoothing)。具體做法是修改極大似然估計的參數(shù):

\phi_{j|y=1} = \frac{\sum_{i=1}^{m} 1 \{ x_j^{(i)} = 1 \land y^{(i)} = 1 \rbrace + 1}{\sum_{i=1}^{m} 1 \{ y^{(i)} = 1 \rbrace + k}
\phi_{j|y=1}即是對p(x_j|y=1)的估計惶看;

\phi_{j|y=0} = \frac{\sum_{i=1}^{m} 1 \{ x_j^{(i)} = 1 \land y^{(i)} = 0 \rbrace + 1 }{\sum_{i=1}^{m} 1 \{ y^{(i)} = 0 \rbrace + k}
\phi_{j|y=0}即是對p(x_j|y=0)的估計捏顺。

其中k代表y的可能取值數(shù)量,我們的例子中y的取值只有01兩種纬黎,因此k=2幅骄。
那么為什么分子加1,分母加k呢本今?因為要保證\phi_j相加仍然是1拆座。下面我們檢驗一下,假設(shè)隨機變量z的取值有k
\phi_{j} = \frac{\sum_{i=1}^{m} 1 \{z_i = j\rbrace}{m}
其中\sum_{j=0}^{k} \phi_j = 1冠息,則應用拉普拉斯平滑之后

\phi_{j}^{'} = \frac{\sum_{i=1}^{m} 1 \{z_i = j\rbrace + 1}{m+ k}
不難推出\sum_{j=0}^{k} \phi_{j}^{'} = 1

除此之外懂拾,另外一個遇到的問題就是下溢出,這是由于太多很小的數(shù)相乘造成的铐达。學過數(shù)學的人都知道,兩個小數(shù)相乘檬果,越乘越小瓮孙,這樣就造成了下溢出。在程序中选脊,在相應小數(shù)位置進行四舍五入杭抠,計算結(jié)果可能就變成0了。為了解決這個問題恳啥,對乘積結(jié)果取自然對數(shù)偏灿。通過求對數(shù)可以避免下溢出或者浮點數(shù)舍入導致的錯誤。同時钝的,采用自然對數(shù)進行處理不會有任何損失翁垂。下圖給出函數(shù)f(x)和ln(f(x))的曲線:

檢查這兩條曲線,就會發(fā)現(xiàn)它們在相同區(qū)域內(nèi)同時增加或者減少硝桩,并且在相同點上取到極值沿猜。它們的取值雖然不同,但不影響最終結(jié)果碗脊。因此我們可以對上篇文章的trainNB0(trainMatrix, trainCategory)函數(shù)進行更改啼肩,修改如下:

"""
函數(shù)說明:樸素貝葉斯分類器訓練函數(shù)

Parameters:
    trainMatrix - 訓練文檔矩陣,即setOfWords2Vec返回的returnVec構(gòu)成的矩陣
    trainCategory - 訓練類別標簽向量,即loadDataSet返回的classVec
Returns:
    p0Vect - 非侮辱類的條件概率數(shù)組
    p1Vect - 侮辱類的條件概率數(shù)組
    pAbusive - 文檔屬于侮辱類的概率
"""
def trainNB(trainMatrix, trainCategory):
    numTrainDocs = len(trainMatrix)         # 計算訓練的文檔數(shù)目
    numWords = len(trainMatrix[0])          # 計算每篇文檔的詞條數(shù)
    pAbusive = sum(trainCategory) / float(numTrainDocs)  # 文檔屬于侮辱類的概率
    p0Num = np.ones(numWords)
    p1Num = np.ones(numWords)               # 創(chuàng)建numpy.ones數(shù)組,詞條出現(xiàn)數(shù)初始化為1祈坠,拉普拉斯平滑
    p0Denom = 2.0
    p1Denom = 2.0                           # 分母初始化為2,拉普拉斯平滑
    for i in range(numTrainDocs):
        if trainCategory[i] == 1:           # 向量相加害碾,統(tǒng)計屬于侮辱類的條件概率所需的數(shù)據(jù),赦拘,即P(w0|1),P(w1|1),P(w2|1)···
            p1Num += trainMatrix[i]
            p1Denom += sum(trainMatrix[i])
        else:                               # 向量相加慌随,統(tǒng)計屬于非侮辱類的條件概率所需的數(shù)據(jù),即P(w0|0),P(w1|0),P(w2|0)···
            p0Num += trainMatrix[i]
            p0Denom += sum(trainMatrix[i])
    p1Vect = np.log(p1Num / p1Denom)        # 取對數(shù)另绩,防止下溢出
    p0Vect = np.log(p0Num / p0Denom)
    return p0Vect, p1Vect, pAbusive         # 返回屬于侮辱類的條件概率數(shù)組儒陨,屬于非侮辱類的條件概率數(shù)組,文檔屬于侮辱類的概率

"""
函數(shù)說明:樸素貝葉斯分類器分類函數(shù)

Parameters:
    vec2Classify - 待分類的詞條數(shù)組
    p0Vec - 非侮辱類的條件概率數(shù)組
    p1Vec -侮辱類的條件概率數(shù)組
    pClass1 - 文檔屬于侮辱類的概率
Returns:
    0 - 屬于非侮辱類
    1 - 屬于侮辱類
"""
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
    p1 = sum(vec2Classify * p1Vec) + np.log(pClass1)  # 對應元素相乘笋籽。logA * B = logA + logB蹦漠,所以這里加上log(pClass1)
    p0 = sum(vec2Classify * p0Vec) + np.log(1.0 - pClass1)
    if p1 > p0:
        return 1
    else:
        return 0

"""
函數(shù)說明:測試樸素貝葉斯分類器

Parameters:
    無
Returns:
    無
"""
def testingNB():
    listOPosts, classVec = loadDataSet()  # 創(chuàng)建實驗樣本

    myVocabList = createVocabList(listOPosts)  # 創(chuàng)建詞匯表

    # 打印中間結(jié)果
    print('myVocabList:\n', myVocabList)

    trainMat = []
    for postinDoc in listOPosts:
        trainMat.append(setOfWords2Vec(myVocabList, postinDoc))  # 將實驗樣本向量化
    p0V, p1V, pAb = trainNB(np.array(trainMat), np.array(classVec))  # 訓練樸素貝葉斯分類器

    # 打印中間結(jié)果
    print('p0V:\n', p0V)
    print('p1V:\n', p1V)
    print('classVec:\n', classVec)
    print('pAb:\n', pAb)


    testEntry = ['love', 'my', 'dalmation']  # 測試樣本1
    thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry))  # 測試樣本向量化
    if classifyNB(thisDoc, p0V, p1V, pAb):
        print(testEntry, '屬于侮辱類')  # 執(zhí)行分類并打印分類結(jié)果
    else:
        print(testEntry, '屬于非侮辱類')  # 執(zhí)行分類并打印分類結(jié)果

    testEntry = ['stupid', 'garbage']  # 測試樣本2
    thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry))  # 測試樣本向量化
    if classifyNB(thisDoc, p0V, p1V, pAb):
        print(testEntry, '屬于侮辱類')  # 執(zhí)行分類并打印分類結(jié)果
    else:
        print(testEntry, '屬于非侮辱類')  # 執(zhí)行分類并打印分類結(jié)果

if __name__ == "__main__":
    testingNB()

運行結(jié)果如下:

Reference

  1. Naive_Bayes_classifier wiki

  2. Gaussian Discriminant Analysis an example of Generative Learning Algorithms

  3. cs229 lecture notes Part IV Generative Learning algorithms

  4. Machine Learning in Action

  5. Jack Cui 機器學習實戰(zhàn)教程(四):樸素貝葉斯基礎(chǔ)篇之言論過濾器

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市车海,隨后出現(xiàn)的幾起案子笛园,更是在濱河造成了極大的恐慌,老刑警劉巖侍芝,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件研铆,死亡現(xiàn)場離奇詭異,居然都是意外死亡州叠,警方通過查閱死者的電腦和手機棵红,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來咧栗,“玉大人逆甜,你說我怎么就攤上這事≈掳澹” “怎么了交煞?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長斟或。 經(jīng)常有香客問我素征,道長,這世上最難降的妖魔是什么萝挤? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任御毅,我火速辦了婚禮,結(jié)果婚禮上怜珍,老公的妹妹穿的比我還像新娘亚享。我一直安慰自己,他們只是感情好绘面,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布欺税。 她就那樣靜靜地躺著侈沪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪晚凿。 梳的紋絲不亂的頭發(fā)上亭罪,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音歼秽,去河邊找鬼应役。 笑死,一個胖子當著我的面吹牛燥筷,可吹牛的內(nèi)容都是我干的箩祥。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼肆氓,長吁一口氣:“原來是場噩夢啊……” “哼袍祖!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起谢揪,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤蕉陋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后拨扶,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凳鬓,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年患民,在試婚紗的時候發(fā)現(xiàn)自己被綠了缩举。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡匹颤,死狀恐怖蚁孔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情惋嚎,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布站刑,位于F島的核電站另伍,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏绞旅。R本人自食惡果不足惜摆尝,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望因悲。 院中可真熱鬧堕汞,春花似錦、人聲如沸晃琳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至人灼,卻和暖如春围段,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背投放。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工奈泪, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人灸芳。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓涝桅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親烙样。 傳聞我的和親對象是個殘疾皇子冯遂,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353