簡體   English   中英

XGBOOST 功能名稱錯誤 - Python

[英]XGBOOST feature name error - Python

可能這個問題已經以不同的形式被問過很多次了。 但是,我的問題是當我將XGBClassifier()與數據之類的產品一起使用時,出現功能名稱不匹配錯誤。 我希望有人能告訴我我做錯了什么。 這是我的代碼。 順便說一句,數據是完全組成的:

import pandas as pd
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
from sklearn.model_selection import train_test_split, KFold, cross_val_score
from sklearn.metrics import accuracy_score
import xgboost as xgb

data = {"Age":[44,27,30,38,40,35,70,48,50,37],
        "BMI":["25-29","35-39","30-35","40-45","45-49","20-25","<19",">70","50-55","55-59"],
        "BP":["<140/90",">140/90",">140/90",">140/90","<140/90","<140/90","<140/90",">140/90",">140/90","<140/90"],
        "Risk":["No","Yes","Yes","Yes","No","No","No","Yes","Yes","No"]}

df = pd.DataFrame(data)

X = df.iloc[:, :-1]
y = df.iloc[:, -1]

labelencoder = LabelEncoder()

def encoder_X(columns):
    for i in columns:
        X.iloc[:, i] = labelencoder.fit_transform(X.iloc[:, i])

encoder_X([1,2])

y = labelencoder.fit_transform(y)

onehotencdoer = OneHotEncoder(categorical_features = [[1,2]])
X = onehotencdoer.fit_transform(X).toarray()

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 13)

model = xgb.XGBClassifier()
model.fit(X_train, y_train, verbose = True)

y_pred = model.predict(X_test)
predictions = [round(value) for value in y_pred]

accuracy = accuracy_score(y_test, predictions)
print("Accuracy: {0}%".format(accuracy*100))

到目前為止一切順利,沒有錯誤。 准確度分數是 100%,但那是因為它是一個虛構的數據集,所以我並不擔心。

當我嘗試根據模型對新數據集進行分類時,出現“特征名稱不匹配錯誤”:

proddata = {"Age":[65,50,37],
        "BMI":["25-29","35-39","30-35"],
        "BP":["<140/90",">140/90",">140/90"]}

prod_df = pd.DataFrame(proddata)

def encoder_prod(columns):
    for i in columns:
        prod_df.iloc[:, i] = labelencoder.fit_transform(prod_df.iloc[:, i])

encoder_prod([1,2])

onehotencdoer = OneHotEncoder(categorical_features = [[1,2]])
prod_df = onehotencdoer.fit_transform(prod_df).toarray()

predictions = model.predict(prod_df)

在此之后,我收到以下錯誤

predictions = model.predict(prod_df)
Traceback (most recent call last):

  File "<ipython-input-24-456b5626e711>", line 1, in <module>
    predictions = model.predict(prod_df)

  File "c:\users\sozdemir\appdata\local\programs\python\python35\lib\site-packages\xgboost\sklearn.py", line 526, in predict
    ntree_limit=ntree_limit)

  File "c:\users\sozdemir\appdata\local\programs\python\python35\lib\site-packages\xgboost\core.py", line 1044, in predict
    self._validate_features(data)

  File "c:\users\sozdemir\appdata\local\programs\python\python35\lib\site-packages\xgboost\core.py", line 1288, in _validate_features
    data.feature_names))

ValueError: feature_names mismatch: ['f0', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', 'f11', 'f12'] ['f0', 'f1', 'f2', 'f3', 'f4', 'f5']
expected f6, f11, f12, f9, f7, f8, f10 in input data

我知道這是由於 OneHotEncoding 在適合並轉換為數組時發生的。 不過我可能錯了。

如果這是 OneHotEncoding 的結果,我是否可以不使用 OneHotEncoding,因為 LabelEncoder() 已經對分類值進行了編碼?

非常感謝您的任何幫助和反饋。

PS:XGBOOST的版本是0.7

xgboost.__version__
Out[37]: '0.7'

安裝后似乎需要保存編碼器。 我使用了joblibsklearn 來自https://machinelearningmastery.com/ 的Jason 給了我保存編碼器的想法。 以下是修改后的版本:

import pandas as pd
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
from sklearn.model_selection import train_test_split, KFold, cross_val_score
from sklearn.metrics import accuracy_score
from sklearn.externals import joblib
import xgboost as xgb

data = {"Age":[44,27,30,38,40,35,70,48,50,37],
        "BMI":["25-29","35-39","30-35","40-45","45-49","20-25","<19",">70","50-55","55-59"],
        "BP":["<140/90",">140/90",">140/90",">140/90","<140/90","<140/90","<140/90",">140/90",">140/90","<140/90"],
        "Risk":["No","Yes","Yes","Yes","No","No","No","Yes","Yes","No"]}

df = pd.DataFrame(data)

X = df.iloc[:, :-1]
y = df.iloc[:, -1]

labelencoder = LabelEncoder()

def encoder_X(columns):
    for i in columns:
        X.iloc[:, i] = labelencoder.fit_transform(X.iloc[:, i])

encoder_X([1,2])

y = labelencoder.fit_transform(y)

onehotencdoer = OneHotEncoder(categorical_features = [[1,2]])
onehotencdoer.fit(X)
enc = joblib.dump(onehotencdoer, "encoder.pkl") # save the fitted encoder
X = onehotencdoer.transform(X).toarray()

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 13)

model = xgb.XGBClassifier()
model.fit(X_train, y_train, verbose = True)

y_pred = model.predict(X_test)
predictions = [round(value) for value in y_pred]

accuracy = accuracy_score(y_test, predictions)
print("Accuracy: {0}%".format(accuracy*100))

現在,我們可以使用擬合編碼器來轉換 prod 數據:

proddata = {"Age":[65,50,37],
        "BMI":["25-29","35-39","30-35"],
        "BP":["<140/90",">140/90",">140/90"]}

prod_df = pd.DataFrame(proddata)

def encoder_prod(columns):
    for i in columns:
        prod_df.iloc[:, i] = labelencoder.fit_transform(prod_df.iloc[:, i])

encoder_prod([1,2])
enc = joblib.load("encoder.pkl")
prod_df = enc.transform(prod_df).toarray()

predictions = model.predict(prod_df)
results = [round(val) for val in predictions]

它似乎適用於這個例子,我將在更大的數據集上嘗試這種方法。 請讓我知道你的想法。

謝謝

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM