日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【机器学习基础】xgboost系列丨xgboost建树过程分析及代码实现

發(fā)布時間:2025/3/12 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【机器学习基础】xgboost系列丨xgboost建树过程分析及代码实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前面我們通過對論文中的公式詳細解讀,一步步推導(dǎo)了XGBoost的優(yōu)化目標以及建樹方法。下面我們就來動手實踐,拿真實的數(shù)據(jù)來手動計算,并且使用python來實現(xiàn)一個簡易的XGBoost。

01?

手動計算還原xgboost的過程

XGBoost的建樹過程包括下面幾個關(guān)鍵步驟。

  • 計算分裂前樣本的G,H(每個樣本的g,h求和)

  • 貪心枚舉每個特征每個值做為分隔條件

  • 計算分隔后左右節(jié)點的G_l,H_l,G_r,H_r,算出Gain

  • 更新最大增益Gain_max,更新分隔點。

  • 最終得到最優(yōu)分隔點。

  • 根據(jù)上述過程遞歸建樹直到終止條件。

  • 計算葉節(jié)點的權(quán)重w

  • 在建完一個樹后,再建下棵樹時,注意G/H/Gain的計算用到的預(yù)測值要進行更新,對之前的所有樹的預(yù)測值求和可以得到建下棵樹時的。

    這里我們使用一個簡單的UCI數(shù)據(jù)集?:

    http://archive.ics.uci.edu/ml/datasets/Container+Crane+Controller+Data+Set
    數(shù)據(jù)集的樣本條數(shù)只有15條,2個特征。具體如下:

    <<? 左右滑動查看更多? >>

    import?pandas?as?pd df?=?pd.read_csv('1.csv',index_col=0) #?df?=?pd.read_clipboard(index_col=0)?可以直接復(fù)制下面這個表格后使用read_clipboard讀成DataFrame

    對于二分類問題概率是預(yù)測值經(jīng)過Sigmoid函數(shù)變換后得到的,默認預(yù)測概率為0.5,也就是默認的預(yù)測值為0。

    <<? 左右滑動查看更多? >>

    def?log_loss_obj(preds,?labels):preds?=?1.0?/?(1.0?+?np.exp(-preds))grad?=?preds?-?labelshess?=?preds?*?(1.0?-?preds)return?grad,?hessbase_predict?=?np.zeros_like(df.y) g,h?=?log_loss_obj(base_predict,df.y.values)?#?計算每個樣本的g和h df['g'],?df['h']?=?g,h df

    x1x2yghID




    11-500.50.25
    22500.50.25
    33-21-0.50.25
    4121-0.50.25
    5201-0.50.25
    66-51-0.50.25
    7751-0.50.25
    86-200.50.25
    97200.50.25
    10601-0.50.25
    118-51-0.50.25
    12951-0.50.25
    1310-200.50.25
    148200.50.25
    15901-0.50.25

    首先對特征x1上的不同的值進行枚舉分裂增益。特征一總共有以下幾個取值:

    sorted(df.x1.unique()) #?[1,?2,?3,?6,?7,?8,?9,?10]

    對x1的取值進行排序后,最小值為1,顯然沒有樣本的x1特征值<1,以x1劃分相當于沒有進行劃分,因此從x1=2進行劃分。

    <<? 左右滑動查看更多? >>

    def?split_data(df,?split_feature,?split_value):left_instance?=?df[df[split_feature]?<?split_value]right_instance?=?df[df[split_feature]?>=?split_value]return?left_instance,?right_instanceleft_instance,?right_instance?=?split_data(df,'x1',2) left_instance.index.tolist(),right_instance.index.tolist() #??([1,?4],?[2,?3,?5,?6,?7,?8,?9,?10,?11,?12,?13,?14,?15])

    可以看到樣本1,4被劃分到了左側(cè),其余樣本劃分到了右側(cè)。對劃分后的數(shù)據(jù)計算G/H,并求出分裂后的增益Gain為0.055727554179566596。

    <<? 左右滑動查看更多? >>

    reg_lambda?=?1 G,H?=?df.g.sum(),?df.h.sum()?#?分裂前全部樣本的G/H for?thresh_values?in?sorted(df.x1.unique())[1:]:???G_left,?H_left?=?left_instance[['g',?'h']].sum()?#?分裂后的G_l,H_lG_right,?H_right?=?right_instance[['g',?'h']].sum()?#?分裂后的G_r,H_rGain?=?G_left**2/(H_left+reg_lambda)+G_right**2?/?\(H_right+reg_lambda)-G**2/(H+reg_lambda)?#?分裂后的增益計算

    對x1每個取值進行劃分,得到下面不同劃分下的增益值。


    G_leftH_leftG_rightH_rightGain
    20.00.50-1.53.250.055728
    30.01.00-1.52.750.126316
    6-0.51.25-1.02.50-0.076859
    7-1.02.00-0.51.75-0.049442
    8-1.02.50-0.51.25-0.076859
    9-1.03.00-0.50.75-0.080827
    10-2.03.500.50.250.615205

    同樣,對于特征x2每個取值的分裂情況:


    G_leftH_leftG_rightH_rightGain
    -2-0.50.75-1.03.00-0.080827
    00.01.50-1.52.250.218623
    2-1.52.250.01.500.218623
    5-1.03.00-0.50.75-0.080827

    我們可以看到當最大的增益為特征x1=10時,增益為0.615205,因此將x1<10作為第一個分裂條件。

    接下來開始進行第2個分裂條件的選擇:

    <<? 左右滑動查看更多? >>

    use_instance,_?=?split_data(df,'x1',10) G,H?=?use_instance.g.sum(),?use_instance.h.sum() for?thresh_values?in?sorted(use_instance.x1.unique())[1:]:???left_instance,?right_instance?=?split_data(use_instance,'x1',thresh_values)G_left,?H_left?=?left_instance[['g',?'h']].sum()G_right,?H_right?=?right_instance[['g',?'h']].sum()Gain?=?G_left**2/(H_left+reg_lambda)+G_right**2?/?\(H_right+reg_lambda)-G**2/(H+reg_lambda)

    對于特征x1:


    G_leftH_leftG_rightH_rightGain
    20.00.50-2.03.000.111111
    30.01.00-2.02.500.253968
    6-0.51.25-1.52.25-0.085470
    7-1.02.00-1.01.50-0.155556
    8-1.02.50-1.01.00-0.103175
    9-1.03.00-1.00.500.027778

    對于特征x2:


    G_leftH_leftG_rightH_rightGain
    -2-0.50.75-1.52.75-0.146032
    0-0.51.25-1.52.25-0.085470
    2-2.02.000.01.500.444444
    5-1.52.75-0.50.75-0.146032

    因此最優(yōu)的劃分為特征x2<2。

    通過不斷的對上述過程迭代,即可遞歸地建出第一棵樹。

    02

    簡易版XGBoost實現(xiàn)

    我們首先使用XGBoost的開源實現(xiàn)來構(gòu)建模型,和下面我們的實現(xiàn)做對比。

    <<? 左右滑動查看更多? >>

    import?xgboost?as?xgb model?=?xgb.XGBClassifier(n_estimators=2,max_depth=3,learning_rate=0.1,random_state=1,reg_lambda=1,gamma=0,objective='binary:logistic',min_child_weight=0,) model.fit(df[['x1','x2']],df.y) xgb.to_graphviz(model,num_trees=0)

    可以看到第一棵樹的結(jié)構(gòu)如下:

    第二棵樹的結(jié)構(gòu)如下:xgb.to_graphviz(model,num_trees=1)

    下面我們來用Python實現(xiàn)自己的簡易版XGBoost。
    首先創(chuàng)建節(jié)點類,通過節(jié)點的遞歸構(gòu)建出一棵樹。

    <<? 左右滑動查看更多? >>

    from?graphviz?import?Digraphclass?Node(object):"""結(jié)點leaf_value :?記錄葉子結(jié)點值split_feature :分裂節(jié)點對應(yīng)的特征名split_value :?分裂節(jié)點對應(yīng)的特征的值left :?左子樹right :?右子樹"""def?__init__(self,?leaf_value=None,?split_feature=None,?split_value=None,?left=None,?right=None):self.leaf_value?=?leaf_valueself.split_feature?=?split_featureself.split_value?=?split_valueself.left?=?leftself.right?=?rightdef?show(self):print(f'weight:?{self.leaf_value},?split_feature:?{self.split_feature},?split_value:?{self.split_value}.')def?visualize_tree(self):"""使用graphviz遞歸繪制樹"""def?add_nodes_edges(self,?dot=None):if?dot?is?None:dot?=?Digraph()dot.node(name=str(self),label=f'{self.split_feature}<{self.split_value}')#?Add?nodesif?self.left:if?self.left.leaf_value:dot.node(name=str(self.left),label=f'leaf={self.left.leaf_value:.10f}')else:dot.node(name=str(self.left),label=f'{self.left.split_feature}<{self.left.split_value}')dot.edge(str(self),?str(self.left))dot?=?add_nodes_edges(self.left,?dot=dot)if?self.right:if?self.right.leaf_value:dot.node(name=str(self.right),label=f'leaf={self.right.leaf_value:.10f}')else:dot.node(name=str(self.right),label=f'{self.right.split_feature}<{self.right.split_value}')dot.edge(str(self),?str(self.right))dot?=?add_nodes_edges(self.right,?dot=dot)return?dotdot?=?add_nodes_edges(self)return?dot

    注意這里我們寫了一個visualize_tree方法,使用graphviz來繪制建好的樹的結(jié)構(gòu),在XGBoost的開源實現(xiàn)中也是使用類似的方案。該方法不是必須的,但是卻對我們了解建樹過程有著很好的幫助。同時我們使用show方法將節(jié)點的信息也字符形式顯示出來。

    下面來看一下?lián)p失函數(shù)和建樹過程的實現(xiàn):

    <<? 左右滑動查看更多? >>

    #?樹的結(jié)構(gòu)參數(shù) reg_lambda?=?1?#?葉節(jié)點權(quán)重L2正則系數(shù) min_samples_split?=?1?#?分裂所需的最小樣本個數(shù) max_depth?=?3?#?樹的深度#?建樹過程參數(shù) learning_rate?=?0.1?#?學(xué)習(xí)率 n_estimators?=?2?#?樹的個數(shù)#?log損失函數(shù) def?log_loss_obj(preds,?labels):#?preds是建該樹之前模型的輸出,對于二分類問題需要的是概率,因此將該值經(jīng)過Sigmoid轉(zhuǎn)換probs?=?1.0?/?(1.0?+?np.exp(-preds))grad?=?probs?-?labelshess?=?probs?*?(1.0?-?probs)return?grad,?hessdef?build_tree(df,?feature_names,?depth=1):df?=?df.copy()df['g'],?df['h']?=?log_loss_obj(df.y_pred,?df.y)G,?H?=?df[['g',?'h']].sum()Gain_max?=?float('-inf')#?終止條件?當前節(jié)點個數(shù)小于分裂所需最小樣本個數(shù),深度大于max_depth,葉節(jié)點只有一類樣本無需再分if?df.shape[0]?>?min_samples_split?and?depth?<=?max_depth?and?df.y.nunique()?>?1:for?feature?in?feature_names:?#?遍歷每個特征thresholds?=?sorted(set(df[feature]))?#?特征取值排序for?thresh_value?in?thresholds[1:]:?#?遍歷每個取值left_instance?=?df[df[feature]?<?thresh_value]?#?劃分到左右節(jié)點的樣本right_instance?=?df[df[feature]?>=?thresh_value]G_left,?H_left?=?left_instance[['g',?'h']].sum()G_right,?H_right?=?right_instance[['g',?'h']].sum()Gain?=?G_left**2/(H_left+reg_lambda)+G_right**2?/?\(H_right+reg_lambda)-G**2/(H+reg_lambda)?#?評價劃分的增益效果if?Gain?>=?Gain_max:Gain_max?=?Gainsplit_feature?=?feature?#?最大增益對應(yīng)的分裂特征split_value?=?thresh_value?#?最大增益對應(yīng)的分裂值left_data?=?left_instance?#?最大增益對應(yīng)的分裂后左節(jié)點樣本right_data?=?right_instance?#?最大增益對應(yīng)的分裂后右節(jié)點樣本left?=?build_tree(left_data,?feature_names,??depth+1)?#?遞歸建左子樹right?=?build_tree(right_data,?feature_names,?depth+1)#?遞歸建右子樹return?Node(split_feature=split_feature,?split_value=split_value,?left=left,?right=right)?#?返回分裂節(jié)點return?Node(leaf_value=-G/(H+reg_lambda)*learning_rate)?#?分裂終止,返回葉節(jié)點權(quán)重

    對于單棵樹的預(yù)測,我們使用predict函數(shù),根據(jù)樹的分裂條件以及當前數(shù)據(jù)的信息來確認每個樣本被分到當前這棵樹的哪個葉節(jié)點,得到對應(yīng)葉節(jié)點的權(quán)重。

    <<? 左右滑動查看更多? >>

    def?predict(x,?tree):#?遞歸每個分裂點直到樣本對應(yīng)的葉節(jié)點#?終止條件:葉節(jié)點if?tree.leaf_value?is?not?None:return?tree.leaf_valueif?x[tree.split_feature]?<?tree.split_value:return?predict(x,?tree.left)else:return?predict(x,?tree.right)

    根據(jù)已建好的樹來更新預(yù)測結(jié)果,進而確定新建樹的結(jié)構(gòu),不斷迭代最終得到全部的樹:

    <<? 左右滑動查看更多? >>

    trees?=?[] y_pred?=?0??#?初始預(yù)測值 for?i?in?range(n_estimators):df['y_pred']?=?y_predtree?=?build_tree(df,?feature_names=['x1',?'x2'])data_weight?=?df[['x1',?'x2']].apply(predict,?tree=tree,?axis=1)y_pred?+=?data_weighttrees.append(tree)

    對于已建好的樹,使用我們前面定義的visualize_tree函數(shù),可以方便的看到樹的結(jié)構(gòu)。

    第一棵數(shù)的結(jié)構(gòu):

    trees[0].visualize_tree()

    第二棵樹的結(jié)構(gòu):
    trees[1].visualize_tree()


    可以看到,我們自己實現(xiàn)的XGBoost與開源的XGBoost得到的樹的結(jié)構(gòu)是一致的。

    03

    封? 裝

    把前面的各部分代碼封裝成類:

    <<? 左右滑動查看更多? >>

    import?numpy?as?np import?pandas?as?pd import?xgboost?as?xgb from?graphviz?import?Digraphclass?Node(object):"""結(jié)點leaf_value :?記錄葉子結(jié)點值split_feature :特征isplit_value :?特征i的值left :?左子樹right :?右子樹"""def?__init__(self,?leaf_value=None,?split_feature=None,?split_value=None,?left=None,?right=None):self.leaf_value?=?leaf_valueself.split_feature?=?split_featureself.split_value?=?split_valueself.left?=?leftself.right?=?rightdef?show(self):print(f'weight:?{self.leaf_value},?split_feature:?{self.split_feature},?split_value:?{self.split_value}.')def?visualize_tree(self):"""遞歸查找繪制樹"""def?add_nodes_edges(self,?dot=None):if?dot?is?None:dot?=?Digraph()dot.node(name=str(self),label=f'{self.split_feature}<{self.split_value}')#?Add?nodesif?self.left:if?self.left.leaf_value:dot.node(name=str(self.left),label=f'leaf={self.left.leaf_value:.10f}')else:dot.node(name=str(self.left),label=f'{self.left.split_feature}<{self.left.split_value}')dot.edge(str(self),?str(self.left))dot?=?add_nodes_edges(self.left,?dot=dot)if?self.right:if?self.right.leaf_value:dot.node(name=str(self.right),label=f'leaf={self.right.leaf_value:.10f}')else:dot.node(name=str(self.right),label=f'{self.right.split_feature}<{self.right.split_value}')dot.edge(str(self),?str(self.right))dot?=?add_nodes_edges(self.right,?dot=dot)return?dotdot?=?add_nodes_edges(self)return?dotdef?log_loss_obj(preds,?labels):preds?=?1.0?/?(1.0?+?np.exp(-preds))grad?=?preds?-?labelshess?=?preds?*?(1.0?-?preds)return?grad,?hessdef?mse_obj(preds,?labels):grad?=?labels-y_predhess?=?np.ones_like(labels)return?grad,?hessclass?XGB:def?__init__(self,?n_estimators=2,?learning_rate=0.1,?max_depth=3,?min_samples_split=0,?reg_lambda=1,?base_score=0.5,?loss=log_loss_obj):#?學(xué)習(xí)控制參數(shù)self.n_estimators?=?n_estimatorsself.learning_rate?=?learning_rateself.base_score?=?base_score#?樹參數(shù)self.max_depth?=?max_depthself.min_samples_split?=?min_samples_splitself.loss?=?lossself.reg_lambda?=?reg_lambdaself.trees?=?[]self.feature_names?=?Nonedef?sigmoid_array(self,?x):return?1?/?(1?+?np.exp(-x))def?_predict(self,?x,?tree):#?循環(huán)終止條件:葉節(jié)點if?tree.leaf_value?is?not?None:return?tree.leaf_valueif?x[tree.split_feature]?<?tree.split_value:return?self._predict(x,?tree.left)else:return?self._predict(x,?tree.right)def?_build_tree(self,?df,?depth=1):df?=?df.copy()df['g'],?df['h']?=?self.loss(df.y_pred,?df.y)G,?H?=?df[['g',?'h']].sum()Gain_max?=?float('-inf')if?df.shape[0]?>?self.min_samples_split?and?depth?<=?self.max_depth?and?df.y.nunique()?>?1:for?feature?in?self.feature_names:thresholds?=?sorted(set(df[feature]))for?thresh_value?in?thresholds[1:]:left_instance?=?df[df[feature]?<?thresh_value]right_instance?=?df[df[feature]?>=?thresh_value]G_left,?H_left?=?left_instance[['g',?'h']].sum()G_right,?H_right?=?right_instance[['g',?'h']].sum()Gain?=?G_left**2/(H_left+self.reg_lambda)+G_right**2?/?\(H_right+self.reg_lambda)-G**2/(H+self.reg_lambda)if?Gain?>=?Gain_max:Gain_max?=?Gainsplit_feature?=?featuresplit_value?=?thresh_valueleft_data?=?left_instanceright_data?=?right_instance#?print(feature,'Gain:',Gain,'G-Left',G_left,'H-left',H_left,'G-Right',G_right,'H-right',H_right,'----',thresh_value)#?print(Gain_max,split_feature,split_value)left?=?self._build_tree(left_data,??depth+1)right?=?self._build_tree(right_data,??depth+1)return?Node(split_feature=split_feature,?split_value=split_value,?left=left,?right=right)return?Node(leaf_value=-G/(H+self.reg_lambda)*self.learning_rate)def?fit(self,?X,?y):y_pred?=?-np.log((1/self.base_score)-1)df?=?pd.DataFrame(X)df['y']?=?yself.feature_names?=?df.columns.tolist()[:-1]for?i?in?range(self.n_estimators):df['y_pred']?=?y_predtree?=?self._build_tree(df)data_weight?=?df[['x1',?'x2']].apply(self._predict,?tree=tree,?axis=1)y_pred?+=?data_weightself.trees.append(tree)def?predict(self,?X):df?=?pd.DataFrame(X)y_pred?=?-np.log((1/self.base_score)-1)for?tree?in?self.trees:df['y_pred']?=?y_preddata_weight?=?df[['x1',?'x2']].apply(self._predict,?tree=tree,?axis=1)y_pred?+=?data_weightreturn?self.sigmoid_array(y_pred)def?__repr__(self):return?'XGBClassifier('+',?'.join(f'{k}={v}'?for?k,?v?in?self.__dict__.items()?if?not?k.startswith('_'))+')'

    使用前面同樣的方法,調(diào)用我們自己封裝好的代碼,可以看到很簡潔的實現(xiàn)了跟官方開源實現(xiàn)類似的效果。

    df?=?pd.read_csv('1.csv',index_col=0) model?=?XGB() model.fit(df[['x1',?'x2']],?df.y) model.predict(df[['x1',?'x2']]) model.trees[0].visualize_tree()

    當然這里只是一個DEMO,來幫助我們更好的理解論文中的公式以及XGBoost的實現(xiàn)過程,更多的細節(jié)優(yōu)化可以參考官方實現(xiàn):https://github.com/dmlc/xgboost


    04

    參? 考

    https://xgboost.readthedocs.io/en/latest/tutorials/model.html

    https://blog.csdn.net/qq_22238533/article/details/79477547

    https://github.com/dmlc/xgboost/blob/master/demo/guide-python/custom_objective.py

    https://github.com/lxmly/machine-learning/blob/master/decision_tree.py

    相關(guān)閱讀

    往期精彩回顧適合初學(xué)者入門人工智能的路線及資料下載機器學(xué)習(xí)及深度學(xué)習(xí)筆記等資料打印機器學(xué)習(xí)在線手冊深度學(xué)習(xí)筆記專輯《統(tǒng)計學(xué)習(xí)方法》的代碼復(fù)現(xiàn)專輯 AI基礎(chǔ)下載機器學(xué)習(xí)的數(shù)學(xué)基礎(chǔ)專輯 獲取本站知識星球優(yōu)惠券,復(fù)制鏈接直接打開: https://t.zsxq.com/qFiUFMV 本站qq群704220115。加入微信群請掃碼:

    總結(jié)

    以上是生活随笔為你收集整理的【机器学习基础】xgboost系列丨xgboost建树过程分析及代码实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 精品视频免费播放 | 欧美精品一级在线观看 | 91小视频| 亚洲视频中文 | 日本色中色| 欧美日韩小视频 | 中文字幕免费中文 | 91久久精品在线 | 岛国伊人| xxxxxx国产| 另类在线视频 | 欧美xx视频 | 国产精品一区二区亚洲 | 极品新婚夜少妇真紧 | 亚洲欧美日韩成人 | 天天草夜夜操 | 真实乱偷全部视频 | 亚洲在线观看一区 | 天堂av中文 | 波多野结衣亚洲一区 | 蜜桃视频黄色 | 黄色操人视频 | 老色批永久免费网站www | 蜜桃视频无码区在线观看 | 亚洲激情图片区 | 精品少妇theporn | 国产精品99久久久久久久久久久久 | 青青草原av | 亚洲国产精品毛片av不卡在线 | 久久毛片视频 | 欧美在线视频一区二区三区 | 97视频免费在线观看 | 亚洲日本久久 | wwwxxx日本人| 91porny九色| 国产精品jizz视频 | 91看片在线观看 | 精品久久久久久久久久久久久久久久久 | 日本一区二区在线播放 | 男女三级视频 | 日韩色在线| 国产毛片一区二区 | 91av视频在线播放 | 天天躁狠狠躁狠狠躁夜夜躁68 | 伊人久久麻豆 | 操欧美老女人 | 337p亚洲精品色噜噜狠狠 | 成人一区二区精品 | 色七七桃花综合影院 | 一级片视频免费观看 | 黄页网站视频在线观看 | 鲁丝av | 欧美一区二区大片 | 欧美在线日韩在线 | 国产精品第一页在线观看 | 国产精品国产精品国产专区不片 | 日本高清免费视频 | 成年人天堂| 麻豆69xxnxxporn| 少妇高潮av久久久久久 | 欧美黄色一级网站 | 天天碰天天碰 | 狠狠躁狠狠躁视频专区 | 中文av一区 | 成人亚洲精品久久久久软件 | 99少妇| 黑人操欧美人 | 日韩欧美精品中文字幕 | 性感美女一区二区三区 | 午夜在线精品 | 91av观看 | 婷婷综合社区 | 老熟妻内射精品一区 | 91网站在线免费观看 | 深夜福利免费视频 | 91综合国产 | 在线观看亚洲av每日更新 | 成人精品一区二区三区电影 | 黑人糟蹋人妻hd中文字幕 | 九色视频网站 | 日韩免费在线看 | 潘金莲一级淫片免费放动漫 | 一区二区亚洲精品 | 国产福利在线视频 | 日鲁鲁 | 黄色网址你懂得 | 成人做爰100| 天天影视插插插 | 亚洲最大的成人网 | 日韩一区二区三区在线观看 | 美女扒开尿口让男人爽 | 嫩草嫩草嫩草嫩草嫩草 | 成人免费视频国产免费网站 | 国产精品第一国产精品 | 日本黄色中文字幕 | 小妹色播影院 | 在线国产精品一区 | 最新中文字幕av专区 | 经典三级第一页 |