支持向量機(jī)模型原理推導(dǎo)及python實(shí)現(xiàn)

SVM

支持向量機(jī)(support vector machines, SVM),是一種二分類模型姨拥, 屬于判別模型。

基本原理是在特征空間中找到一個(gè)間隔最大的分離超平面,將正負(fù)類分開疯暑。

1. 基本模型定義:

(硬間隔)支持向量機(jī):

假設(shè)給定線性可分訓(xùn)練集T = \{(x_1,y_1), (x_2. y_2), \cdots ,(x_N, y_N)\}

通過間隔最大化或者等價(jià)地求解相應(yīng)的凸二次規(guī)劃問題,從而學(xué)習(xí)到的分隔超平面為:w^* · x + b^* = 0

以及相應(yīng)的分類決策函數(shù)為f(x) = sign(w^* · x + b^* )

以上模型即(硬間隔)支持向量機(jī)

其中

w^*, b^* 均為模型參數(shù)

w^* 表示分離超平面的法向量

b^* 為 分離超平面的截距

支持向量機(jī)的目標(biāo)是最大化分超平面與最近的二分類點(diǎn)的距離

樣本空間中任意一點(diǎn)到分離超平面的距離推導(dǎo):

設(shè)一點(diǎn)x_0, 求它到超平面S:w · x + b = 0 的距離哑舒,
設(shè)x_0S 上的投影點(diǎn)為 x_1, 則有 w ·x_1 + b = 0妇拯,
同時(shí)向量 \overrightarrow{x_0x_1} 與 超平面的法向量w 平行,故有洗鸵,
|w ·\overrightarrow{x_0x_1} | = |w ·| |\overrightarrow{x_0x_1} | = ||w|| d 其中 d 是我們要求的距離越锈,而
w ·\overrightarrow{x_0x_1} = w · x_0 - w · x_1
代入 w · x_1 + b = 0 得到 w ·\overrightarrow{x_0x_1} = w · x_0 + b
||w|| d = |w · x_0 + b| \Rightarrow d = \frac{1}{||w||} |w· x + b|

因此 支持向量機(jī)的目標(biāo)就是 通過特征空間,找到(w, b)來最大化這個(gè)距離d

2. 函數(shù)間隔和幾何間隔

函數(shù)間隔定義為

對(duì)于給定的訓(xùn)練數(shù)據(jù)集T和超平面(w·x+b = 0) , 定義樣本點(diǎn)(x_i, y_i) 到超平面的函數(shù)間隔為:

\hat \gamma = y_i(w · x_i + b)

PS:定義訓(xùn)練數(shù)據(jù)集T關(guān)于超平面(w,b)的函數(shù)間隔為所有樣本點(diǎn)(x_i,y_i) 的函數(shù)間隔中的最小值 即 \hat \gamma = min (\hat{\gamma_i} ), i =1,2,\cdots, N

幾何間隔定義為:

對(duì)于給定的訓(xùn)練數(shù)據(jù)集T和超平面(w·x+b = 0) , 定義樣本點(diǎn)(x_i, y_i) 到超平面的幾何間隔為:

\gamma = y_i(\frac{w}{||w||} · x_i + \frac预麸{||w||})

定義訓(xùn)練數(shù)據(jù)集T關(guān)于超平面(w,b)的幾何間隔為所有樣本點(diǎn)(x_i,y_i) 的幾何間隔中的最小值 即 \gamma = min ({\gamma_i} ), i =1,2,\cdots, N

所以 當(dāng)||w|| = 1 時(shí) 函數(shù)間隔與幾何間隔等價(jià)瞪浸。

3. 幾何間隔最大化

支持向量機(jī)的基本目標(biāo)是找到能夠正確劃分?jǐn)?shù)據(jù)集并且最大化幾何間隔的超平面。

和感知機(jī)原理不同吏祸,感知機(jī)中能夠正確劃分?jǐn)?shù)據(jù)集的分離超平面可能會(huì)有很多对蒲。

SVM中只有一個(gè)符合目標(biāo)的超平面

數(shù)學(xué)表示為約束最優(yōu)化問題:
max_{(w,b)} \gamma

s.t. y_i(\frac{w}{||w||} · x_i + \frac{||w||}) >= \gamma, i = 1, 2, \cdots, N

考慮到幾何間隔和函數(shù)間隔的關(guān)系, 有:

max_{(w,b)} \frac{\hat\gamma}{||w||}

s.t. y_i(w · x+b) > \hat\gamma, i = 1,2,\cdots, N

