A Feyn tour around the block
Welcome to this quick guided tour. We'll get you set up and taking advantage of your shiny new
QLattice in no time.
richard@feyn:~$ pip3 install feyn
Once installed, go to your preferred Python environment and follow along with this example.
Connect to your QLattice
You're going to need access to a
QLattice to get started. Don't have one? Sign up!
from feyn import QLattice qlattice = QLattice(url = "<URL to your qlattice>", api_token="<Your API token>")
Here's a guide on how to get your URL and API token.
Load an example dataset
To introduce the core concepts of building a
Feyn graph, we will pick a simple classification problem from
sklearn, and load it with
import sklearn.datasets import pandas as pd from feyn.tools import split breast_cancer = sklearn.datasets.load_breast_cancer() input_columns = breast_cancer.feature_names # Load into a pandas dataframe data = pd.DataFrame(breast_cancer.data, columns=input_columns) data['target'] = pd.Series(breast_cancer.target) # Split into train & test train, test = split(data, ratio=(0.67, 0.33))
Set up your QLattice
First, let's read in your example dataset and get a
register for each column.
registers describe your problem - which features go in, and which feature you want to predict. This is often the same as the columns in your dataset, but could also be a subset.
# Create a register for each feature for feature_name in data.columns: qlattice.get_register(name=feature_name)
QLattice is set up and ready for your problem.
How to fit your QGraph
The next step is to retrieve a
QGraph from your
QLattice with the
registers you've defined. The
QGraph is a collection of possible (untrained) graphs between your inputs and output. You can either save those registers in a list to fetch your
QGraph with, or you can just use the label names. We're gonna go ahead and just use the names.
# Get a QGraph of graphs between your inputs and output from the remote QLattice. qgraph = qlattice.get_qgraph(data.columns, 'target') # Now fit the local QGraph with your local data qgraph.fit(train, epochs=10)
While this might, for simple cases, come up with a good solution already, you should ideally run this in a sort of iterative fashion and update the
QLattice with the best results. This will allow it to get better at suggesting
QGraphs and narrow the search space.
This is done by evaluating the
QGraph after fitting, and updating the
QLattice with the best results. This will bias the
QLattice based on your learnings. Each time you update, it will get better at fitting your problem domain.
An update loop could look like this:
no_updates = 3 for _ in range(no_updates): # Get a QGraph. This will be biased with learnings from previous `updates`. qgraph = qlattice.get_qgraph(data.columns, 'target') # Now fit the local QGraph with your local data qgraph.fit(train, epochs=10) # Select the graph with lowest training loss as the best solution. best_graph = qgraph.select(train) # Feed the experience back to the QLattice so it gets smarter for subsequent calls. qlattice.update(best_graph)
Repeat until convergence happens - just as you would in regular machine learning situations.
Notice, that while the
QLattice lives remotely on the Abzu cluster, it never sees your local data. You train locally, and the resulting structure of the graphs is what is transmitted to the
Finally, use the resulting single
graph and evaluate the results on the test dataset.
Here, we explicitly state the input columns, but
Feyn would also filter away the target column if it was included (as it's not being used as input to the
graph). Nifty, huh?
from feyn import tools predictions = best_graph.predict(test[input_columns]) # Round off the results to discretize to 0 or 1 for classification. predictions = predictions.round() tools.plot_confusion_matrix(y_true=test['target'], y_pred=predictions, title="Evaluation Results")