99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
2021-03-05 閱讀量: 1768
python中如何用xgboost模型填補(bǔ)缺失值?

如何用xgboost模型填補(bǔ)缺失值?

演示用數(shù)據(jù)如下:

1614829496_756660.xlsx

代碼文件如下:

liushagai1.txt

代碼如下:



# ### 導(dǎo)入庫
import pandas as pd
import numpy as np
import xgboost as xgb
from sklearn.base import BaseEstimator, TransformerMixin
#from sklearn.ensemble import BaggingClassifier, RandomForestClassifier
#pip install pyecharts -i https://pypi.tuna.tsinghua.edu.cn/simple
pd.options.display.max_columns = None  # 顯示所有列
pd.set_option('display.float_format', lambda x: '%.3f' % x)  # 取消科學(xué)計數(shù)法
#定義一個函數(shù)來判斷一個變量到底是什么類型
def get_kind(x: pd.Series, diff_limit: int = 10):
    x = x.astype('str')
    x = x.str.extract(r'(^(\-|)(?=.*\d)\d*(?:\.\d*)?$)')[0]
    x.dropna(inplace=True)
    if x.nunique() > diff_limit:
        kind = 'numeric'
    else:
        kind = 'categorical'
    return kind
#1.先將這個變量x轉(zhuǎn)化為字符型
#2.對這個字符串變量x進(jìn)行正則表達(dá)式的匹配,如果沒有匹配成功,則返回缺失值,并且直接作用于x
#3.刪除變量x里面的缺失值,并且直接作用于x
#4.數(shù)一數(shù)變量x里面有多少個唯一值,
#5.將唯一值的個數(shù)和diff_limit進(jìn)行比較
#6.如果大于diff_limit則將其判定為numeric類型,否則將其判定為categorical類型。
#7.也就是categorical類型變量的取值是不能太多的,不能超過我們設(shè)定的閥值10
class wrong_value_fillna(BaseEstimator, TransformerMixin):
    def __init__(self,
                 num_list: list = None,
                 cate_list: list = None,
                 wrong_value: list = None,
                 diff_num: int = 10):
        self.num_list = num_list
        self.cate_list = cate_list
        self.diff_num = diff_num
        self.wrong_value = wrong_value
    def fit(self, X, y=None):
        X = X.copy()
        
        if self.num_list is None:
            self.num_list = []
            for col in X.columns:
                kind = get_kind(x=X[col], diff_limit=self.diff_num)
                if kind == 'numeric':
                    self.num_list.append(col)
                    
        if self.cate_list is None:
            self.cate_list = []
            for col in X.columns:
                kind = get_kind(x=X[col], diff_limit=self.diff_num)
                if kind == 'categorical':
                    self.cate_list.append(col)
        return self
    def transform(self, X):
        X = X.copy()
        X.replace(self.wrong_value, np.nan, inplace=True)
        for col in X.columns:
            if get_kind(X[col]) == 'numeric':
                X[col] = X[col].astype('float')
            else:
                X[col] = X[col].astype('object')
        return X