假設(shè)將wb 按比例改變?yōu)?img class="math-inline" src="https://math.jianshu.com/math?formula=%5Clambda%20w" alt="\lambda w" mathimg="1"> 和\lambda b ,此時(shí) 函數(shù)間隔將變?yōu)?\lambda \hat\gamma ,因此函數(shù)間隔 \hat \gamma 的取值對(duì)于上述最優(yōu)化問題沒有影響贡翘。

不妨取 \hat\gamma =1

意識(shí)到最大化\frac{1}{||w||} 和最小化\frac{1}{2} ||w||^2 是等價(jià)的

則上述最優(yōu)化問題 變?yōu)?/p>

min_{(w,b)} \frac{1}{2} ||w|| ^2

s.t. y_i(w·x+b)-1 \geq 0, i=1,2,\cdots,N

這是個(gè)凸二次規(guī)劃問題蹈矮。

可以采用拉格朗日乘子法,將其變換成對(duì)偶問題鸣驱。

4. 拉格朗日法求解凸二次規(guī)劃問題

定義拉格朗日函數(shù)為:

L(w, b, \alpha) = \frac{1}{2} ||w||^2 - \sum_{i =1}^{N} \alpha_i(y_i(w · x_i + b) -1)

其中

\alpha = (\alpha_1 ,\alpha_2, \cdots, \alpha_N)^T 為拉格朗日乘子向量

分別對(duì)w,b 并令其 = 0得:

\nabla _w L(w, b, \alpha) = w - \sum_{i=1}^{N}\alpha_iy_ix_i = 0

\nabla _b L(w, b, \alpha) = -\sum_{i =1}^{N}a_iy_i= 0

w = \sum_{i=1}^{N}\alpha_iy_ix_i

\sum_{i =1}^{N}a_iy_i = 0

代回拉格朗日函數(shù)

L(w,b, \alpha) =\frac{1}{2} \sum_{i=1}^{N} \sum_{j=1}^{N} \alpha_iy_ix_i \alpha_j y_j x_j - \sum_{i =1}^{N} \alpha_i(y_i(\sum_{j=1}^{N} \alpha_j y_j x_j) · x_i+ b-1)

= -\frac{1}{2} \sum_{i=1}^{N} \sum_{j=1}^{N} \alpha_iy_ix_i \alpha_j y_j x_j + \sum_{i =1}^{N} \alpha_i

即轉(zhuǎn)換后得對(duì)偶問題為

max -\frac{1}{2} \sum_{i=1}^{N} \sum_{j=1}^{N} \alpha_iy_ix_i \alpha_j y_j x_j + \sum_{i =1}^{N} \alpha_i

s.t. \sum_{i=1}^{N} \alpha_{i} y_{i} = 0

\alpha_i \geq 0, i=1,2,\cdots,N

將目標(biāo)函數(shù)由求極大轉(zhuǎn)為求極小泛鸟,得到與之等價(jià)的對(duì)偶問題為

min \frac{1}{2} \sum_{i=1}^{N} \sum_{j=1}^{N} \alpha_iy_ix_i \alpha_j y_j x_j -\sum_{i =1}^{N} \alpha_i

s.t. \sum_{i=1}^{N} \alpha_{i} y_{i} = 0

\alpha_i \geq 0, i=1,2,\cdots,N

相應(yīng)的KKT條件為:

\alpha_i \geq 0, i=1,2,\cdots,N ;

y_i(w · x_i +b -1) \geq 0;

\alpha_i(y_i (w · x_i+b) -1) = 0.

5. 軟間隔支持向量機(jī)

如果訓(xùn)練樣本含有噪聲,這個(gè)時(shí)候支持向量機(jī)可能就不存在這個(gè) 超平面可以將兩個(gè)樣本分開或者達(dá)到比較好的最大間隔踊东,為了解決這個(gè)問題引入 一個(gè)新概念:軟間隔北滥。

即:y_i(w· x_i +b) \geq 1 - \xi_ i

同時(shí)我們的約束變?yōu)?/p>

min_{(w,b)} \frac{1}{2} ||w|| ^2 + C \sum _{i=1}^{N} \xi_i

s.t. y_i(w·x+b) \geq 1-\xi_i , i=1,2,\cdots,N

? \xi_i \geq 0, i = 1,2,\cdots, N

同之前硬間隔一樣,變換為對(duì)偶問題闸翅,最后變成:

min_{\alpha} \frac{1}{2} \sum_{i=1}^{N} \sum_{j=1}^{N} \alpha_i \alpha_j y_i y_j(x_i ·x_j)-\sum_{i =1}^{N} \alpha_i

s.t. \sum_{i=1}^{N} \alpha_{i} y_{i} = 0

0 \leq \alpha_i \leq C , i=1,2,\cdots,N

所以我們只要求解滿足約束的最優(yōu)解的\alpha 出來就計(jì)算w,b 就可以找到超平面了再芋。

6. 核函數(shù)

實(shí)際上到此我們已經(jīng)掌握了SVM,但是如果我們就這樣直接去尋找最優(yōu)解坚冀,速度會(huì)非常慢, 這里的核技巧 和 后面序列最優(yōu)化算法(SMO)都是為了改善SVM的速度而提出的济赎。

min_{\alpha} \frac{1}{2} \sum_{i=1}^{N} \sum_{j=1}^{N} \alpha_i \alpha_j y_i y_j(x_i ·x_j)-\sum_{i =1}^{N} \alpha_i
s.t. \sum_{i=1}^{N} \alpha_{i} y_{i} = 0
? 0 \leq \alpha_i \leq C , i=1,2,\cdots,N

上式中x_i,x_j 均為向量,如果直接計(jì)算,對(duì)于整個(gè)訓(xùn)練集而言司训,計(jì)算起來會(huì)有巨大的時(shí)間開銷构捡,核函數(shù)可以減少這里時(shí)間開銷。

K(x , z) = \phi(x) · \phi(z) = (x, z)

即向量 x,z的點(diǎn)積 可以用K(x,z)來表示

比如高斯核:

K(x , z) =exp (- \frac{||x-z||^2}{2 \sigma ^2})

因此使用的時(shí)候我們把(x_i, x_j) 替換成K(x_i,x_j)就好

7. 序列最優(yōu)化算法

將上一部分的核函數(shù)替換掉點(diǎn)積壳猜,我們得到:

min_{\alpha} \frac{1}{2} \sum_{i=1}^{N} \sum_{j=1}^{N} \alpha_i \alpha_j y_i y_j K(x_i ·x_j)-\sum_{i =1}^{N} \alpha_i

s.t. \sum_{i=1}^{N} \alpha_{i} y_{i} = 0

0 \leq \alpha_i \leq C , i=1,2,\cdots,N

我們需要做的就是計(jì)算\alpha

由于\alpha = \{\alpha_1, \alpha_2, \cdots, \alpha_N\} ,直接求解N個(gè)未知量難度很大

序列最優(yōu)化算法就是為了解決這個(gè)問題勾徽。

其核心思想就是,先將\alpha_1蓖谢,\alpha_2視為變量, 將其他的\alpha_i全部當(dāng)成參數(shù)捂蕴,然后迭代使得\alpha_1滿足KKT條件。

由第一個(gè)約束有: \alpha_1 = - \frac{1}{y_1} \sum_{i = 2}^{N} \alpha_i y_i

所以將原式中的變量\alpha_1, \alpha_2顯式寫出闪幽,最終整理得如下:

min_{(\alpha_1,\alpha_2)} \frac{1}{2} K_{11} \alpha_1^2 +\frac{1}{2} K_{22} \alpha_2^2 + y_1y_2K_{22} \alpha_1\alpha_2 - (\alpha_1+\alpha_2) + y_1\alpha_1 \sum_{i=3}^{N} y_i \alpha_i K_{i1} + y_2\alpha_2 \sum_{i=3}^{N} y_i \alpha_i K_{i2}

s.t. \alpha_1 y_1+ \alpha_2 y_2 = \sum_{i=3}^{N} y_i \alpha_i = \zeta

0 \leq \alpha_i \leq C, i =1, 2

根據(jù)書中表述啥辨,假設(shè)上述問題得初始可行解為(\alpha_1^{old}, \alpha_2^{old}) ,最優(yōu)解為(\alpha_1^{new}, \alpha_2^{new}),則有:

L \leq \alpha_2^{new} \leq H

其中LH\alpha_2^{new} 所在對(duì)角線端點(diǎn)的界盯腌。

如果y_1 \neq y_2 \Rightarrow \alpha_1 -\alpha_2 = kL = max(0, \alpha_2^{old} - \alpha_1^{old}), H=min(C,C+\alpha_2^{old} - \alpha_1^{old})

如果y_1 = y_2 \Rightarrow \alpha_1 +\alpha_2 = k,則 L = max(0, \alpha_2^{old} + \alpha_1^{old}-C), H=min(C,\alpha_2^{old} + \alpha_1^{old})

