diff --git a/.circleci/config.yml b/.circleci/config.yml index d46ced84..219d2afd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,10 +19,10 @@ jobs: - run: sudo apt-get update - run: pyenv install 3.6.3 - run: pyenv global 3.6.3 - - run: wget https://github.com/graknlabs/grakn/releases/download/v1.4.3/grakn-core-1.4.3.zip - - run: unzip grakn-core-1.4.3.zip - - run: nohup grakn-core-1.4.3/grakn server start - - run: grakn-core-1.4.3/graql console -k test_schema -f kglib/kgcn/test_data/schema.gql + - run: wget https://storage.googleapis.com/kglib/grakn-core-all-20750ca0a46b4bc252ad81edccdfd8d8b7c46caa.zip + - run: unzip grakn-core-all-20750ca0a46b4bc252ad81edccdfd8d8b7c46caa.zip + - run: nohup grakn-core-all/grakn server start + - run: cd grakn-core-all && ./grakn console -k test_schema -f ../kglib/kgcn/test_data/schema.gql - run: bazel test //kglib/... --test_output=streamed --force_python PY3 --python_path $(which python) test-deploy-pip: diff --git a/VERSION b/VERSION index ceab6e11..8eda8749 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.1 \ No newline at end of file +0.1a3 \ No newline at end of file diff --git a/WORKSPACE b/WORKSPACE index e7813e67..5962c8f0 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -42,6 +42,6 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file") http_file( name = "animaltrade_dist", - urls = ["https://github.com/graknlabs/kglib/releases/download/v0.1a1/grakn-animaltrade.zip", # TODO How to update to the latest relase each time? + urls = ["https://storage.googleapis.com/kglib/grakn-core-animaltrade-20750ca0a46b4bc252ad81edccdfd8d8b7c46caa.zip", # TODO How to update to the latest relase each time? ] ) \ No newline at end of file diff --git a/examples/BUILD b/examples/BUILD index 3ebc867b..502f5023 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -36,7 +36,7 @@ py_library( requirement('grakn-kglib'), # Grakn deps - requirement('grakn'), + requirement('grakn-client'), requirement('grpcio'), # TensorFlow deps diff --git a/examples/kgcn/animal_trade/prediction_schema.gql b/examples/kgcn/animal_trade/prediction_schema.gql index 5548397a..d9b5b67c 100644 --- a/examples/kgcn/animal_trade/prediction_schema.gql +++ b/examples/kgcn/animal_trade/prediction_schema.gql @@ -24,7 +24,7 @@ prediction-score sub attribute, datatype double; traded-item has endangerment-level; -value-prediction sub relationship, +value-prediction sub relation, has prediction-score, relates predicted-value, relates predicting-kgcn-model; @@ -49,7 +49,7 @@ match $t1 isa traded-item, has endangerment-level $el1 via $r1; $el1 1; $vp1(pre define -suspicious-activity-detection sub relationship, +suspicious-activity-detection sub relation, relates suspicious-activity, relates cause-of-suspicion; diff --git a/examples/kgcn/animal_trade/schema.gql b/examples/kgcn/animal_trade/schema.gql index d89ba9ec..247a36ac 100644 --- a/examples/kgcn/animal_trade/schema.gql +++ b/examples/kgcn/animal_trade/schema.gql @@ -61,7 +61,7 @@ define has unit-of-measurement, plays quantification-measurement; - exchange sub relationship, + exchange sub relation, relates receiving-country, relates providing-country, relates exchanged-item, @@ -80,11 +80,11 @@ define relates imported-item as exchanged-item, plays corresponding-import; - import-export-correspondence sub relationship, + import-export-correspondence sub relation, relates corresponding-import, relates corresponding-export; - quantification sub relationship, + quantification sub relation, relates quantified-subject, relates quantification-measurement; @@ -111,7 +111,7 @@ define plays originated-species, plays sub-taxon; - hierarchy sub relationship, + hierarchy sub relation, relates superior, relates subordinate; @@ -131,11 +131,11 @@ define relates containing-continent as container, relates contained-country as containee; - species-origination sub relationship, + species-origination sub relation, relates originating-country, relates originated-species; - taxon-membership sub relationship, + taxon-membership sub relation, relates member-item, relates taxonomic-group; diff --git a/examples/kgcn/animal_trade/test/end_to_end_test.py b/examples/kgcn/animal_trade/test/end_to_end_test.py index 47dc066b..553b854a 100644 --- a/examples/kgcn/animal_trade/test/end_to_end_test.py +++ b/examples/kgcn/animal_trade/test/end_to_end_test.py @@ -82,7 +82,7 @@ def test_end_to_end(self): 'external/animaltrade_dist/file/downloaded-unzipped']) # Start Grakn - sub.run(['external/animaltrade_dist/file/downloaded-unzipped/grakn-animaltrade/grakn', 'server', 'start']) + sub.run(['external/animaltrade_dist/file/downloaded-unzipped/grakn-core-animaltrade-1.5.0/grakn', 'server', 'start']) modes = (TRAIN, EVAL) diff --git a/kglib/BUILD b/kglib/BUILD index 38776e58..8e96c7f1 100644 --- a/kglib/BUILD +++ b/kglib/BUILD @@ -138,7 +138,7 @@ py_library( srcs = glob(['__init__.py', 'kgcn/**/*.py']), deps = [ # Grakn deps - requirement('grakn'), + requirement('grakn-client'), requirement('grpcio'), # TensorFlow deps diff --git a/kglib/kgcn/README.md b/kglib/kgcn/README.md index 586a8eeb..188a0a1d 100644 --- a/kglib/kgcn/README.md +++ b/kglib/kgcn/README.md @@ -13,15 +13,15 @@ A KGCN can be used to create vector representations, *embeddings*, of any labell Often, data doesn't fit well into a tabular format. There are many benefits to storing complex and interrelated data in a knowledge graph, not least that the context of each datapoint can be stored in full. -However, many existing machine learning techniques rely upon an *input vector for each example*. This can make it difficult to directly apply many conventional machine learning techniques over a knowledge graph. +However, many existing machine learning techniques rely upon the existence of an *input vector for each example*. Creating such a vector to represent a node in a knowledge graph is non-trivial. -In order to make use of the wealth of existing ideas, tools and pipelines in machine learning, we need a method of building a vector to describe a datapoint in a knowledge graph. In this way we can leverage contextual information from a knowledge graph for machine learning. +In order to make use of the wealth of existing ideas, tools and pipelines in machine learning, we need a method of building these vectors. In this way we can leverage contextual information from a knowledge graph for machine learning. -This is what a KGCN can achieve. Given an example datapoint taken from a knowledge graph, it can examine the nodes in the vicinity of an example, its *context*. Based on this context it can determine a vector representation, an *embedding*, for that example. +This is what a KGCN can achieve. Given an example node in a knowledge graph, it can examine the nodes in the vicinity of that example, its *context*. Based on this context it can determine a vector representation, an *embedding*, for that example. **There are two broad learning tasks a KGCN is suitable for:** -**1. Supervised learning from a knowledge graph for prediction e.g. multi-class classification (currently implemented), regression, link prediction** +**1. Supervised learning from a knowledge graph for prediction e.g. multi-class classification (implemented), regression, link prediction** **2. Unsupervised creation of Knowledge Graph Embeddings, e.g. for clustering and node comparison tasks** ![KGCN Process](readme_images/KGCN_process.png) @@ -46,7 +46,8 @@ In order to build a *useful* representation, a KGCN needs to perform some learni The following is a template of what must be defined in order to instantiate a KGCN, optimised for a downstream learning task of multi-class classification: ```python -import kglib.kgcn.embed.model as model +import kglib.kgcn.core.model as model +import kglib.kgcn.learn.classify as classify import tensorflow as tf import grakn @@ -65,10 +66,16 @@ kgcn = model.KGCN(neighbour_sample_sizes, batch_size) optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate) -classifier = learn.classify.SupervisedKGCNClassifier(kgcn, optimizer, num_classes, log_dir, - max_training_steps=max_training_steps) -training_feed_dict = classifier.get_feed_dict(session, training_things, labels=training_labels) +classifier = classify.SupervisedKGCNClassifier(kgcn, + optimizer, + num_classes, + log_dir, + max_training_steps=max_training_steps) + +training_feed_dict = classifier.get_feed_dict(session, + training_things, + labels=training_labels) classifier.train(training_feed_dict) @@ -80,17 +87,17 @@ There is also a [full example](https://github.com/graknlabs/kglib/tree/master/ex ## Methodology -The ideology behind this project is described [here](https://blog.grakn.ai/knowledge-graph-convolutional-networks-machine-learning-over-reasoned-knowledge-9eb5ce5e0f68), and a [video of the presentation](https://youtu.be/Jx_Twc75ka0?t=368). The principles of the implementation are based on [GraphSAGE](http://snap.stanford.edu/graphsage/), from the Stanford SNAP group, heavily adapted to work over a knowledge graph. Instead of working on a typical property graph, a KGCN learns from the context of a *typed hypergraph*, **Grakn**. Additionally, it learns from facts deduced by Grakn's *automated logical reasoner*. From this point onwards some understanding of [Grakn's docs](http://dev.grakn.ai) is assumed. +The ideology behind this project is described [here](https://blog.grakn.ai/knowledge-graph-convolutional-networks-machine-learning-over-reasoned-knowledge-9eb5ce5e0f68), and a [video of the presentation](https://youtu.be/Jx_Twc75ka0?t=368). The principles of the implementation are based on [GraphSAGE](http://snap.stanford.edu/graphsage/), from the Stanford SNAP group, heavily adapted to work over a knowledge graph. Instead of working on a typical property graph, a KGCN learns from contextual data stored in a *typed hypergraph*, **Grakn**. Additionally, it learns from facts deduced by Grakn's *automated logical reasoner*. From this point onwards some understanding of [Grakn's docs](http://dev.grakn.ai) is assumed. Now we introduce the key components and how they interact. ### KGCN -A KGCN is responsible for deriving embeddings for a set of Things (and thereby directly learn to classify them). We start by querying Grakn to find a set of labelled examples. Following that, we gather data about the context of each example Thing. We do this by considering their *k-hop* neighbours. +A KGCN is responsible for deriving embeddings for a set of Things (and thereby directly learn to classify them). We start by querying Grakn to find a set of labelled examples. Following that, we gather data about the context of each example Thing. We do this by considering their neighbours, and their neighbours' neighbours, recursively, up to K hops away. -![methodology](readme_images/methodology.png)We retrieve the data concerning this neighbourhood from Grakn (diagram above). This information includes the *type hierarchy*, *roles*, and *attribute* values of each neighbouring Thing encountered, and any inferred neighbours (represented above by dotted lines). +![methodology](readme_images/methodology.png)We retrieve the data concerning this neighbourhood from Grakn (diagram above). This information includes the *type hierarchy*, *roles*, and *attribute value* of each neighbouring Thing encountered, and any inferred neighbours (represented above by dotted lines). This data is compiled into arrays to be ingested by a neural network. -Via operations Aggregate and Combine, a single vector representation is built for a Thing. This process can be chained recursively over k-hops of neighbouring Things. This builds a representation for a Thing of interest that contains information extracted from a wide context. +Via operations Aggregate and Combine, a single vector representation is built for a Thing. This process can be chained recursively over *K* hops of neighbouring Things. This builds a representation for a Thing of interest that contains information extracted from a wide context. ![chaining](readme_images/chaining.png) @@ -104,7 +111,7 @@ In order to feed a TensorFlow neural network, we need regular array structures o - Id - Type -- Meta-Type (either Entity or Relationship or Attribute) +- Meta-Type (either Entity or Relation or Attribute) - Data-type (if it's an attribute) - Value (if it's an attribute) - The Role that connects the example to that neighbour diff --git a/kglib/kgcn/core/ingest/encode/encode.py b/kglib/kgcn/core/ingest/encode/encode.py index fa124ad0..71e05108 100644 --- a/kglib/kgcn/core/ingest/encode/encode.py +++ b/kglib/kgcn/core/ingest/encode/encode.py @@ -83,7 +83,7 @@ def __init__(self, schema_tx): "https://tfhub.dev/google/nnlm-en-dim128-with-normalization/1", 128) data_types = list(neighbour.DATA_TYPE_NAMES) - data_types.insert(0, NO_DATA_TYPE) # For the case where an entity or relationship is encountered + data_types.insert(0, NO_DATA_TYPE) # For the case where an entity or relation is encountered data_types_traversal = {data_type: data_types for data_type in data_types} # Later a hierarchy could be added to data_type meaning. e.g. long and double are both numeric diff --git a/kglib/kgcn/core/ingest/traverse/data/context/builder.py b/kglib/kgcn/core/ingest/traverse/data/context/builder.py index 2a904b2f..1c76ea25 100644 --- a/kglib/kgcn/core/ingest/traverse/data/context/builder.py +++ b/kglib/kgcn/core/ingest/traverse/data/context/builder.py @@ -58,7 +58,7 @@ def _traverse_from_thing(self, starting_thing: neighbour.Thing, depth: int, tx): sampler = self._depth_samplers[-depth] next_depth = depth - 1 - # Any concept could play a role in a relationship if the schema permits it + # Any concept could play a role in a relation if the schema permits it # Distinguish the concepts found as roles-played connections = self._neighbour_finder.find(starting_thing.id, tx) diff --git a/kglib/kgcn/core/ingest/traverse/data/context/builder_mocks.py b/kglib/kgcn/core/ingest/traverse/data/context/builder_mocks.py index 6faa65f1..9ce08bf5 100644 --- a/kglib/kgcn/core/ingest/traverse/data/context/builder_mocks.py +++ b/kglib/kgcn/core/ingest/traverse/data/context/builder_mocks.py @@ -31,7 +31,7 @@ def mock_traversal_output(): neighbour.Thing("0", "person", "entity"), [ builder.Neighbour("employee", neighbour.TARGET_PLAYS, builder.ThingContext( - neighbour.Thing("1", "employment", "relationship"), + neighbour.Thing("1", "employment", "relation"), [ builder.Neighbour("employer", neighbour.NEIGHBOUR_PLAYS, builder.ThingContext( neighbour.Thing("2", "company", "entity"), [] @@ -39,7 +39,7 @@ def mock_traversal_output(): ] )), builder.Neighbour("@has-name-owner", neighbour.TARGET_PLAYS, builder.ThingContext( - neighbour.Thing("3", "@has-name", "relationship"), + neighbour.Thing("3", "@has-name", "relation"), [ builder.Neighbour("@has-name-value", neighbour.NEIGHBOUR_PLAYS, builder.ThingContext( neighbour.Thing("4", "name", "attribute", data_type='string', value="Employee Name"), @@ -67,8 +67,8 @@ def find(self, thing_id, tx): role_direction = neighbour.TARGET_PLAYS yield from gen([ - _build_data("employee", role_direction, "1", "employment", "relationship"), - _build_data("@has-name-owner", role_direction, "3", "@has-name", "relationship") + _build_data("employee", role_direction, "1", "employment", "relation"), + _build_data("@has-name-owner", role_direction, "3", "@has-name", "relation") ]) elif thing_id == "1": diff --git a/kglib/kgcn/core/ingest/traverse/data/context/neighbour.py b/kglib/kgcn/core/ingest/traverse/data/context/neighbour.py index 579fbf16..befac944 100644 --- a/kglib/kgcn/core/ingest/traverse/data/context/neighbour.py +++ b/kglib/kgcn/core/ingest/traverse/data/context/neighbour.py @@ -20,7 +20,7 @@ import kglib.kgcn.core.ingest.traverse.data.context.utils as utils -TARGET_PLAYS = 0 # In this case, the neighbour is a relationship in which this thing plays a role +TARGET_PLAYS = 0 # In this case, the neighbour is a relation in which this thing plays a role NEIGHBOUR_PLAYS = 1 # In this case the target DATA_TYPE_NAMES = ('long', 'double', 'boolean', 'date', 'string') @@ -46,20 +46,20 @@ class NeighbourFinder: ATTRIBUTE_ROLE_LABEL = 'has' ROLE_QUERY = { - 'query': "match $thing id {}; $relationship id {}; $relationship($role: $thing); get $role;", + 'query': "match $thing id {}; $relation id {}; $relation($role: $thing); get $role;", 'variable': 'role' } ROLES_PLAYED_QUERY = { - 'query': "match $thing id {}; $relationship($thing); get $relationship, $thing;", + 'query': "match $thing id {}; $relation($thing); get $relation, $thing;", 'role_direction': TARGET_PLAYS, 'target_variable': 'thing', - 'neighbour_variable': 'relationship'} + 'neighbour_variable': 'relation'} ROLEPLAYERS_QUERY = { - 'query': "match $relationship id {}; $relationship($thing); get $thing, $relationship;", + 'query': "match $relation id {}; $relation($thing); get $thing, $relation;", 'role_direction': NEIGHBOUR_PLAYS, - 'target_variable': 'relationship', + 'target_variable': 'relation', 'neighbour_variable': 'thing'} def __init__(self, find_neighbours_from_attributes=True, roles_played_query=ROLES_PLAYED_QUERY, @@ -89,38 +89,38 @@ def _link_iterator(): if target_thing.is_attribute() and self._find_neighbours_from_attributes: yield from self._find_neighbours_from_attribute(tx, target_thing) - # # Connections to entities, relationships and optionally implicit relationships - # yield from self._find_entity_and_relationship_neighbours(query_direction, thing_id, tx) + # # Connections to entities, relations and optionally implicit relations + # yield from self._find_entity_and_relation_neighbours(query_direction, thing_id, tx) - yield from self._find_neighbour_relationships_where_thing_plays_role(tx, thing_id) + yield from self._find_neighbour_relations_where_thing_plays_role(tx, thing_id) - if target_thing.is_relationship(): + if target_thing.is_relation(): yield from self._find_neighbour_roleplayers(tx, thing_id) return _link_iterator() - def _find_neighbour_relationships_where_thing_plays_role(self, tx, thing_id): + def _find_neighbour_relations_where_thing_plays_role(self, tx, thing_id): base_query = self.ROLES_PLAYED_QUERY thing_variable = base_query['target_variable'] - relationship_variable = base_query['neighbour_variable'] - yield from self._get_role_link(tx, base_query, relationship_variable, thing_variable, thing_id) + relation_variable = base_query['neighbour_variable'] + yield from self._get_role_link(tx, base_query, relation_variable, thing_variable, thing_id) def _find_neighbour_roleplayers(self, tx, thing_id): base_query = self.ROLEPLAYERS_QUERY thing_variable = base_query['neighbour_variable'] - relationship_variable = base_query['target_variable'] - yield from self._get_role_link(tx, base_query, relationship_variable, thing_variable, thing_id) + relation_variable = base_query['target_variable'] + yield from self._get_role_link(tx, base_query, relation_variable, thing_variable, thing_id) - def _get_role_link(self, tx, base_query, relationship_variable, thing_variable, thing_id): + def _get_role_link(self, tx, base_query, relation_variable, thing_variable, thing_id): query = base_query['query'].format(thing_id) print(query) link_iterator = self._query(query, tx) for answer in link_iterator: - relationship = answer.get(relationship_variable) + relation = answer.get(relation_variable) thing = answer.get(thing_variable) - if not(relationship.type().is_implicit() or thing.type().is_implicit()): - role_sups = self._find_roles(thing, relationship, tx) + if not(relation.type().is_implicit() or thing.type().is_implicit()): + role_sups = self._find_roles(thing, relation, tx) role = find_lowest_role_from_role_sups(role_sups) role_label = role.label() @@ -131,8 +131,8 @@ def _get_role_link(self, tx, base_query, relationship_variable, thing_variable, yield {'role_label': role_label, 'role_direction': base_query['role_direction'], 'neighbour_thing': neighbour_thing} - def _find_roles(self, thing, relationship, tx): - query_str = self.ROLE_QUERY['query'].format(thing.id, relationship.id) + def _find_roles(self, thing, relation, tx): + query_str = self.ROLE_QUERY['query'].format(thing.id, relation.id) answers = self._query(query_str, tx) role_sups = [answer.get(self.ROLE_QUERY['variable']) for answer in answers] return role_sups @@ -141,7 +141,7 @@ def _find_direct_attribute_neighbours(self, tx, target_thing, thing_id): if target_thing.type().is_implicit(): raise ValueError( - "A target thing has been found to be implicit, but using implicit relationships has " + "A target thing has been found to be implicit, but using implicit relations has " "been optionally disabled") attribute_query = self.ATTRIBUTE_QUERY['query'].format(thing_id) @@ -201,7 +201,7 @@ def build_thing(grakn_thing): type_label = grakn_thing.type().label() base_type_label = grakn_thing.base_type.lower() - assert(base_type_label in ['entity', 'relationship', 'attribute']) + assert(base_type_label in ['entity', 'relation', 'attribute']) if base_type_label == 'attribute': data_type = grakn_thing.type().data_type().name.lower() diff --git a/kglib/kgcn/core/ingest/traverse/data/context/neighbour_test.py b/kglib/kgcn/core/ingest/traverse/data/context/neighbour_test.py index 5f19330a..62d44c9f 100644 --- a/kglib/kgcn/core/ingest/traverse/data/context/neighbour_test.py +++ b/kglib/kgcn/core/ingest/traverse/data/context/neighbour_test.py @@ -78,7 +78,7 @@ def setUp(self): self._res = list(self._neighbour_finder.find(self._grakn_thing.id, self._tx)) -class TestNeighbourFinderFromRelationship(BaseTestNeighbourFinder.TestNeighbourFinder): +class TestNeighbourFinderFromRelation(BaseTestNeighbourFinder.TestNeighbourFinder): query = "match $x isa employment; get;" var = 'x' @@ -87,7 +87,7 @@ class TestNeighbourFinderFromRelationship(BaseTestNeighbourFinder.TestNeighbourF neighbour_type = 'person' def setUp(self): - super(TestNeighbourFinderFromRelationship, self).setUp() + super(TestNeighbourFinderFromRelation, self).setUp() self._res = list(self._neighbour_finder.find(self._grakn_thing.id, self._tx)) @@ -132,18 +132,18 @@ def setUp(self): class TestFindLowestRoleFromRoleSups(BaseGraknIntegrationTest.GraknIntegrationTest): - relationship_query = "match $employment(employee: $roleplayer) isa employment; get;" + relation_query = "match $employment(employee: $roleplayer) isa employment; get;" role_query = "match $employment id {}; $person id {}; $employment($role: $person); get $role;" - relationship_var = 'employment' + relation_var = 'employment' thing_var = 'roleplayer' role_var = 'role' def setUp(self): super(TestFindLowestRoleFromRoleSups, self).setUp() - ans = list(self._tx.query(self.relationship_query))[0] + ans = list(self._tx.query(self.relation_query))[0] self._thing = ans.get(self.thing_var) - self._relationship = ans.get(self.relationship_var) - role_query = self.role_query.format(self._relationship.id, self._thing.id) + self._relation = ans.get(self.relation_var) + role_query = self.role_query.format(self._relation.id, self._thing.id) self._role_sups = [r.get(self.role_var) for r in self._tx.query(role_query)] def test_role_matches(self): @@ -182,20 +182,20 @@ class TestBuildThingForEntity(BaseTestBuildThing.TestBuildThing): base_type = 'entity' -class TestBuildThingForRelationship(BaseTestBuildThing.TestBuildThing): +class TestBuildThingForRelation(BaseTestBuildThing.TestBuildThing): query = "match $x isa employment; get;" var = 'x' type_label = 'employment' - base_type = 'relationship' + base_type = 'relation' -class TestBuildThingForImplicitRelationship(BaseTestBuildThing.TestBuildThing): +class TestBuildThingForImplicitRelation(BaseTestBuildThing.TestBuildThing): query = "match $x isa @has-job-title; get;" var = 'x' type_label = '@has-job-title' - base_type = 'relationship' # TODO do we want to see @has-attribute here? + base_type = 'relation' # TODO do we want to see @has-attribute here? class BaseTestBuildThingForAttribute: diff --git a/kglib/kgcn/core/ingest/traverse/schema/traversal.py b/kglib/kgcn/core/ingest/traverse/schema/traversal.py index ce0df879..62f905ea 100644 --- a/kglib/kgcn/core/ingest/traverse/schema/traversal.py +++ b/kglib/kgcn/core/ingest/traverse/schema/traversal.py @@ -19,7 +19,7 @@ import collections -METATYPE_LABELS = ['thing', 'entity', 'relationship', 'attribute', 'role', '@has-attribute-value', +METATYPE_LABELS = ['thing', 'entity', 'relation', 'attribute', 'role', '@has-attribute-value', '@has-attribute-owner', '@has-attribute'] diff --git a/kglib/kgcn/core/model_test.py b/kglib/kgcn/core/model_test.py index ac992337..77265188 100644 --- a/kglib/kgcn/core/model_test.py +++ b/kglib/kgcn/core/model_test.py @@ -33,7 +33,7 @@ class TestKGCN(unittest.TestCase): - Number of neighbours to sample at each depth - How to sample those neighbours (incl. pseudo-random params) - Whether to propagate sampling through attributes - - Whether to use implicit relationships, or 'has' roles + - Whether to use implicit relations, or 'has' roles - Number of training steps - Learning rate - Optimiser e.g. AdamOptimiser diff --git a/kglib/kgcn/readme_images/KGCN_process.png b/kglib/kgcn/readme_images/KGCN_process.png index b80501c3..44aa0d94 100644 Binary files a/kglib/kgcn/readme_images/KGCN_process.png and b/kglib/kgcn/readme_images/KGCN_process.png differ diff --git a/kglib/kgcn/readme_images/aggregate_and_combine.png b/kglib/kgcn/readme_images/aggregate_and_combine.png index 5e568391..9d68fbb3 100644 Binary files a/kglib/kgcn/readme_images/aggregate_and_combine.png and b/kglib/kgcn/readme_images/aggregate_and_combine.png differ diff --git a/kglib/kgcn/readme_images/supervised_learner.png b/kglib/kgcn/readme_images/supervised_learner.png index 304c5eac..edc144e1 100644 Binary files a/kglib/kgcn/readme_images/supervised_learner.png and b/kglib/kgcn/readme_images/supervised_learner.png differ diff --git a/kglib/kgcn/test_data/schema.gql b/kglib/kgcn/test_data/schema.gql index f7d0450c..47a0fe10 100644 --- a/kglib/kgcn/test_data/schema.gql +++ b/kglib/kgcn/test_data/schema.gql @@ -25,7 +25,7 @@ job-title sub name; date-started sub attribute, datatype date; -ownership sub relationship, +ownership sub relation, relates owner, relates property; @@ -48,7 +48,7 @@ person sub entity, plays member; -affiliation sub relationship, +affiliation sub relation, relates party; membership sub affiliation, diff --git a/requirements.txt b/requirements.txt index d6609fdb..113106a4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ absl-py==0.5.0 astor==0.7.1 decorator==4.3.0 gast==0.2.0 -grakn==1.4.2 +http://repo.grakn.ai/repository/test-pypi-group/packages/grakn-client/1.5.0-5459d5d88a30631c5ebdac3a9b0d5ea6f184c8ae/grakn-client-1.5.0-5459d5d88a30631c5ebdac3a9b0d5ea6f184c8ae.tar.gz grpcio==1.15.0 h5py==2.8.0 Keras-Applications==1.0.6 @@ -20,4 +20,4 @@ tensorboard==1.11.0 tensorflow==1.11.0 tensorflow-hub==0.1.1 termcolor==1.1.0 -Werkzeug==0.14.1 \ No newline at end of file +Werkzeug==0.14.1