Xgboost: feature_names stimmt nicht ĂŒberein, wenn in Python spĂ€rliche Matrizen verwendet werden

Erstellt am 31. Mai 2016  Â·  51Kommentare  Â·  Quelle: dmlc/xgboost

Ich erhalte ValueError: feature_names mismatch beim Training von xgboost mit spÀrlichen Matrizen in Python.
Die xgboost-Version ist die neueste von git. Ältere Versionen geben diesen Fehler nicht aus. WĂ€hrend der Vorhersagezeit wird ein Fehler zurĂŒckgegeben.

Code

from scipy import sparse
import xgboost as xgb
from random import *
randBinList = lambda n: [randint(0,1) for b in range(1,n+1)]

train = sparse.rand(100,500)
test = sparse.rand(10, 500)
y = randBinList(100)
clf = xgb.XGBClassifier()
clf.fit(train,y)
preds = clf.predict_proba(test)

VollstĂ€ndige RĂŒckverfolgung:

ValueError                                Traceback (most recent call last)
<ipython-input-15-e03f10289bf1> in <module>()
----> 1 preds = clf.predict_proba(test)

/usr/local/lib/python2.7/dist-packages/xgboost-0.4-py2.7.egg/xgboost/sklearn.pyc in predict_proba(self, data, output_margin, ntree_limit)
    471         class_probs = self.booster().predict(test_dmatrix,
    472                                              output_margin=output_margin,
--> 473                                              ntree_limit=ntree_limit)
    474         if self.objective == "multi:softprob":
    475             return class_probs

/usr/local/lib/python2.7/dist-packages/xgboost-0.4-py2.7.egg/xgboost/core.pyc in predict(self, data, output_margin, ntree_limit, pred_leaf)
    937             option_mask |= 0x02
    938 
--> 939         self._validate_features(data)
    940 
    941         length = ctypes.c_ulong()

/usr/local/lib/python2.7/dist-packages/xgboost-0.4-py2.7.egg/xgboost/core.pyc in _validate_features(self, data)
   1177 
   1178                 raise ValueError(msg.format(self.feature_names,
-> 1179                                             data.feature_names))
   1180 
   1181     def get_split_value_histogram(self, feature, fmap='', bins=None, as_pandas=True):

