(二十七)項目實戰(zhàn)|交易數據異常檢測(二)-python數據分析與機器學習實戰(zhàn)(學習筆記)

文章原創(chuàng),最近更新:2018-06-4

1.交叉驗證
2.模型評估方法
3.正則化懲罰
4.邏輯回歸模型
課程來源: python數據分析與機器學習實戰(zhàn)-唐宇迪

課程資料:這里所涉及到的練習資料creditcard.csv相關的鏈接以及密碼如下:
鏈接: https://pan.baidu.com/s/1APgU4cTAaM9zb8_xAIc41Q 密碼: xgg7

1.交叉驗證

這節(jié)課的主要內容是交叉驗證的學習.首先要了解交叉驗證,具體如下:

  • 什么是交叉驗證法但指?

在建立分類模型時,交叉驗證(Cross Validation)簡稱為CV抗楔,CV是用來驗證分類器的性能棋凳。它的主體思想是將原始數據進行分組,一部分作為訓練集连躏,一部分作為驗證集剩岳。利用訓練集訓練出模型,利用驗證集來測試模型入热,以評估分類模型的性能拍棕。

訓練數據上的誤差叫做訓練誤差,它對算法模型的評價過于樂觀勺良。利用測試數據測量的是測試誤差绰播,我門報告的是測試誤差。有的時候訓練集上的正確率可能達到100%郑气,但是在測試集上可能和隨機猜測差不多幅垮。

  • 為什么用交叉驗證法?

交叉驗證用于評估模型的預測性能尾组,尤其是訓練好的模型在新數據上的表現忙芒,可以在一定程度上減小過擬合。
還可以從有限的數據中獲取盡可能多的有效信息讳侨。

  • 交叉驗證常用的幾種方法:

    • 1.去一法 Leave-One-Out Cross Validation(記為LOO-CV)**
      它的做法是呵萨,從訓練集中拿出一個樣本,并在缺少這個樣本的數據上訓練出一個模型跨跨,然后看模型是否能對這個樣本正確分類潮峦。假設樣本個數有N個囱皿,則該方法一共要訓練出N個模型,利用這N個模型最終的驗證集的分類準確率的平均數作為此下LOO-CV分類器的性能指標忱嘹。然而隨著數據量的增大嘱腥,工作量會劇增,在時間是處于劣勢拘悦。但是它具有顯著德爾優(yōu)點:
      1)每一回合中幾乎所有的樣本皆用于訓練模型,因此最接近原始樣本的分布,這樣評估所得的結果比較可靠齿兔。
      2)實驗過程中沒有隨機因素會影響實驗數據,確保實驗過程是可以被復制的。

    • 2础米、k折交叉驗證 K-fold Cross Validation(記為K-CV)
      K折交叉驗證是以部分代價去獲得去一法的大部分收益分苇,這里的k折是吧數據分為k組。它的做法是將k-1組作為訓練集訓練出一個模型屁桑,然后將剩下的一組用做測試集医寿。利用這k個模型最終的平均正確率來衡量模型的正確率。常使用的一般是5折10折蘑斧,5折交叉驗證是將數據分為5組靖秩。實際做法是把20%的數據拿出去作為測試集,將剩下的80%數據訓練模型乌叶。使用80%或者90%的數據與使用所有數據的效果比較接近盆偿。
      使用交叉驗證時,需要謹慎保持數數據的分布平衡准浴,不能在某一折中全部是一類的數據事扭。

學習參考鏈接:
1、為什么要用交叉驗證
2乐横、一篇文章,帶你明白什么是過擬合,欠擬合以及交叉驗證


比如有個集合叫data求橄,通常建立機器模型的時候,先對數據進行切分或者選擇葡公,取前面80%的數據當成訓練集罐农,取20%的數據當成測試集。80%的數據是來建立一個模型催什,剩下的20%的數據是用來測試模型的表達效果是怎么樣的涵亏?

  • 因此第一步是將數據進行切分,切分成訓練集以及測試集蒲凶。這部分操作是必須要做的气筋。
  • 第二步還要在訓練集進行平均切分,比如平均切分成3份旋圆,分別是數據集1,2,3宠默。為什么要進行隨機的切分呢?因為最終的測試數據集灵巧,只能夠在一個最終的測試階段搀矫,在模型以及參數都調整好之后抹沪,才能用測試集去測試當前模型的效果是怎么樣的?

在建立模型的時候瓤球,不管建立什么樣的模型融欧,這個模型伴隨著很多參數,有不同的參數進行選擇冰垄,這個參數選擇大比較好蹬癌,還是選擇小比較好一些?從經驗值角度來說虹茶,肯定沒辦法很準的,怎么樣去確定這個參數呢隅要?只能通過交叉驗證的方式蝴罪。

那什么又叫交叉驗證呢?

  • 第一次:將數據集1,2分別建立模型步清,用數據集3在當前權重下一個驗證的效果要门。數據集3是個驗證集,驗證集是訓練集的一部分廓啊。用驗證集去收集模型是好還是壞欢搜?
  • 第二次:將數據集1,3分別建立模型,用數據集2在當前權重下一個驗證的效果谴轮。
  • 第三次:將數據集2,3分別建立模型炒瘟,用數據集1在當前權重下一個驗證的效果。

為什么要驗證模型3次呢第步?其實這些操作并非是重復的疮装,每一次的訓練集是不一樣的。(比如第一次的訓練集是1和2粘都,第二次的訓練集是1和3廓推,第三次的訓練集是3和2)此外驗證集也是不一樣的。(比如第一次的驗證集是3翩隧,第二次的驗證集是2樊展,第三次的驗證集是1)

現在是比較求穩(wěn)的操作,如果只是求一次的交叉驗證堆生,這樣的操作會存在風險专缠。比如只做第一次交叉驗證,會使3驗證集偏簡單一些顽频。會使模型效果偏高藤肢,此外模型有些數據是錯誤值以及離群值,如果把這些不太好的數據當成驗證集糯景,會使模型的效果偏低的嘁圈。模型當然是不希望偏高也不希望偏低省骂,那就需要多做幾次交叉驗證模型,求平均值最住。這里有1钞澳,2,3分別求驗證集涨缚,每個驗證集都有評估的標準轧粟。最終模型的效果將1,2,3的評估效果加在一起,再除以3,就可以得到模型一個大致的效果脓魏。

交叉驗證只是做一步求穩(wěn)的操作兰吟,要讓模型的評估效果是可信的。既不能偏高也不能偏低茂翔,就這樣求了平均值來當模型的效果混蔼。

之前說到要做數據交叉驗證,要對原始數據集進行切分珊燎。

  • sklearn.cross_validation是交叉驗證模塊惭嚣,train_test_split對原始數據集有進行切分的操作。
  • test_size = 0.3實際做法是把30%的數據拿出去作為測試集悔政,將剩下的70%數據訓練模型晚吞。這個可以根據實際需求進行修改。
  • random_state = 0谋国,為了使訓練集以及測試集一樣槽地,設置隨機狀態(tài)為0,這樣就拋開了樣本對模型的影響烹卒。(之前有對原始數據集進行洗牌闷盔,再切分測試集以及訓練集,才能保證隨機切分旅急。)
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size = 0.3, random_state = 0)

之前做了下采樣的數據集逢勾,讓0和1都比較少,要對下采樣數據集進行的交叉切分相同的操作藐吮。

X_train_undersample, X_test_undersample, y_train_undersample, y_test_undersample = train_test_split(X_undersample
                                                                                                   ,y_undersample
                                                                                                   ,test_size = 0.3
                                                                                                   ,random_state = 0)

為什么同時要對下采樣以及原始的數據進行交叉切分呢?