假設(shè)在沿著約束方向未剪輯時(shí)\alpha_2的最優(yōu)解為\alpha^{new,unc}

為了表示\alpha^{new} ,記g(x) = \sum_{i=1}^{N} \alpha_i y_i K(x_i, x) + b溉知, E_i = g(x_i) - y_i, i=1,2

8.變量的選擇方法

第一個(gè)變量的選擇

從訓(xùn)練樣本中選擇違反KKT條件最嚴(yán)重的點(diǎn) 即檢查KKT條件

第二個(gè)變量的選擇

選擇最大化|E_1- E_2|的點(diǎn)。

9. python代碼實(shí)現(xiàn)

實(shí)現(xiàn)遵循文中表述

import time
import numpy as np
import math
import random

'''
數(shù)據(jù)集: MNIST
訓(xùn)練集大小: 60000(實(shí)際使用1000)
測(cè)試集大小: 10000(實(shí)際使用100)
-----
運(yùn)行結(jié)果:

the accuracy is : 0.92
time span: 62.679516553878784 s
'''


def loadData(fileName):
    '''
    加載數(shù)據(jù)集
    :param fileName: 文件路徑
    :return: dataList腕够,labelList分別為特征集X和標(biāo)記Y. 均為list

    '''
    dataList = []  #
    labelList = []

    f = open(fileName, 'r')

    for line in f.readlines():
        curline = line.strip().split(',')
        '''
        這里考慮到我用的文件是csv格式级乍,所以用split(',')

        Mnsit有0-9十個(gè)標(biāo)記
        文件每行開頭第一個(gè)數(shù)字為該行的label標(biāo)記
        這里為了簡(jiǎn)化,限定二分類任務(wù)帚湘,所以將標(biāo)記0的作為1(正例)玫荣,其余為0(反例)
        '''
        if (int(curline[0]) == 0):
            labelList.append(1)
        else:
            labelList.append(0)

        '''
        加入特征集X
        由于開頭第一個(gè)數(shù)字為標(biāo)記,故從下標(biāo) 1 開始
        這里轉(zhuǎn)為int類型
        /255 是為了歸一化大诸,有效減少數(shù)字爆炸捅厂。
        '''
        dataList.append([int(num) / 255 for num in curline[1:]])

    # 讀取完畢關(guān)閉文件
    f.close()

    # 返回?cái)?shù)據(jù)集和標(biāo)記
    return dataList, labelList