ValueError: feature_names mismatch: ['f0', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', 'f11', 'f12', 'f13', 'f14', 'f15', 'f16', 'f17', 'f18', 'f19', 'f20', 'f21', 'f22', 'f23', 'f24', 'f25', 'f26', 'f27', 'f28', 'f29', 'f30', 'f31', 'f32', 'f33', 'f34', 'f35', 'f36', 'f37', 'f38', 'f39', 'f40', 'f41', 'f42', 'f43', 'f44', 'f45', 'f46', 'f47', 'f48', 'f49', 'f50', 'f51', 'f52', 'f53', 'f54', 'f55', 'f56', 'f57', 'f58', 'f59', 'f60', 'f61', 'f62', 'f63', 'f64', 'f65', 'f66', 'f67', 'f68', 'f69', 'f70', 'f71', 'f72', 'f73', 'f74', 'f75', 'f76', 'f77', 'f78', 'f79', 'f80', 'f81', 'f82', 'f83', 'f84', 'f85', 'f86', 'f87', 'f88', 'f89', 'f90', 'f91', 'f92', 'f93', 'f94', 'f95', 'f96', 'f97', 'f98', 'f99', 'f100', 'f101', 'f102', 'f103', 'f104', 'f105', 'f106', 'f107', 'f108', 'f109', 'f110', 'f111', 'f112', 'f113', 'f114', 'f115', 'f116', 'f117', 'f118', 'f119', 'f120', 'f121', 'f122', 'f123', 'f124', 'f125', 'f126', 'f127', 'f128', 'f129', 'f130', 'f131', 'f132', 'f133', 'f134', 'f135', 'f136', 'f137', 'f138', 'f139', 'f140', 'f141', 'f142', 'f143', 'f144', 'f145', 'f146', 'f147', 'f148', 'f149', 'f150', 'f151', 'f152', 'f153', 'f154', 'f155', 'f156', 'f157', 'f158', 'f159', 'f160', 'f161', 'f162', 'f163', 'f164', 'f165', 'f166', 'f167', 'f168', 'f169', 'f170', 'f171', 'f172', 'f173', 'f174', 'f175', 'f176', 'f177', 'f178', 'f179', 'f180', 'f181', 'f182', 'f183', 'f184', 'f185', 'f186', 'f187', 'f188', 'f189', 'f190', 'f191', 'f192', 'f193', 'f194', 'f195', 'f196', 'f197', 'f198', 'f199', 'f200', 'f201', 'f202', 'f203', 'f204', 'f205', 'f206', 'f207', 'f208', 'f209', 'f210', 'f211', 'f212', 'f213', 'f214', 'f215', 'f216', 'f217', 'f218', 'f219', 'f220', 'f221', 'f222', 'f223', 'f224', 'f225', 'f226', 'f227', 'f228', 'f229', 'f230', 'f231', 'f232', 'f233', 'f234', 'f235', 'f236', 'f237', 'f238', 'f239', 'f240', 'f241', 'f242', 'f243', 'f244', 'f245', 'f246', 'f247', 'f248', 'f249', 'f250', 'f251', 'f252', 'f253', 'f254', 'f255', 'f256', 'f257', 'f258', 'f259', 'f260', 'f261', 'f262', 'f263', 'f264', 'f265', 'f266', 'f267', 'f268', 'f269', 'f270', 'f271', 'f272', 'f273', 'f274', 'f275', 'f276', 'f277', 'f278', 'f279', 'f280', 'f281', 'f282', 'f283', 'f284', 'f285', 'f286', 'f287', 'f288', 'f289', 'f290', 'f291', 'f292', 'f293', 'f294', 'f295', 'f296', 'f297', 'f298', 'f299', 'f300', 'f301', 'f302', 'f303', 'f304', 'f305', 'f306', 'f307', 'f308', 'f309', 'f310', 'f311', 'f312', 'f313', 'f314', 'f315', 'f316', 'f317', 'f318', 'f319', 'f320', 'f321', 'f322', 'f323', 'f324', 'f325', 'f326', 'f327', 'f328', 'f329', 'f330', 'f331', 'f332', 'f333', 'f334', 'f335', 'f336', 'f337', 'f338', 'f339', 'f340', 'f341', 'f342', 'f343', 'f344', 'f345', 'f346', 'f347', 'f348', 'f349', 'f350', 'f351', 'f352', 'f353', 'f354', 'f355', 'f356', 'f357', 'f358', 'f359', 'f360', 'f361', 'f362', 'f363', 'f364', 'f365', 'f366', 'f367', 'f368', 'f369', 'f370', 'f371', 'f372', 'f373', 'f374', 'f375', 'f376', 'f377', 'f378', 'f379', 'f380', 'f381', 'f382', 'f383', 'f384', 'f385', 'f386', 'f387', 'f388', 'f389', 'f390', 'f391', 'f392', 'f393', 'f394', 'f395', 'f396', 'f397', 'f398', 'f399', 'f400', 'f401', 'f402', 'f403', 'f404', 'f405', 'f406', 'f407', 'f408', 'f409', 'f410', 'f411', 'f412', 'f413', 'f414', 'f415', 'f416', 'f417', 'f418', 'f419', 'f420', 'f421', 'f422', 'f423', 'f424', 'f425', 'f426', 'f427', 'f428', 'f429', 'f430', 'f431', 'f432', 'f433', 'f434', 'f435', 'f436', 'f437', 'f438', 'f439', 'f440', 'f441', 'f442', 'f443', 'f444', 'f445', 'f446', 'f447', 'f448', 'f449', 'f450', 'f451', 'f452', 'f453', 'f454', 'f455', 'f456', 'f457', 'f458', 'f459', 'f460', 'f461', 'f462', 'f463', 'f464', 'f465', 'f466', 'f467', 'f468', 'f469', 'f470', 'f471', 'f472', 'f473', 'f474', 'f475', 'f476', 'f477', 'f478', 'f479', 'f480', 'f481', 'f482', 'f483', 'f484', 'f485', 'f486', 'f487', 'f488', 'f489', 'f490', 'f491', 'f492', 'f493', 'f494', 'f495', 'f496', 'f497', 'f498'] ['f0', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', 'f11', 'f12', 'f13', 'f14', 'f15', 'f16', 'f17', 'f18', 'f19', 'f20', 'f21', 'f22', 'f23', 'f24', 'f25', 'f26', 'f27', 'f28', 'f29', 'f30', 'f31', 'f32', 'f33', 'f34', 'f35', 'f36', 'f37', 'f38', 'f39', 'f40', 'f41', 'f42', 'f43', 'f44', 'f45', 'f46', 'f47', 'f48', 'f49', 'f50', 'f51', 'f52', 'f53', 'f54', 'f55', 'f56', 'f57', 'f58', 'f59', 'f60', 'f61', 'f62', 'f63', 'f64', 'f65', 'f66', 'f67', 'f68', 'f69', 'f70', 'f71', 'f72', 'f73', 'f74', 'f75', 'f76', 'f77', 'f78', 'f79', 'f80', 'f81', 'f82', 'f83', 'f84', 'f85', 'f86', 'f87', 'f88', 'f89', 'f90', 'f91', 'f92', 'f93', 'f94', 'f95', 'f96', 'f97', 'f98', 'f99', 'f100', 'f101', 'f102', 'f103', 'f104', 'f105', 'f106', 'f107', 'f108', 'f109', 'f110', 'f111', 'f112', 'f113', 'f114', 'f115', 'f116', 'f117', 'f118', 'f119', 'f120', 'f121', 'f122', 'f123', 'f124', 'f125', 'f126', 'f127', 'f128', 'f129', 'f130', 'f131', 'f132', 'f133', 'f134', 'f135', 'f136', 'f137', 'f138', 'f139', 'f140', 'f141', 'f142', 'f143', 'f144', 'f145', 'f146', 'f147', 'f148', 'f149', 'f150', 'f151', 'f152', 'f153', 'f154', 'f155', 'f156', 'f157', 'f158', 'f159', 'f160', 'f161', 'f162', 'f163', 'f164', 'f165', 'f166', 'f167', 'f168', 'f169', 'f170', 'f171', 'f172', 'f173', 'f174', 'f175', 'f176', 'f177', 'f178', 'f179', 'f180', 'f181', 'f182', 'f183', 'f184', 'f185', 'f186', 'f187', 'f188', 'f189', 'f190', 'f191', 'f192', 'f193', 'f194', 'f195', 'f196', 'f197', 'f198', 'f199', 'f200', 'f201', 'f202', 'f203', 'f204', 'f205', 'f206', 'f207', 'f208', 'f209', 'f210', 'f211', 'f212', 'f213', 'f214', 'f215', 'f216', 'f217', 'f218', 'f219', 'f220', 'f221', 'f222', 'f223', 'f224', 'f225', 'f226', 'f227', 'f228', 'f229', 'f230', 'f231', 'f232', 'f233', 'f234', 'f235', 'f236', 'f237', 'f238', 'f239', 'f240', 'f241', 'f242', 'f243', 'f244', 'f245', 'f246', 'f247', 'f248', 'f249', 'f250', 'f251', 'f252', 'f253', 'f254', 'f255', 'f256', 'f257', 'f258', 'f259', 'f260', 'f261', 'f262', 'f263', 'f264', 'f265', 'f266', 'f267', 'f268', 'f269', 'f270', 'f271', 'f272', 'f273', 'f274', 'f275', 'f276', 'f277', 'f278', 'f279', 'f280', 'f281', 'f282', 'f283', 'f284', 'f285', 'f286', 'f287', 'f288', 'f289', 'f290', 'f291', 'f292', 'f293', 'f294', 'f295', 'f296', 'f297', 'f298', 'f299', 'f300', 'f301', 'f302', 'f303', 'f304', 'f305', 'f306', 'f307', 'f308', 'f309', 'f310', 'f311', 'f312', 'f313', 'f314', 'f315', 'f316', 'f317', 'f318', 'f319', 'f320', 'f321', 'f322', 'f323', 'f324', 'f325', 'f326', 'f327', 'f328', 'f329', 'f330', 'f331', 'f332', 'f333', 'f334', 'f335', 'f336', 'f337', 'f338', 'f339', 'f340', 'f341', 'f342', 'f343', 'f344', 'f345', 'f346', 'f347', 'f348', 'f349', 'f350', 'f351', 'f352', 'f353', 'f354', 'f355', 'f356', 'f357', 'f358', 'f359', 'f360', 'f361', 'f362', 'f363', 'f364', 'f365', 'f366', 'f367', 'f368', 'f369', 'f370', 'f371', 'f372', 'f373', 'f374', 'f375', 'f376', 'f377', 'f378', 'f379', 'f380', 'f381', 'f382', 'f383', 'f384', 'f385', 'f386', 'f387', 'f388', 'f389', 'f390', 'f391', 'f392', 'f393', 'f394', 'f395', 'f396', 'f397', 'f398', 'f399', 'f400', 'f401', 'f402', 'f403', 'f404', 'f405', 'f406', 'f407', 'f408', 'f409', 'f410', 'f411', 'f412', 'f413', 'f414', 'f415', 'f416', 'f417', 'f418', 'f419', 'f420', 'f421', 'f422', 'f423', 'f424', 'f425', 'f426', 'f427', 'f428', 'f429', 'f430', 'f431', 'f432', 'f433', 'f434', 'f435', 'f436', 'f437', 'f438', 'f439', 'f440', 'f441', 'f442', 'f443', 'f444', 'f445', 'f446', 'f447', 'f448', 'f449', 'f450', 'f451', 'f452', 'f453', 'f454', 'f455', 'f456', 'f457', 'f458', 'f459', 'f460', 'f461', 'f462', 'f463', 'f464', 'f465', 'f466', 'f467', 'f468', 'f469', 'f470', 'f471', 'f472', 'f473', 'f474', 'f475', 'f476', 'f477', 'f478', 'f479', 'f480', 'f481', 'f482', 'f483', 'f484', 'f485', 'f486', 'f487', 'f488', 'f489', 'f490', 'f491', 'f492', 'f493', 'f494', 'f495', 'f496', 'f497', 'f498', 'f499']
training data did not have the following fields: f499