現在要拿下采樣的數據進行模型訓練的操作,但是模型訓練完要進行測試,那么測試的時候拿什么數據集進行測試呢?是拿下采樣切分的測試數據集進行測試么?二下采樣切分的測試數據數量比較少,而且也是下采樣的測試數據集,不具備原始數據的分布規(guī)則.最終的測試集是拿原始數據集中的測試數據集再進行測試.

因此這里有2種切分的方式,第一種是對原始數據集即28萬個數據進行交叉切分.然后有對984個下采樣數據集又進行了一次交叉切分,

from sklearn.cross_validation import train_test_split

# Whole dataset
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size = 0.3, random_state = 0)

print("Number transactions train dataset: ", len(X_train))
print("Number transactions test dataset: ", len(X_test))
print("Total number of transactions: ", len(X_train)+len(X_test))

# Undersampled dataset
X_train_undersample, X_test_undersample, y_train_undersample, y_test_undersample = train_test_split(X_undersample
                                                                                                   ,y_undersample
                                                                                                   ,test_size = 0.3
                                                                                                   ,random_state = 0)
print("")
print("Number transactions train dataset: ", len(X_train_undersample))
print("Number transactions test dataset: ", len(X_test_undersample))
print("Total number of transactions: ", len(X_train_undersample)+len(X_test_undersample))

輸出結果如下:

Number transactions train dataset:  199364
Number transactions test dataset:  85443
Total number of transactions:  284807

Number transactions train dataset:  688
Number transactions test dataset:  296
Total number of transactions:  984

后面會拿原始數據中的85443的數據集進行測試操作,而下采樣的數據總共有984個,訓練集的數據共有668個,測試集有296個,上面已經將數據集進行了切分,就可以進行建模的操作,在建模的過程中要使用邏輯回歸.

2.模型評估方法

假設有1000個病人的數據,要對1000個病人進行分類,有哪些是癌癥的?哪些不是患有癌癥的?

假設有990個人不患癌癥,10個人是患癌癥.用一個最常見的評估標準,比方說精度,就是真實值與預測值之間的差異.真實值用y來表示,預測值用y1來表示.y真實值1,2,3...10,共有10個樣本,y1預測值1,2,3...10,共有10個樣本.精度就是看真實值y與預測值y1是否一樣的.要么都是0,要么都是1,如果是一致,就用=表示,比如1號真實值樣本=預測值的1號樣本,如果不相等就用不等號來表示.如果等號出現了8個,那么它的精確度為8/10=80%,從而確定模型的精度.

990個人不患癌癥,10個人是患癌癥建立一個模型,所有的預測值都會建立一個正樣本.對1000個樣本輸入到模型,它的精確度是多少呢?990/1000=99%
這個模型把所有的值都預測成正樣本,但是沒有得到任何一個負樣本.在醫(yī)院是想得到癌癥的識別,但是檢查出來的結果是0個,雖然精度達到了99%,
但這個模型是沒有任何的含義的,因為一個癌癥病人都找不出來.在建立模型的時候一定要想好一件事,模型雖然很容易建立出來,那么難點是應該怎么樣去評估這樣的模型呢?

剛才提到了用精度去評估模型,但是精度有些時候是騙人的.尤其是在樣本數據不均衡的情況下.

接下來要講到一個知識點叫recall,叫召回率或叫查全率.recall有0或者1,我們的目標是找出患有癌癥的那10個人.因此根據目標制定衡量的標準.就是有10個癌癥病人,能夠檢測出來有幾個?如果檢測0個癌癥病人,那么recall值就是0/10=0;如果檢測2個癌癥病人,那么recall值就是2/10=20%.用recall檢測模型的效果更科學一些.

建立模型無非是選擇一些參數,如果精度專用recall來表示,也并非那么容易.在統(tǒng)計學中會經常提到的4個詞,分別如下:


