Класс sklearn.cross_decomposition.PLSSVD
в Sci-kit Learn, по-видимому, дает сбой, когда переменная ответа имеет форму (N,)
вместо (N,1)
, где N
— количество выборок в наборе данных.
Однако sklearn.cross_validation.cross_val_score
терпит неудачу, когда переменная ответа имеет форму (N,1)
вместо (N,)
. Как я могу использовать их вместе?
Фрагмент кода:
from sklearn.pipeline import Pipeline
from sklearn.cross_decomposition import PLSSVD
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
# x -> (N, 60) numpy array
# y -> (N, ) numpy array
# These are the classifier 'pieces' I'm using
plssvd = PLSSVD(n_components=5, scale=False)
logistic = LogisticRegression(penalty='l2', C=0.5)
scaler = StandardScaler(with_mean=True, with_std=True)
# Here's the pipeline that's failing
plsclf = Pipeline([('scaler', scaler),
('plssvd', plssvd),
('logistic', logistic)])
# Just to show how I'm using the pipeline for a working classifier
logclf = Pipeline([('scaler', scaler),
('logistic', logistic)])
##################################################################
# This works fine
log_scores = cross_validation.cross_val_score(logclf, x, y, scoring='accuracy',
verbose=True, cv=5, n_jobs=4)
# This fails!
pls_scores = cross_validation.cross_val_score(plsclf, x, y, scoring='accuracy',
verbose=True, cv=5, n_jobs=4)
В частности, он терпит неудачу в функции _center_scale_xy
cross_decomposition/pls_.pyc
с 'IndexError: tuple index out of range'
в строке 103: y_std = np.ones(Y.shape[1])
, потому что кортеж формы имеет только один элемент.
Если я установлю scale=True
в конструкторе PLSSVD
, произойдет сбой в той же функции в строке 99: y_std[y_std == 0.0] = 1.0
, потому что он попытается сделать логический индекс для числа с плавающей запятой (y_std
— это число с плавающей запятой, поскольку оно имеет только одно измерение).
Кажется, это легко исправить, просто убедитесь, что переменная y
имеет два измерения, (N,1)
. Однако:
Если я создам массив с размерами (N,1)
из выходной переменной y
, это все равно не удастся. Чтобы изменить массивы, я добавляю это перед запуском cross_val_score
:
y = np.transpose(np.array([y]))
Затем он терпит неудачу в sklearn/cross_validation.py
в строке 398:
File "my_secret_script.py", line 293, in model_create
scores = cross_validation.cross_val_score(plsclf, x, y, scoring='accuracy', verbose=True, cv=5, n_jobs=4)
File "/Users/my.secret.name/anaconda/lib/python2.7/site-packages/sklearn/cross_validation.py", line 1129, in cross_val_score
cv = _check_cv(cv, X, y, classifier=is_classifier(estimator))
File "/Users/my.secret.name/anaconda/lib/python2.7/site-packages/sklearn/cross_validation.py", line 1216, in _check_cv
cv = StratifiedKFold(y, cv, indices=needs_indices)
File "/Users/my.secret.name/anaconda/lib/python2.7/site-packages/sklearn/cross_validation.py", line 398, in __init__
label_test_folds = test_folds[y == label]
ValueError: boolean index array should have 1 dimension
Я запускаю это на OSX, NumPy версии 1.8.0
, Sci-kit Learn версии 0.15-git
.
Есть ли способ использовать PLSSVD
вместе с cross_val_score
?
y
имеет только один столбец.PLSSVD
принимает SVDX.T.dot(Y)
, который в вашем случае становится вектором-столбцом. Насколько я понимаю, точка частичного наименьшего квадрата состоит в том, чтобы найти скрытые факторы для проецирования какX
, так иY
, где скрытые факторыX
используются для объяснения факторовY
. В этом случае, посколькуY
имеет только одну запись, похоже, что это сводится к простому методу наименьших квадратов. Использование преобразователя дает одномерный вектор, входящий в вашу логистическую регрессию, что кажется довольно бессмысленным. С тем же успехом можно было порог. - person eickenberg   schedule 27.05.2014