Hilfreichster Kommentar

Das Problem tritt auf, weil DMatrix..num_col() nur die Anzahl der Spalten ungleich Null in einer Matrix mit geringer Dichte zurĂŒckgibt. Wenn also sowohl Trainings- als auch Testdaten die gleiche Anzahl von Spalten ungleich Null aufweisen, funktioniert alles einwandfrei.
Andernfalls erhalten Sie unterschiedliche Feature-Namenslisten, da die Validierungsfunktionen Folgendes aufrufen:

    <strong i="7">@property</strong>
    def feature_names(self):
        """Get feature names (column labels).

        Returns
        -------
        feature_names : list or None
        """
        if self._feature_names is None:
            return ['f{0}'.format(i) for i in range(self.num_col())]
        else:
            return self._feature_names

self._feature_names ist None fĂŒr dĂŒnn besetzte Matrizen, und da self.num_col() nur die Anzahl der Spalten ungleich null zurĂŒckgibt, schlĂ€gt die Validierung fehl, sobald die Anzahl der Spalten ungleich null in der "zu-be- vorhergesagte" Daten unterscheidet sich von der Anzahl der Spalten ungleich null in den Trainingsdaten.

Keine Ahnung, wo das am besten zu beheben ist.

Alle 51 Kommentare

Es scheint, dass dies nur funktioniert, wenn die spĂ€rliche Matrizen CSC ist. Es funktioniert nicht fĂŒr CSR- oder COO-Matrizen wie frĂŒhere Versionen.

Ist es nicht ein zufÀlliges Problem, wenn die Spalte ganz rechts 0 oder 1 ist? Vielleicht das gleiche wie #1091 und #1221.

@sinhrks : FĂŒr mich ist das nicht "zufĂ€llig". Ich trainiere XGBoost hĂ€ufig mit sehr spĂ€rlichen Daten (und es ist großartig! Es schlĂ€gt normalerweise alle anderen Modelle und mit einem ziemlich großen Vorsprung).

Sobald das trainierte Modell dann in der Produktion lĂ€uft, möchte ich natĂŒrlich Vorhersagen ĂŒber ein neues StĂŒck eingehender Daten treffen. Diese Daten sind natĂŒrlich sehr wahrscheinlich spĂ€rlich und haben keinen Wert fĂŒr die Spalte, die zufĂ€llig die letzte Spalte ist. Daher bricht XGBoost fĂŒr mich jetzt hĂ€ufig zusammen, und ich habe zu anderen (weniger genauen) Modellen gewechselt, einfach weil sie eine bessere UnterstĂŒtzung fĂŒr spĂ€rliche Daten haben.

Weiß jemand genau warum dieser Fehler jetzt auftritt und wie man ihn adressiert? Dies ist ein Schmerzpunkt fĂŒr mich, da meine vorhandenen Skripte versagen.

Ich probiere xgboost als Teil einer Sklearn-Pipeline aus und bin auf das gleiche Problem gestoßen. Gibt es einen Workaround, bis es behoben ist?

Ja, wenn Sie Predict aufrufen, verwenden Sie die Funktion toarray() des Sparse-Arrays. Es ist furchtbar ineffizient mit dem Speicher, ist aber mit kleinen Slices bearbeitbar.

von meinem Iphone gesendet

Am 26. August 2016 um 22:44 Uhr schrieb Pedro Rodriguez [email protected] :

Ich probiere xgboost als Teil einer Sklearn-Pipeline aus und bin auf das gleiche Problem gestoßen. Gibt es einen Workaround, bis es behoben ist?

—
Sie erhalten dies, weil Sie einen Kommentar abgegeben haben.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub an oder schalten Sie den Thread stumm.

Aus irgendeinem Grund tritt der Fehler nicht auf, wenn ich das trainierte Modell speichere und lade:

    bst = xgb.train(param, dtrain, num_round)

    # predict is not working without this code
    bst.save_model(model_file_name)
    bst = xgb.Booster(param)
    bst.load_model(model_file_name)

    preds = bst.predict(dtest)

@bryan-woods Ich konnte mit tocsc eine bessere Lösung finden. Es gibt wahrscheinlich einige Leistungseinbußen, aber nicht annĂ€hernd so schlimm wie eine dichte Matrix.

Dies in meine Sklearn-Pipeline aufzunehmen, kurz bevor xgboost funktionierte

class CSCTransformer(TransformerMixin):
    def transform(self, X, y=None, **fit_params):
        return X.tocsc()

    def fit_transform(self, X, y=None, **fit_params):
        self.fit(X, y, **fit_params)
        return self.transform(X)

    def fit(self, X, y=None, **fit_params):
        return self

    def get_params(self, deep=True):
        return {}

Weder das CSC-Format noch das HinzufĂŒgen von Nicht-Null-EintrĂ€gen in die letzte Spalte behebt das Problem in der neuesten Version von xgboost. Das ZurĂŒcksetzen auf Version 0.4a30 ist das einzige, was ich zum Laufen bringen kann. Betrachten Sie die folgende Optimierung (mit einem reproduzierbaren Seed) am ursprĂŒnglichen Beispiel:

>>> import xgboost as xgb
>>> import numpy as np
>>> from scipy import sparse
>>> 
>>> np.random.seed(10)
>>> X = sparse.rand(100,10).tocsr()
>>> test = sparse.rand(10, 500).tocsr()
>>> y = np.random.randint(2,size=100)
>>> 
>>> clf = xgb.XGBClassifier()
>>> clf.fit(X,y)
XGBClassifier(base_score=0.5, colsample_bylevel=1, colsample_bytree=1,
       gamma=0, learning_rate=0.1, max_delta_step=0, max_depth=3,
       min_child_weight=1, missing=None, n_estimators=100, nthread=-1,
       objective='binary:logistic', reg_alpha=0, reg_lambda=1,
       scale_pos_weight=1, seed=0, silent=True, subsample=1)
>>> 
>>> try:
...     pred = clf.predict_proba(test)
...     print "Works when csr with version %s" %xgb.__version__
... except ValueError:
...     "Broken when csr with version %s" %xgb.__version__
... 
'Broken when csr with version 0.6'
>>> try:
...     pred = clf.predict_proba(test.tocsc())
...     print "Works when csc with version %s" %xgb.__version__
... except ValueError:
...     "Still broken when csc with version %s" %xgb.__version__
... 
'Still broken when csc with version 0.6'
>>> try:
...     test[0,(test.shape[1]-1)] = 1.0
...     pred = clf.predict_proba(test)
...     print "Works when adding non-zero entries to last column with version %s" %xgb.__version__
... except ValueError:
...     "Still broken when adding non-zero entries to last column with version %s" %xgb.__version__
... 
/home/david.mcgarry/.conda/envs/ml/lib/python2.7/site-packages/scipy/sparse/compressed.py:730: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.
  SparseEfficiencyWarning)
