title: How can I bind parameters in a scikit-learn pipeline?
body: <p>I have a <code>pipeline</code> object whose hyperparameters I want to optimize using a <code>RandomizedSearchCV</code>, but I need to bind two parameters, in the sense that if one is set to a value the other one is automatically set to the same value.</p>
  
  <p>Here is my concrete case: I chain a PCA which reduces to <code>nbFeature</code> dimensions, to a Keras classifier which requires its input dim <code>nbFeature</code> to be explicited. Obviously this fails when the two do not match. See a toy example below:</p>
  
  
  
  <pre class="lang-python prettyprint-override"><code># setup
  import numpy as np
  from sklearn.pipeline import Pipeline
  from sklearn.decomposition import PCA
  from sklearn.model_selection import RandomizedSearchCV
  from keras.models import Sequential
  from keras.layers import Dense
  from keras.wrappers.scikit_learn import KerasClassifier
  
  # toy data
  n = 500
  p = 100
  X = np.random.normal(size=(n,p))
  Y = np.concatenate((np.zeros(int(n/2)),np.ones(int(n/2))))
  
  # toy pipeline
  nbFeature = 10 # the guy to bind between the PCA and my Keras model
  
  reducer = PCA(n_components=nbFeature)
  
  def myBasicDense(n_feature):
      return KerasClassifier(build_fn=buildfn_myBasicDense,n_feature=n_feature,verbose=0) 
  def buildfn_myBasicDense(n_feature=777):
      model = Sequential()
      model.add(Dense(1,input_dim=n_feature,activation='softmax'))
      model.compile(optimizer='rmsprop',loss='binary_crossentropy',metrics=['accuracy'])
      return model  
  model = myBasicDense(n_feature=nbFeature) # tried using 'reducer.n_components' but this only uses the value once, instead of binding
  
  pipeStep = [('reducer',reducer),('model',model)]
  pipe = Pipeline(pipeStep)
  
  # run RandomizedSearchCV
  # this works only when sampled 'reducer__n_components' and 'model__n_feature' are equal
  gridDist = {'reducer__n_components': [10, 50],'model__n_feature': [10, 50]}
  
  n_iter_search = 2
  optimizedPipe = RandomizedSearchCV(
          refit=True,        
          estimator=pipe,
          param_distributions=gridDist,
          n_iter=n_iter_search,
          scoring='accuracy',
          cv=3,         
          verbose=2,
          random_state=12 # chosen so that is fails on second round...
          )
  
  optimizedPipe.fit(X,Y)
  </code></pre>
  
  <p><strong>So here is my question</strong>: is there a way to specify to a pipeline that two or more of its parameters must always be the same, so that I can grid search for only one of them?</p>
  
  <p>(Alternatively, any workaround is welcome, including a better use of <code>RandomizedSearchCV</code>).</p>
  
  <p>Thanks a lot!</p>