比如一個班級有80個男生,20個女生,共100個人,在100多個人中有個目標,把所有的女生都抓出來.建立一個模型,挑選50個人,預測結果是20個是女的,剩下30個是男的.

  • TP:表示預測對的正例結果,比如判斷成正例,20個女生,當成正例.
  • FP:表示預測錯的正例結果,把負例判斷成正例,比如把男生判斷成女生,共有30個.
  • FN:就是把女生錯當成男生的例子為0個.
  • TN:就是把男生判斷成了男生,因此等于50.

這里的Recall = TP/(TP+FN)

3.正則化懲罰

先導入機器學習建模的庫

from sklearn.linear_model import LogisticRegression
from sklearn.cross_validation import KFold, cross_val_score
from sklearn.metrics import confusion_matrix,recall_score,classification_report 
  • from sklearn.linear_model import LogisticRegression邏輯回歸

  • from sklearn.cross_validation import KFold, cross_val_score,

    • 這里的KFold是指交叉驗證的時候,可以選擇做幾倍的交叉驗證.之前有提到將原始的訓練集切分成3份,不光可以切分成3份,也可以切分成4份或者5份都可以的,可以根據自己的喜好,任意的切分.
    • cross_val_score值是指交叉驗證評估得到的結果,
  • from sklearn.metrics import confusion_matrix,recall_score,classification_report

    • confusion_matrix是混淆矩陣

在機器建模的時候需要做這樣的一件事,要做交叉驗證,要把原始的數據集切分成幾部分,fold = KFold(len(y_train_data),5,shuffle=False) ,這里將原始數據傳進來,并切分成了5部分.

在邏輯回歸當中,需要有寫參數傳進來,今天的參數叫做正則化懲罰項,什么叫正則化懲罰?

比如有A模型:?1溺拱、?2、?3...?10谣辞,比如還有B模型:?1迫摔、?2、?3...?10泥从,這兩個模型的recall值都是等于90%句占。如果兩個模型的recall值都是等于90%,是不是隨便選一個都可以呢躯嫉?
比如A模型的原點浮動比較大纱烘,具體如截圖:



比如B模型的原點浮動比較小杨拐,具體如截圖:


雖然兩個模型的recall值都是等于90%,A模型的浮動范圍太大了擂啥,都希望模型更加穩(wěn)定一些哄陶,不光滿足訓練的數據,還要盡可能的滿足測試數據哺壶。因此希望模型的浮動差異更小一些屋吨,差異小可以使過度擬合的風險更小一些。

過度擬合的意思是在訓練集表達效果很好,但是在測試集表達效果很差,因此這組模型發(fā)生了過擬合。過擬合是非常常見的現象,很大程度上是因為權重參數浮動較大引起的乘陪,因此希望得到B模型,因為B模型的浮動差異比較小。

那么怎么樣能夠得到B模型呢沙廉?從而就引入了正則化的東西,懲罰模型的?胖翰,因為模型的數據有時候分布大接剩,有時候分布小。希望大力度懲罰A模型萨咳,小力度懲罰B模型懊缺,可不可以呢?

  • L2正則化

首先介紹一些L2正則化培他,對于目標損失函數來說鹃两,希望目標函數是越低越好的,在懲罰的過程中舀凛,需要在(loss)損失目標函數中+1/2w*w俊扳,即就是如下截圖:


對于A模型,w值浮動比較大猛遍,如果計算w*w的話馋记,這樣的話計算的目標損失函數的值就會更大。對于B模型而言懊烤,計算的目標損失函數的值也是如此梯醒。

分別計算A、B模型中的loss+1/2w*w中的值腌紧,哪個值更加低茸习?

  • L1正則化

(loss)損失目標函數中+|w|,去計算當前的懲罰力度是多少壁肋?

因此有兩種懲罰函數号胚,一種是L2正則化籽慢,一種是L1正則化。