'Still broken when adding non-zero entries to last column with version 0.6'
>>> import xgboost as xgb
>>> import numpy as np
>>> from scipy import sparse
>>> 
>>> np.random.seed(10)
>>> X = sparse.rand(100,10).tocsr()
>>> test = sparse.rand(10, 500).tocsr()
>>> y = np.random.randint(2,size=100)
>>> 
>>> clf = xgb.XGBClassifier()
>>> clf.fit(X,y)
XGBClassifier(base_score=0.5, colsample_bylevel=1, colsample_bytree=1,
       gamma=0, learning_rate=0.1, max_delta_step=0, max_depth=3,
       min_child_weight=1, missing=None, n_estimators=100, nthread=-1,
       objective='binary:logistic', reg_alpha=0, reg_lambda=1,
       scale_pos_weight=1, seed=0, silent=True, subsample=1)
>>> 
>>> try:
...     pred = clf.predict_proba(test)
...     print "Works when csr with version %s" %xgb.__version__
... except ValueError:
...     "Broken when csr with version %s" %xgb.__version__
... 
Works when csr with version 0.4
>>> try:
...     pred = clf.predict_proba(test.tocsc())
...     print "Works when csc with version %s" %xgb.__version__
... except ValueError:
...     "Still broken when csc with version %s" %xgb.__version__
... 
Works when csc with version 0.4
>>> try:
...     test[0,(test.shape[1]-1)] = 1.0
...     pred = clf.predict_proba(test)
...     print "Works when adding non-zero entries to last column with version %s" %xgb.__version__
... except ValueError:
...     "Still broken when adding non-zero entries to last column with version %s" %xgb.__version__
... 
/Users/david.mcgarry/anaconda/envs/ml/lib/python2.7/site-packages/scipy/sparse/compressed.py:739: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.
  SparseEfficiencyWarning)
Works when adding non-zero entries to last column with version 0.4

Gleiches Problem hier, in der letzten Version ist definitiv etwas kaputt gegangen. Hatte dieses Problem mit dem gleichen Datensatz und der gleichen Verarbeitung zuvor nicht. Ich könnte mich irren, aber es sieht so aus, als ob es derzeit keine Unit-Tests mit spĂ€rlichen csr-Arrays in Python gibt, die die sklearn-API verwenden. WĂ€re es möglich, das obige @dmcgarry- Beispiel zu tests/python/tests_with_sklearn.py hinzuzufĂŒgen?

Ich habe versucht, es mit .toarray() mit CSR-Sparse-Arrays zu umgehen, aber etwas ist ernsthaft defekt. Wenn ich ein gespeichertes Modell lade und versuche, damit Vorhersagen mit .toarray() zu treffen, erhalte ich keine Fehlermeldung, aber die Ergebnisse sind falsch. Ich habe auf 0.4a30 zurĂŒckgesetzt und es funktioniert gut. Ich hatte nicht die Zeit, der Ursache nachzugehen, aber es ist nicht gut.

Das Problem tritt auf, weil DMatrix..num_col() nur die Anzahl der Spalten ungleich Null in einer Matrix mit geringer Dichte zurĂŒckgibt. Wenn also sowohl Trainings- als auch Testdaten die gleiche Anzahl von Spalten ungleich Null aufweisen, funktioniert alles einwandfrei.
Andernfalls erhalten Sie unterschiedliche Feature-Namenslisten, da die Validierungsfunktionen Folgendes aufrufen:

    <strong i="7">@property</strong>
    def feature_names(self):
        """Get feature names (column labels).

        Returns
        -------
        feature_names : list or None
        """
        if self._feature_names is None:
            return ['f{0}'.format(i) for i in range(self.num_col())]
        else:
            return self._feature_names

self._feature_names ist None fĂŒr dĂŒnn besetzte Matrizen, und da self.num_col() nur die Anzahl der Spalten ungleich null zurĂŒckgibt, schlĂ€gt die Validierung fehl, sobald die Anzahl der Spalten ungleich null in der "zu-be- vorhergesagte" Daten unterscheidet sich von der Anzahl der Spalten ungleich null in den Trainingsdaten.

Keine Ahnung, wo das am besten zu beheben ist.

Ich befĂŒrchte auch, dass es ein grundlegendes Problem beim Umgang mit spĂ€rlichen Matrixen gibt, aufgrund dessen, was @bryan-woods berichtet hat: Sagen wir, wir haben x Nullspalten sowohl im Zug als auch im Test, aber mit unterschiedlichen Indizes => Es wird kein Fehler sein, da "feature_names(self)" die gleiche Feature-Liste fĂŒr beide Sets zurĂŒckgibt, aber die Vorhersagen sind falsch, da die Spaltenindizes zwischen Zug und Test nicht ĂŒbereinstimmen, die nicht Null sind.

Hat jemand an diesem Problem gearbeitet? Hat jemand zumindest einen Unit-Test entwickelt, gegen den wir entwickeln könnten?

Ich habe nicht daran gearbeitet, aber das obige Beispiel von Komponententests verwendet werden, denke ich,

import xgboost as xgb
import numpy as np
import scipy.sparse


def test_xgbclassifier_sklearn_sparse():
    np.random.seed(10)
    X = scipy.sparse.rand(100,10).tocsr()
    test = scipy.sparse.rand(10, 500).tocsr()
    y = np.random.randint(2,size=100)

    clf = xgb.XGBClassifier()
    clf.fit(X,y)
    pred = clf.predict_proba(test)