class SVM_CLF:
    def __init__(self, X_train,y_train, sigma = 10, C = 200, toler = 0.001):
        """
        相關(guān)參數(shù)初始化
        :param X_train: 訓(xùn)練數(shù)據(jù)集
        :param y_train: 訓(xùn)練數(shù)據(jù)集標(biāo)記
        :param sigma: 高斯核中的\sigma
        :param C: 懲罰項(xiàng)系數(shù)
        :param toler: 松弛變量
        """
        self.trainData = np.mat(X_train)
        self.trainLabel = np.mat(y_train).T
        self.m, self.n = np.shape(self.trainData) #訓(xùn)練及大小,循環(huán)中會(huì)用到
        self.sigma = sigma                        #高斯核參數(shù)
        self.C = C
        self.toler = toler
        self.k = self.calcKernel()                 #初始化時(shí)提前計(jì)算高斯核
        self.b = 0                                #初始化偏置項(xiàng)為0
        self.alpha = [0] * self.m
        self.E = [0 * self.trainLabel[i,0] for i in range(self.m)]
        self.supportVectorIndex = []


    def calcKernel(self):
        """
        計(jì)算核函數(shù)资柔,本例使用的是高斯核
        :return: 高斯核矩陣
        """
        #初始化高斯核矩陣 大小=[m * m] 焙贷,m為訓(xùn)練集樣本數(shù)量
        k_matrix = np.zeros((self.m, self.m))
        for i in range(self.m):
            X = self.trainData[i,:]
            for j in range(i, self.m):
                Z = self.trainData[j,:]
                XZ = (X - Z) * (X - Z).T
                result = np.exp(-1 * XZ / (2 * self.sigma **2))
                k_matrix[i][j] = result
                k_matrix[j][i] = result

        return k_matrix

    def isSatisfyKKT(self, i):
        """
        判斷alpha i 是否符合KKT條件
        i為下標(biāo)
        :return: True (滿足)或者 False (不滿足)
        """
        gxi = self.calc_gxi(i)
        yi = self.trainLabel[i]
        if (math.fabs(self.alpha[i] < self.toler)) and (yi * gxi >= 1):
            return True
        elif(math.fabs(self.alpha[i] - self.C) < self.toler) and (yi * gxi )<=1:
            return True
        elif(math.fabs(self.alpha[i]) > -self.toler) and (self.alpha[i] < self.C)\
            and (math.fabs(yi * gxi) - 1) < self.toler:
            return True
        return False

    def calc_gxi(self, i):
        gxi = 0
        index = [i for i,alpha in enumerate(self.alpha) if alpha != 0]
        for j in index:
            gxi += self.alpha[j] * self.trainLabel[j] * self.k[j][i]

        gxi += self.b

        return gxi

    def calc_EI(self, i):
        '''
        計(jì)算Ei
        根據(jù)書中章節(jié)7.4.1 兩個(gè)變量二次規(guī)劃的求解方法 中 式7.105
        :param i: E的下標(biāo)
        :return: E2,和下標(biāo)
        '''
        gxi = self.calc_gxi(i)
        return gxi - self.trainLabel[i]

    def get_Alpha2(self, E1, i):
        '''
        選擇第二個(gè)alpha
        :param E1:
        :param i:
        :return:
        '''
        E2 = 0
        maxE1_E2 = -1
        E2_index = -1

        noZero_E = [i for i ,Ei in enumerate(self.E) if Ei != 0]
        for j in noZero_E:
            E2_tmp = self.calc_EI(j)

            if (math.fabs(E1 - E2_tmp) > maxE1_E2):
                maxE1_E2 = math.fabs(E1 - E2_tmp)
                E2 = E2_tmp
                E2_index = j

            if E2_index == -1:
                E2_index = i
                while E2_index == i:

                    E2_index = random.randint(0, self.m)
                E2 = self.calc_EI(E2_index)

            return E2, E2_index


    def train(self, Maxiter = 100):
        '''
        用訓(xùn)練數(shù)據(jù)集學(xué)習(xí)模型
        :param Maxiter: 最大迭代次數(shù)
        :return: w, b

        '''
        iterstep = 0
        is_Alpha_changed = 1
        while(iterstep < Maxiter) and (is_Alpha_changed > 0):

            print('iterstep:%d:%d'%(iterstep, Maxiter))

            iterstep += 1
            is_Alpha_changed = 0
            for i in range(self.m):
                if self.isSatisfyKKT(i) == False:
                    E1 = self.calc_EI(i)
                    E2, j = self.get_Alpha2(E1, i )

                    y1 = self.trainData[i]
                    y2 = self.trainLabel[j]

                    alpha_old_1 = self.alpha[i]
                    alpha_old_2 = self.alpha[j]

                    if y1 != y2:
                        L = max(0, alpha_old_2 - alpha_old_1)
                        H = min(self.C, self.C+ alpha_old_2 - alpha_old_1)

                    else:
                        L = max(0, alpha_old_2 + alpha_old_1 - self.C)
                        H = min(self.C, alpha_old_2 + alpha_old_1)
                    #如果L 和 H相等 贿堰,說明變量無法優(yōu)化辙芍, 直接跳過
                    if L == H: continue

                    #根據(jù)書中式7.106
                    # 計(jì)算alpha的新值
                    K11 = self.k[i][i]
                    K22 = self.k[j][j]
                    K12 = self.k[i][j]

                    alpha_new_2 = alpha_old_2 + y2 * (E1 - E2) / (k11 + k22 - 2 * k12)
                    #剪切alpha2
                    if alpha_new_2 < L : alpha_new_2 = L
                    elif alpha_new_2 > H: alpha_new_2 = H

                    #根據(jù) 7.109式 更新alpha1
                    alpha_new_1 = alpha_old_1 + y1 * y2 * (alpha_old_2 - alpha_new_2)

                    #根據(jù)書中“7.4.2 變量的選擇方法” 第三步式 7.115 和 7.116
                    b1_new = -E1 - y1 * K11 * (alpha_new_1 - alpha_old_1) \
                             - y2* K21 * (alpha_new_2 - alpha_old_2) + self.b
                    b2_new = -E2 - y1 * K12 * (alpha_new_1 - alpha_old_1) \
                             - y2* K22 * (alpha_new_2 - alpha_old_2) + self.b
                    if(alpha_new_1 > 0) and (alpha_new_1 < self.C):
                        b_new = b1_new
                    elif(alpha_new_2 > 0) and (alpha_new_2 < self.C):
                        b_new = b2_new
                    else:
                        b_new = (b1_new + b2_new) / 2

                    #將各參數(shù)更新
                    self.alpha[i] = alpha_new_1
                    self.alpha[j] = alpha_new_2
                    self.b = b_new

                    self.E[i] = self.calc_EI(i)
                    self.E[j] = self.calc_EI(j)

                    if math.fabs(alpha_new_2 - alpha_old_2) > 0.0001:
                        is_Alpha_changed += 1

                    #print("iter: %d i: %d, pairs changed %d" %(iterstep, i, is_Alpha_changed))

                    #全部計(jì)算結(jié)束后遍歷一遍alpha ,找出支持向量。
                    for i in range(self.m):

                        if self.alpha[i] > 0:
                            self.supportVectorIndex.append(i)


    def calc_Single_Kernel(self, x1, x2):
        '''
        單獨(dú)計(jì)算核函數(shù)
        在predict的時(shí)候用到

        :param x1:
        :param x2:
        :return:
        '''
        x1_x2 = (x1 - x2) * (x1 - x2).T
        result = np.exp(- x1_x2 / (2 * self.sigma ** 2))
        return result

    def predict(self, x):
        '''
        預(yù)測(cè)樣本
        :param x: 預(yù)測(cè)的樣本
        :return: 預(yù)測(cè)結(jié)果
        '''

        result = 0
        for i in self.supportVectorIndex:
            tmp = self.calc_Single_Kernel(np.mat(x), self.trainData[i,:])
            result += self.alpha[i] * self.trainLabel[i] * tmp

        result += self.b

        return np.sign(result)

    def test(self, testData, testLabel):
        '''
        測(cè)試測(cè)試集
        :param testData: 測(cè)試數(shù)據(jù)集
        :param testLabel: 測(cè)試標(biāo)記集
        :return:  正確率

        '''
        errorCount = 0
        for i in range(len(testData)):
            print('testing : %d: %d'%(i, len(testData)))

            result = self.predict(testData[i])
            if result != testLabel[i]:
                errorCount += 1

        return 1 - errorCount/len(testLabel)