class xgb_fill(BaseEstimator, TransformerMixin):
    def __init__(self,
                 num_list: list = None,
                 cate_list: list = None,
                 diff_num: int = 10,
                 #注意這個diff_num的設(shè)定非常重要,這個值最好與get_kind函數(shù)里面的設(shè)定值保持一致,否則可能出現(xiàn)漏洞
                 #比如這里設(shè)定為了8,而get_kind里面設(shè)定為了10,那么當(dāng)判斷一個變量是否要處理為object變量的時候
                 #就可能出現(xiàn)問題,比如這個變量的不重復(fù)值有9個,到了get_kind函數(shù)那里,將其處理為了object變量,
                 #在這里就會被處理成float變量
                 random_state: int = 0):
        self.num_list = num_list
        self.cate_list = cate_list
        self.diff_num = diff_num
        self.random_state = random_state
        self.xgb_cla_dict = {}
        self.xgb_reg_dict = {}
    def fit(self, X, y=None):
        from tqdm import tqdm
        X = X.copy()
        #1.先找到numberic變量列表self.num_list
        #2.再找到categorical變量列表self.cate_list
        if self.num_list is None:
            self.num_list = []
            for col in X.columns:
                kind = get_kind(x=X[col], diff_limit=self.diff_num)
                if kind == 'numeric':
                    self.num_list.append(col)
                    
        if self.cate_list is None:
            self.cate_list = []
            for col in X.columns:
                kind = get_kind(x=X[col], diff_limit=self.diff_num)
                if kind == 'categorical':
                    self.cate_list.append(col)
                    
        #對categorical變量進(jìn)行處理
        for col in tqdm(self.cate_list):
            file = X.copy()
            if file[col].isnull().any():
                #如果變量有缺失值的話,則用XGBClassifier分類器進(jìn)行填補(bǔ),填補(bǔ)后的變量放在了xgb_cla_dict里面
                df = pd.get_dummies(file, columns=[i for i in self.cate_list if i != col],
                                    prefix=[i for i in self.cate_list if i != col],
                                    dummy_na=True)
                #找出col列沒有缺失值的行,生成not_null數(shù)據(jù)框
                not_null = df.dropna(subset=[col])
                #將not_null中col以外的列設(shè)定為x_,將col列設(shè)定為y_
                x_ = not_null.drop([col], axis=1)
                y_ = not_null[col]
                #實例化分類器
                xgb_cla = xgb.XGBClassifier(random_state=self.random_state)
                #xgb_cla是一個針對col列預(yù)測的分類器
                #用fit方法擬合這個分類器的參數(shù)
                xgb_cla.fit(x_, y_)
                #將擬合好的分類器傳給字典self.xgb_cla_dict[col]
                self.xgb_cla_dict[col] = xgb_cla
        #對numberic變量進(jìn)行處理
        for col in tqdm(self.num_list):
            file = X.copy()
            if file[col].isnull().any():
                #如果變量有缺失值的話,則用XGBRegressor回歸器進(jìn)行填補(bǔ),填補(bǔ)后的變量放在了xgb_reg_dict里面
                df = pd.get_dummies(file, columns=self.cate_list, dummy_na=True, prefix=self.cate_list)
                not_null = df.dropna(subset=[col])
                x_ = not_null.drop([col], axis=1)
                y_ = not_null[col]
                xgb_reg = xgb.XGBRegressor(random_state=self.random_state, objective='reg:squarederror')
                xgb_reg.fit(x_, y_)
                self.xgb_reg_dict[col] = xgb_reg
        print('fit xgb fill the Na success!')
        return self
    def transform(self, X):
        print("cate_list1",self.cate_list,sep="************************")
        X = X.copy()
        from tqdm import tqdm
        print("******************",self.cate_list)
        for col in tqdm(self.cate_list):
            #對object變量進(jìn)行填補(bǔ)
            print("cate_list",col,sep="************************")
            file = X.copy()
            if file[col].isnull().any():
                print(col,"有缺失")
                #如果col列中有缺失值的話則進(jìn)行如下處理
                #1將數(shù)據(jù)框file里面的全部object變量都轉(zhuǎn)化為虛擬變量,并且把缺失值也看成一個類別。
                #2把數(shù)據(jù)框保存為df
                df = pd.get_dummies(file, columns=[i for i in self.cate_list if i != col],
                                    prefix=[i for i in self.cate_list if i != col],
                                    dummy_na=True)
                
                #刪除col變量存在缺失值的行,保留col變量不存在缺失值的行,保存為not_null
                not_null = df.dropna(subset=[col])
                #把col變量存在缺失值的行保存為數(shù)據(jù)框null
                null = df.drop(not_null.index)
                #根據(jù)數(shù)據(jù)框null的除col列的其他列的值對col列進(jìn)行插補(bǔ)
                #開始調(diào)用實例的predict方法
                #如果調(diào)用predict方法就會先調(diào)用fit方法
                #接下來可以轉(zhuǎn)到上面的fit方法定義那里看一下
                #完成fit之后數(shù)據(jù)就會插補(bǔ)成功了,并且將插補(bǔ)后的結(jié)果放到了self.xgb_cla_dict里面
                #然后用self.xgb_cla_dict里面的值對數(shù)據(jù)框null里面的col列進(jìn)行賦值。
                print(null.drop([col],axis=1).dtypes)
                null[col] = self.xgb_cla_dict[col].predict(null.drop([col], axis=1))
                #然后對X里面的col列進(jìn)行賦值
                X[col] = pd.concat([null, not_null], axis=0)[col]
            else:
                #如果col列中沒有缺失值的話則進(jìn)行如下處理
                X[col] = file[col]
            
        
        #對float64變量進(jìn)行填補(bǔ)
        for col in tqdm(self.num_list):
            print("num_list",col,sep="************************")
            file = X.copy()
            if file[col].isnull().any():
                df = pd.get_dummies(file, columns=self.cate_list, dummy_na=True, prefix=self.cate_list)
                not_null = df.dropna(subset=[col])
                null = df.drop(not_null.index)
                null[col] = self.xgb_reg_dict[col].predict(null.drop([col], axis=1))
                X[col] = pd.concat([null, not_null], axis=0)[col]
            else:
                X[col] = file[col]
        print('transform xgb fill the NA success!')
        return X
wvf = wrong_value_fillna(wrong_value=['.', '?'])
data = pd.read_excel(r"C:\Users\Administrator\Desktop\1614829496_756660.xlsx")
#我們看一下現(xiàn)在data數(shù)據(jù)里面的變量類型
#其中類型為object的變量有age,sex,region,
#float64:'B0003', 'B0004', 'B0005', 'B0006', 'B0008', 'B0010', 'B0011', 'B0014', 'B0015', 'B0016',  'B0018',
#int64:'B0012','B0017', 'B0124', 'Target'
data = wvf.transform(data)
#我們看一下經(jīng)過轉(zhuǎn)化后的data數(shù)據(jù)里面的變量類型
#其中類型為object的變量有age,sex,region,
#float64:'B0003',  'B0005', 'B0006',  'B0010',  'B0012','B0015', 'B0016',  'B0018', 'B0124', 
#object:'B0004','B0008','B0011','B0014','B0017','Target'
#將數(shù)據(jù)轉(zhuǎn)化好后進(jìn)行數(shù)據(jù)拆分
x1_ = data.drop(['Target'], axis=1)
y1_ = data['Target'].values
#實例化
xgbf = xgb_fill()
#調(diào)用fit_transform方法進(jìn)行插補(bǔ)
x_=xgbf.fit_transform(x1_)  #這個就是插補(bǔ)之后的結(jié)果




希望大家運(yùn)行愉快!





0.0000
0
關(guān)注作者
收藏
評論(0)

發(fā)表評論

暫無數(shù)據(jù)
推薦帖子