Ich habe ein paar neue Sparse-Array-Tests in meinem Fork des Repositorys erstellt. FĂŒr Interessierte:
https://github.com/bryan-woods/xgboost/blob/sparse_test/tests/python/test_scipy_sparse.py

So fĂŒhren Sie die Tests aus dem Stammverzeichnis des Checkouts aus:
python -m Nase tests/python/test_scipy_sparse.py

Sie werden feststellen, dass beide Tests fehlschlagen. Dies wird zumindest einen Test bieten, gegen den man sich entwickeln kann.

Ich habe auch dieses Problem, aber ich kann nicht herausfinden, was der beste Weg ist, um es zu beheben, bis es endlich in der lib gelöst ist.

Sie könnten Ihrer Feature-Liste ein Feature mit einem maximalen Feature-Index hinzufĂŒgen, wie z. B. maxid:0

Übergabe eines Datenrahmens hat das Problem fĂŒr mich gelöst

Wie kann ich zu Version 0.4 zurĂŒckkehren?

pip install --upgrade xgboost==0.4a30

Alle Arten von spĂ€rlichen Matrizen haben bei mir nicht funktioniert (ich arbeite mit tf-idf-Daten). Ich musste auf die vorherige Version zurĂŒckgreifen. Danke fĂŒr den Tipp!

Alle, die immer noch Probleme haben: EnthÀlt der Code, den Sie verwenden, die Korrekturen in #1606 ?

Ja, ich habe die letzte Version von xgboost installiert und dieses Problem tritt immer noch auf.

Diese existiert noch und ist leicht reproduzierbar. Wenn Sie einen ausreichend großen Datensatz verwenden, ist dies weniger wahrscheinlich, aber wenn Sie dies in ein Rastersuchobjekt einschließen, geschieht dies mit ziemlicher Sicherheit innerhalb eines CV-Splits, bei dem sich die in den Zug-/CV-TestsĂ€tzen verfĂŒgbaren Funktionen unterscheiden.

Ehrlich gesagt verstehe ich nicht wirklich, warum DMatrix den Formhinweis ignoriert, der von scipy spĂ€rlichen Matrizen bereitgestellt wird. Es sollte die GrĂ¶ĂŸe basierend auf diesen Informationen festlegen, anstatt sie zu berechnen.