if __name__ == '__main__':
    start = time.time()

    print('read trainSet')
    trainData, trainLabel = loadData('D:/PythonLearn/MLA/mnist_train.csv')

    print('read testSet')
    testData, testLabel = loadData('D:/PythonLearn/MLA/mnist_test.csv')

    print('init SVM ')
    svm = SVM_CLF(trainData[:1000], trainLabel[:1000], sigma=10, C = 200,toler = 0.001)

    print('training')
    svm.train()

    print('testing')
    accuracy = svm.test(testData[:100], testLabel[:100])

    end = time.time()

    print('the accuracy is :', accuracy)
    print('time span:', end - start, 's')
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末羹与,一起剝皮案震驚了整個(gè)濱河市故硅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纵搁,老刑警劉巖吃衅,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異诡渴,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門妄辩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來惑灵,“玉大人,你說我怎么就攤上這事眼耀∮⒅В” “怎么了?”我有些...
    開封第一講書人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵哮伟,是天一觀的道長(zhǎng)干花。 經(jīng)常有香客問我,道長(zhǎng)楞黄,這世上最難降的妖魔是什么池凄? 我笑而不...
    開封第一講書人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮鬼廓,結(jié)果婚禮上肿仑,老公的妹妹穿的比我還像新娘。我一直安慰自己碎税,他們只是感情好尤慰,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著雷蹂,像睡著了一般伟端。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上匪煌,一...
    開封第一講書人閱讀 51,698評(píng)論 1 305
  • 那天责蝠,我揣著相機(jī)與錄音,去河邊找鬼虐杯。 笑死玛歌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的擎椰。 我是一名探鬼主播支子,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼达舒!你這毒婦竟也來了值朋?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤巩搏,失蹤者是張志新(化名)和其女友劉穎昨登,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贯底,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡丰辣,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年撒强,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片笙什。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡飘哨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出琐凭,到底是詐尸還是另有隱情芽隆,我是刑警寧澤,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布统屈,位于F島的核電站胚吁,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏愁憔。R本人自食惡果不足惜腕扶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望惩淳。 院中可真熱鬧蕉毯,春花似錦、人聲如沸思犁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)激蹲。三九已至棉磨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間学辱,已是汗流浹背乘瓤。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留策泣,地道東北人衙傀。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像萨咕,于是被迫代替她去往敵國(guó)和親统抬。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355