在判斷之前需要設置好參數涕刚,需要設置當前懲罰的力度有多大嗡综?可以設置成0.1懲罰力度比較小,也可以設置懲罰力度為1杜漠,也可以設置懲罰力度為10极景。但是懲罰力度等于多少的時候,效果比較好呢驾茴?具體多少也不知道盼樟,需要通過交叉驗證,去評估一下什么樣的參數達到更好的效果锈至。

c_param_range = [0.01,0.1,1,10,100]這里就是前面提到的那一章的懲罰力度晨缴。需要將這5個參數不斷的嘗試。

這一部分內容是可視化顯示峡捡,具體如下:

    results_table = pd.DataFrame(index = range(len(c_param_range),2), columns = ['C_parameter','Mean recall score'])
    results_table['C_parameter'] = c_param_range

在循環(huán)里面利用懲罰力度的參數,看一下那個參數的取值效果更好.

    for c_param in c_param_range:
        print('-------------------------------------------')
        print('C parameter: ', c_param)
        print('-------------------------------------------')
        print('')

下面的循環(huán)是對數據進行交叉驗證,具體如下:

  • lr = LogisticRegression(C = c_param, penalty = 'l1')首先建立邏輯回歸模型,在邏輯回歸函數,傳進C這個懲罰力度參數.懲罰的方式可以選擇l1懲罰或者l2懲罰.

  • lr.fit(x_train_data.iloc[indices[0],:],y_train_data.iloc[indices[0],:].values.ravel())這個語句是對模型進行訓練,用交叉驗證的方式建立一個模型.

  • y_pred_undersample = lr.predict(x_train_data.iloc[indices[1],:].values),建立完模型之后就可以進行預測.

  • 比如在C=0的情況下,它的效果是多少的?并計算recall的值,

recall_acc = recall_score(y_train_data.iloc[indices[1],:].values,y_pred_undersample)
            recall_accs.append(recall_acc)
            print('Iteration ', iteration,': recall score = ', recall_acc)

4.邏輯回歸模型

完整的案例代碼如下:

def printing_Kfold_scores(x_train_data,y_train_data):
    fold = KFold(len(y_train_data),5,shuffle=False) 

    # Different C parameters
    c_param_range = [0.01,0.1,1,10,100]

    results_table = pd.DataFrame(index = range(len(c_param_range),2), columns = ['C_parameter','Mean recall score'])
    results_table['C_parameter'] = c_param_range

    # the k-fold will give 2 lists: train_indices = indices[0], test_indices = indices[1]
    j = 0
    for c_param in c_param_range:
        print('-------------------------------------------')
        print('C parameter: ', c_param)
        print('-------------------------------------------')
        print('')


        recall_accs = []
        for iteration, indices in enumerate(fold,start=1):

            # Call the logistic regression model with a certain C parameter
            lr = LogisticRegression(C = c_param, penalty = 'l1')

            # Use the training data to fit the model. In this case, we use the portion of the fold to train the model
            # with indices[0]. We then predict on the portion assigned as the 'test cross validation' with indices[1]
            lr.fit(x_train_data.iloc[indices[0],:],y_train_data.iloc[indices[0],:].values.ravel())

            # Predict values using the test indices in the training data
            y_pred_undersample = lr.predict(x_train_data.iloc[indices[1],:].values)

            # Calculate the recall score and append it to a list for recall scores representing the current c_parameter
            recall_acc = recall_score(y_train_data.iloc[indices[1],:].values,y_pred_undersample)
            recall_accs.append(recall_acc)
            print('Iteration ', iteration,': recall score = ', recall_acc)

        # The mean value of those recall scores is the metric we want to save and get hold of.
        results_table.ix[j,'Mean recall score'] = np.mean(recall_accs)
        j += 1
        print('')
        print('Mean recall score ', np.mean(recall_accs))
        print('')

best_c = printing_Kfold_scores(X_train_undersample,y_train_undersample)

輸出結果如下:

-------------------------------------------
C parameter:  0.01
-------------------------------------------

Iteration  1 : recall score =  0.958904109589
Iteration  2 : recall score =  0.917808219178
Iteration  3 : recall score =  1.0
Iteration  4 : recall score =  0.972972972973
Iteration  5 : recall score =  0.954545454545

Mean recall score  0.960846151257

-------------------------------------------
C parameter:  0.1
-------------------------------------------

Iteration  1 : recall score =  0.835616438356
Iteration  2 : recall score =  0.86301369863
Iteration  3 : recall score =  0.915254237288
Iteration  4 : recall score =  0.932432432432
Iteration  5 : recall score =  0.878787878788

Mean recall score  0.885020937099

-------------------------------------------
C parameter:  1
-------------------------------------------

Iteration  1 : recall score =  0.835616438356
Iteration  2 : recall score =  0.86301369863
Iteration  3 : recall score =  0.966101694915
Iteration  4 : recall score =  0.945945945946
Iteration  5 : recall score =  0.893939393939

Mean recall score  0.900923434357

-------------------------------------------
C parameter:  10
-------------------------------------------

Iteration  1 : recall score =  0.849315068493
Iteration  2 : recall score =  0.86301369863
Iteration  3 : recall score =  0.966101694915
Iteration  4 : recall score =  0.959459459459
Iteration  5 : recall score =  0.893939393939

Mean recall score  0.906365863087

-------------------------------------------
C parameter:  100
-------------------------------------------

Iteration  1 : recall score =  0.86301369863
Iteration  2 : recall score =  0.86301369863
Iteration  3 : recall score =  0.966101694915
Iteration  4 : recall score =  0.959459459459
Iteration  5 : recall score =  0.893939393939

Mean recall score  0.909105589115

*********************************************************************************
Best model to choose from cross validation is with C parameter =  0.01
*********************************************************************************

C parameter是懲罰力度參數,從這里可以看出哪些recall值比較低?哪些recall值比較高?希望找出較高模型的參數,這個數值是其中一個5倍交叉驗證的結果值,具體如下:

Iteration  1 : recall score =  0.849315068493
Iteration  2 : recall score =  0.86301369863
Iteration  3 : recall score =  0.966101694915
Iteration  4 : recall score =  0.959459459459
Iteration  5 : recall score =  0.893939393939

通過結果可以看出,當懲罰參數是0.01,recall的值最高.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末击碗,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子们拙,更是在濱河造成了極大的恐慌稍途,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件砚婆,死亡現場離奇詭異械拍,居然都是意外死亡,警方通過查閱死者的電腦和手機装盯,發(fā)現死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門坷虑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人埂奈,你說我怎么就攤上這事迄损。” “怎么了挥转?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵海蔽,是天一觀的道長。 經常有香客問我绑谣,道長党窜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任借宵,我火速辦了婚禮幌衣,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己豁护,他們只是感情好哼凯,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著楚里,像睡著了一般断部。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上班缎,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天蝴光,我揣著相機與錄音,去河邊找鬼达址。 笑死蔑祟,一個胖子當著我的面吹牛,可吹牛的內容都是我干的沉唠。 我是一名探鬼主播疆虚,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼满葛!你這毒婦竟也來了径簿?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤嘀韧,失蹤者是張志新(化名)和其女友劉穎牍帚,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體乳蛾,經...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年肃叶,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片十嘿。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡因惭,死狀恐怖,靈堂內的尸體忽然破棺而出绩衷,到底是詐尸還是另有隱情蹦魔,我是刑警寧澤,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布咳燕,位于F島的核電站勿决,受9級特大地震影響,放射性物質發(fā)生泄漏招盲。R本人自食惡果不足惜低缩,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧咆繁,春花似錦讳推、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至坏为,卻和暖如春究驴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背久脯。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工纳胧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人帘撰。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓跑慕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親摧找。 傳聞我的和親對象是個殘疾皇子核行,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內容