Ich verwende die native Xgboost-Python-API (0.6) und habe den gleichen Fehler beim Laden einer DMatrix aus einer LIBSVM-Datei im [sparse]-Format, wenn eine der Zeilen enthÀlt, die die letzte Spalte definiert hat. Meine Problemumgehung bestand darin, eine Dummy-Spalte in der ersten Zeile zu definieren :(

train_fv_file = 'train_fv_eval.svm'
dtrain = xgb.DMatrix(train_fv_file, feature_names=feature_vector_labels, feature_types=feature_vector_types)

Wenn es so einfach zu reproduzieren ist, möchte jemand ein reproduzierbares Beispiel liefern? Am besten ohne die Sklearn-Schicht (um eine mögliche Ursache zu isolieren).

@gabrielspmoreira : Ich num_col Hinweis profitieren.

In [42]: matrix = xgboost.DMatrix(scipy.sparse.csr_matrix([[0, 2, 3, 0], [0, 2, 2, 0], [1, 0, 5, 0], [0, 1, 0, 0]], shape=(4,4)))
In [43]: matrix.num_col()
Out[43]: 3L

Jedes Mal, wenn eine neue DMatrix auf einer Unterstichprobe von Zeilen/Spalten erstellt wird, besteht die Möglichkeit, dass dies geschieht (die Anzahl der Spalten wird reduziert, obwohl wir DMatrix ausdrĂŒcklich gesagt haben, wie viele Spalten es gibt). Dies geschieht hĂ€ufig bei kleineren DatensĂ€tzen oder sehr, sehr spĂ€rlichen Spalten, da es wahrscheinlicher ist, dass eine Teilmenge nur Nullen enthĂ€lt.

Geschieht dies zwischen einem Train/Test-Set, kann das Modell das Test-Set nicht auswerten, da es eine andere Anzahl von Features erwartet und einen ValueError ausspuckt.

Ich versuche, einen Test zu finden, bei dem dies innerhalb des xgboost-Kerns und des sklearn-wrapper funktioniert / nicht funktioniert, da ich zuversichtlich bin, was passiert, aber ich weiß nicht, wo es passiert.

@l3link : Ihr Code scheint veraltet zu sein. Folgendes bekomme ich:

In [2]: import scipy
   ...: import xgboost
   ...: matrix = xgboost.DMatrix(scipy.sparse.csr_matrix([[0, 2, 3, 0], [0, 2, 2, 0], [1, 0, 5, 0], [0, 1, 0, 0]], shape=(4,4)))
   ...: matrix.num_col()
   ...:
Out[2]: 4L

In [3]: matrix._init_from_csr??
Signature: matrix._init_from_csr(csr)
Source:
    def _init_from_csr(self, csr):
        """
        Initialize data from a CSR matrix.
        """
        if len(csr.indices) != len(csr.data):
            raise ValueError('length mismatch: {} vs {}'.format(len(csr.indices), len(csr.data)))
        self.handle = ctypes.c_void_p()
        _check_call(_LIB.XGDMatrixCreateFromCSREx(c_array(ctypes.c_size_t, csr.indptr),
                                                  c_array(ctypes.c_uint, csr.indices),
                                                  c_array(ctypes.c_float, csr.data),
                                                  len(csr.indptr), len(csr.data),
                                                  csr.shape[1],
                                                  ctypes.byref(self.handle)))
File:      c:\anaconda2\lib\site-packages\xgboost-0.6-py2.7.egg\xgboost\core.py
Type:      instancemethod

Huch,

In [64]: xgboost.__version__ Out[64]: '0.6'

Signature: matrix._init_from_csr(csr) Source: def _init_from_csr(self, csr): """ Initialize data from a CSR matrix. """ if len(csr.indices) != len(csr.data): raise ValueError('length mismatch: {} vs {}'.format(len(csr.indices), len(csr.data))) self.handle = ctypes.c_void_p() _check_call(_LIB.XGDMatrixCreateFromCSR(c_array(ctypes.c_ulong, csr.indptr), c_array(ctypes.c_uint, csr.indices), c_array(ctypes.c_float, csr.data), len(csr.indptr), len(csr.data), ctypes.byref(self.handle))) File: ~/anaconda/lib/python2.7/site-packages/xgboost/core.py Type: instancemethod

Scheint bizarr, dass meine .6-Version XGDMatrixCreateFromCSR anstelle von XGDMatrixCreateFromCSREx-Anweisungen enthÀlt, die die Form nicht annehmen.
Ist es möglich, dass die osx-Verteilung anders ist?

Ich befĂŒrchte auch, dass es ein grundlegendes Problem beim Umgang mit spĂ€rlichen Matrixen gibt, aufgrund dessen, was @bryan-woods berichtet hat: Sagen wir, wir haben x Nullspalten sowohl im Zug als auch im Test, aber mit unterschiedlichen Indizes => Es wird kein Fehler sein, da "feature_names(self)" die gleiche Feature-Liste fĂŒr beide Sets zurĂŒckgibt, aber die Vorhersagen sind falsch, da die Spaltenindizes zwischen Zug und Test nicht ĂŒbereinstimmen, die nicht Null sind.

Kann mir bitte jemand diese Frage beantworten? Ich bin auf Version 0.4 zurĂŒckgekehrt und jetzt scheint es zu funktionieren, aber ich fĂŒrchte, wenn es richtig funktioniert, weil ich immer noch sehr spĂ€rliche Matrizen verwende.

@l3link nichts Bizarres daran: Versionsnummern (oder Pypi-Pakete) werden manchmal lange Zeit nicht aktualisiert. ZB wurde die Datei https://github.com/dmlc/xgboost/blob/master/python-package/xgboost/VERSION zuletzt am 29. Juli geÀndert und das letzte pypi-Paket https://pypi.python. org/pypi/xgboost/ ist vom 9. August datiert. WÀhrend der Fix am 23. September #1606 eingereicht wurde. Bitte sehen Sie sich den neuesten Code von github an.

Ich hatte dieses Problem, als ich Pandas DataFrame (nicht-sparse-Darstellung) verwendet habe.
Ich habe es ĂŒber df.as_matrix() in numpy ndarray und den Fehler behoben.

Auch ich habe diesen Fehler nach der Konvertierung des Datenrahmens in ein Array behoben.

Das Neuordnen der Spalten im Testset in der gleichen Reihenfolge wie im Zugset hat dies fĂŒr mich behoben.
Ich habe Pandas-Datenrahmen verwendet. Ohne dies fĂŒhrte die Verwendung von .as_matrix() zum gleichen Problem.

Ich tat:

test = test[train.columns]

Ich habe die @warpuv- Lösung

Das Konvertieren von Train/Test-CSR-Matrizen in CSC hat bei mir funktioniert

Xtrain = scipy.sparse.csc_matrix(Xtrain)

Die Konvertierung in csc_matrix funktioniert, getestet auf 0.6a2 :

    X_train = scipy.sparse.csc_matrix(X_train)
    X_test = scipy.sparse.csc_matrix(X_test)

    xgb_train = xgb.DMatrix(X_train, label=y_train)
    xgb_test = xgb.DMatrix(X_test, label=y_test)
type(X_train) <class 'scipy.sparse.csr.csr_matrix'>
type(X_test) <class 'scipy.sparse.csr.csr_matrix'>
type(X_train) <class 'scipy.sparse.csc.csc_matrix'>
type(X_test) <class 'scipy.sparse.csc.csc_matrix'>
type(xgb_train) <class 'xgboost.core.DMatrix'>
type(xgb_test) <class 'xgboost.core.DMatrix'>

Meine ursprĂŒngliche Sparse-Matrix ist die Ausgabe des sklearn tf-idf vectorizers im Format csr_matrix .

Gibt es schon eine Lösung?

Habe gerade die neueste Version (0.7.post3) in Python3 erstellt und ich kann bestÀtigen, dass dieses Problem immer noch besteht. Nachdem ich das obige sehe ich immer noch Probleme mit csr_matrix und csc_matrix .

import xgboost as xgb
import numpy as np
from scipy import sparse

np.random.seed(10)

X_csr = sparse.rand(100, 10).tocsr()
test_csr = sparse.rand(10, 500).tocsr()

X_csc = sparse.rand(100, 10).tocsc()
test_csc = sparse.rand(10, 500).tocsc()

y = np.random.randint(2, size=100)

clf_csr = xgb.XGBClassifier()
clf_csr.fit(X_csr, y)

clf_csc = xgb.XGBClassifier()
clf_csc.fit(X_csc, y)

# Try with csr
try:
    pred = clf_csr.predict_proba(test_csr)
    print("Works when csr with version %s" %xgb.__version__)
except ValueError:
    print("Broken when csr with version %s" %xgb.__version__)

try:
    test_csr[0,(test_csr.shape[1]-1)] = 1.0
    pred = clf_csr.predict_proba(test_csr)
    print("Works when adding non-zero entries to last column with version %s" %xgb.__version__)
except:
    print("Still broken when adding non-zero entries to last column with version %s" %xgb.__version__)

# Try with csc
try:
    pred = clf_csc.predict_proba(test_csc)
    print("Works when csc with version %s" %xgb.__version__)
except ValueError:
    print("Broken when csc with version %s" %xgb.__version__)

try:
    test_csc[0,(test_csc.shape[1]-1)] = 1.0
    pred = clf_csc.predict_proba(test_csc)
    print("Works when adding non-zero entries to last column with version %s" %xgb.__version__)
except:
    print("Still broken when adding non-zero entries to last column with version %s" %xgb.__version__)

Der obige Code fĂŒhrte zu folgender Ausgabe:

Broken when csr with version 0.7
Still broken when adding non-zero entries to last column with version 0.7
Broken when csc with version 0.7
Still broken when adding non-zero entries to last column with version 0.7

bitte hilfe

Warum wurde dieses Thema geschlossen?

Ich bin vor kurzem zweimal auf dieses Problem gestoßen. In einem Fall Ă€ndere ich einfach den Eingabedatenrahmen in ein Array und es funktioniert. FĂŒr den zweiten muss ich die Spaltennamen des Testdatenrahmens mit test_df = test_df[train_df.columns] neu ausrichten. In beiden FĂ€llen haben train_df und test_df genau die gleichen Spaltennamen.

Ich glaube, ich verstehe deinen Kommentar @CathyQian nicht , sind die train_df / test_df spĂ€rlich? Außerdem, welche Version von xgboost haben Sie ausgefĂŒhrt, als Sie auf diese Probleme gestoßen sind?

@CathyQian xgboost basiert auf der _Reihenfolge_ von Spalten, und das hat nichts mit diesem Problem zu tun.

@ewellinger WRT Ihr Beispiel: Ein auf Daten mit 10 Features trainiertes Modell sollte keine Daten mit 500 Features fĂŒr die Vorhersage akzeptieren, daher wird der Fehler ausgegeben. Auch das Erstellen von DMatrices aus all Ihren Matrizen und das Untersuchen ihrer num_col und num_row fĂŒhrt zu den erwarteten Ergebnissen.

Der aktuelle Stand der "Spasity-Probleme" ist:

  • Die DMatrix-Erstellung aus CSR und ihre Verwendung in einem Modell sollten korrekt funktionieren. Das Thema wurde geschlossen, da dies Thema dieses Themas war.
  • Die DMatrix-Erstellung aus CSC erzeugt ein Objekt mit korrekten Abmessungen, kann jedoch wĂ€hrend des Trainings oder der Vorhersage falsche Ergebnisse liefern, wenn die letzten Zeilen vollstĂ€ndig spĂ€rlich sind #2630. Ich hatte noch keine Zeit, das Teil richtig zu reparieren.
  • Ein Parameter zur Angabe einer vordefinierten Spaltenanzahl beim Laden von libsvm-Daten in DMatrix wurde noch nicht implementiert. Ehrenamtliche Mitwirkende sind willkommen.

@warpuv bei mir

Hatte den gleichen Fehler mit dichten Matrizen. ( xgboost v.0.6 von der neuesten Anaconda.)
Ein Fehler ist aufgetreten, als ich mehrere Regressionen fĂŒr verschiedene Feature-Subsets des Trainingsbeispiels ausgefĂŒhrt habe.
Das Problem wurde behoben, indem jedes Mal eine neue Modellinstanz erstellt wurde, bevor eine nÀchste Regression angepasst wurde.

  • Ein Parameter zur Angabe einer vordefinierten Spaltenanzahl beim Laden von libsvm-Daten in DMatrix wurde noch nicht implementiert. Ehrenamtliche Mitwirkende sind willkommen.

Ab 0.8 existiert dies immer noch nicht oder?

Die DMatrix-Erstellung aus CSC erzeugt ein Objekt mit korrekten Abmessungen, kann jedoch wÀhrend des Trainings oder der Vorhersage falsche Ergebnisse liefern, wenn die letzten Zeilen vollstÀndig spÀrlich sind #2630. Ich hatte noch keine Zeit, das Teil richtig zu reparieren.

@khotilov #3553 hat dieses Problem behoben.

Ein Parameter zur Angabe einer vordefinierten Spaltenanzahl beim Laden von libsvm-Daten in DMatrix wurde noch nicht implementiert. Ehrenamtliche Mitwirkende sind willkommen.

@MonsieurWave FĂŒr diese Funktion sollte ein kleiner Pull-Request an dmlc-core den Zweck erfĂŒllen. Lass es mich anschauen.

@hcho3 Vielen Dank.

Im Moment umgehe ich dieses Problem, indem ich die erste Zeile meiner libsvm nicht so spÀrlich habe, dh: sogar die Spalten mit dem Wert 0 speichern.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen