Evaluation of the performance of different NoSQL databases using a ranking function for gene identification.
In recent years web applications such as Facebook or YouTube have revolutionized the world of computing due to to the large amounts of information that they manage efficiently and quickly. This fact has led to The companies in charge of managing these Databases have developed various tools to respond to new needs, such as Nosql Databases. The main features of these systems is their operation without large resource needs and with the ability to manage a very high amount of information (the more information stored there, the better its performance and the more efficient will be its management).
With the aim of making a comparison between the best-known systems currently on the market (Neo4j, Titan Cassandra, MongoDB, Cassandra), we have decided to apply a Ranking function used to analyze genes and See which systems offer us the best benefits. To do this, we have created different gene databases with different amounts of connections, classes and genes and, in this way, you can see which system performs the calculations faster in different situations.
Thanks to this, we have come to the conclusion that currently for systems with few resources and not distributed, We will obtain better results with those NoSql databases managed by Neo4J, a system aimed at graphics and with a native language that is very easy to use.
In this report, the activities carried out for the achievement of the project and what tools have been used.
Keywords
Databases, Free Software, NoSql, MongoDB, Cassandra, Titan, Java.
How to read this long-form NoSQL comparison
This page is intentionally extensive because it documents a complete academic project: context, graph model, implementation strategy and performance results. The most useful reading path is to start with the database comparison, then review the graph-ranking workload and finally interpret the benchmark results according to the shape of the data.
If you need a shorter conceptual entry point, read it together with basic NoSQL models, MongoDB updated and Neo4j graph queries.
1. Introduction
The first chapter documents the context, the student's motivation, and the proposed objectives. at the beginning of the project, as well as the work environment and the structure of the entire memory.1.1. Context
In today's society we have millions of examples where we handle large amounts of information, from web applications such as Facebook, Twitter, Instagram or banks with millions and millions of daily transactions. In all these examples, the rapid handling of information and the search for data in their Servers pose a problem because of their large volume and, as a consequence, any operation becomes very complex. To better understand the magnitude of this problem, there are several estimates that state, for example, that there will be an amount of information stored and processed by 2020 of 35,000 Exabytes (1 Exabyte is 1024 Petabytes, and one Petabyte 1024 Terabytes), that the annual Internet traffic is probably close to 8 Exabytes or the content (what we write, tweet, our photos, etc.) can be approximately 500 Exabytes (mmdrigal.com 2014). As we can read, it represents a real challenge for computing to the point of creating a new field for treat these problems. Researchers use a new term, “Big Data” to refer to situations when faced with databases with gigantic amounts of information and have to solve problems in three very different fields: volume, speed and variety.- Volume: companies manage an increasing amount of data of all types, easily accumulating Terabytes, even petabytes, of information.
- Speed: sometimes 2 minutes is too late. In processes in which time counts, such as For example, detecting fraud, large volumes of data must be used in real time to maximize the value.
- Variety: Big data includes any type of data, structured and unstructured, such as text, sensor data, audio, video, click sequences or log files, among others. At By analyzing this data together you will find new information.
1.2. Motivation
The algorithms proposed for this purpose, called ranking algorithms, use graphs loaded entirely into main memory (using data structures such as arrays or adjacency lists) so that they can later catalog the unidentified genes, according to the degree of belonging to a class of genes with which it is related. These methods provide us with a value of probability regarding the membership relationship that exists between a certain gene and a class. Among all the various classification techniques found in the bibliography, in this project, the Score has been used Function based on kernels [Re et al, 2010] that is based on identifying the characteristics of a gene using as basis of information relating to neighboring genes, that is, the vertices that can be reached through the arcs that protrude from the starting vertex. In the new contexts that arise to apply these methods, such as feature prediction genetics in different species or the gene-disease association, the number of genes that should be taken into account consideration, and consequently the size of the graph with which we work, grows exponentially. For this reason, classical ranking algorithms become computationally very expensive or even inapplicable and therefore Therefore, we have to develop new algorithms that allow you to better scale the information while keeping it in a secondary storage or distributing the workload across multiple machines. Furthermore, if we analyze the Current languages or computers on which we can apply the algorithms can only handle a matrix of limited in size and will rarely exceed 50,000 elements, i.e. at most 2,500,000,000 values to maintain in memory. Another characteristic of these matrices is that due to their nature they are dispersed and it is difficult that an element has arcs with all the other elements of the graph. Therefore, this leads to the matrix memorize a large number of values equal to 0 that are not useful for the final calculation. All these new needs have led to an increase in research related to the field of management of massive information, that is, more and more attempts were made to solve the problem of analyzing the “Big Data”. In response to this problem, the NoSQL movement was born in 2009, a group of organizations that propose Innovative systems for managing data sets much larger than those commonly managed by through relational systems. They also propose effective techniques for working with large structures of graphs, and distribute the workload between several machines in a simple and intuitive way. The basis of some NoSQL systems is the possibility of using the MapReduce paradigm [Ghemawat et al, 2004], implemented in the Hadoop library. This technique consists of dividing the problem into a Map function and a another from Reduce, so the Map function converts the lines read from the input file into pairs key-value and the internal logic process this pair, gather all the key values and offer the result to the Reduce function that processes the whole. Among the systems that are part of the NoSQL movement we also include those that manage modeled structures with a graph, such as Neo4J or Titan Cassandra, that is, easily represented with nodes and associations between them nodes. This representation is useful in many modern application cases (e.g. Facebook) since both Data management systems abandon property relationships in favor of a graph-based structure. Other systems that are part of NoSQL systems are, for example, MongoDB where we store the database structures. data in JSON-type documents with a dynamic schema (MongoDB calls that format BSON), making the integration of data in certain applications easier and faster; o Cassandra, a distributed NoSQL database, based on a column storage model and written in Java that has as its main characteristic a great ability to manage large volumes of data in a distributed manner.1.3. Goals
Returning to the main problem, in this final year project we are going to carry out a search for information about "Big Data", apply the knowledge acquired to develop techniques for solve the problem of predicting genetic characteristics when the size of the graphs they manage is of high dimensions. Following the spirit of NoSQL databases we are going to use machines with normal returns (personal computers that we can find in stores and, therefore, a quantity relatively small amount of main memory) to verify to what extent it is possible to analyze gene networks in order to predict the genetic characteristics in them. The ultimate goal is to develop new approaches which will be scalable in the reference applied context. Also, we want to empirically evaluate the complexity of the approaches developed in order to allow the application of classification algorithms to large dimensional graphs. Therefore, to obtain these results it is necessary to rethink the algorithms developed for a representation of the graph matrix in algorithms that work directly on the graph. Furthermore, it is necessary develop algorithms that work locally on a node, rather than end-to-end. This allows to obtain techniques that are more scalable and the ability to parallelize the calculation process. In order to achieve the objectives set in the thesis we have decided to implement the different algorithms with the following NoSQL systems: Neo4J, Titan Cassandra, Cassandra and MongoDB. Each will provide The methods have a different philosophy since their specifications are quite diverse among them. The first of them, Neo4J is a database management system totally oriented to the graph model, Titan Cassandra allows the management of graphs but using a column representation oriented to this purpose, Cassandra represents the graphs through column management and finally MongoDB will use document management structured, which can be used to represent graphs. All these systems allow management in a single machine or on a network. From the approach provided by the methods of prediction of genetic characteristics and functions based on kernel-based functions [King et al, 2012], which is especially fast in main memory, We have carried out different implementations in the NoSQL systems previously explained. After that we have built different benchmarks to evaluate and compare the performance of implementations on a single machine. To verify the accuracy of the results provided in the tests we have compared the values obtained in our implementations with the results obtained in an R implementation provided by the Professor Marco Mesiti. Finally, all the applications that we are going to implement will be characterized by the following requirements:- Performance: We will use the structures that generate a better temporal cost for the applications. For example if we want check if an element is within a collection, the time cost of performing this query to a HashMap is much less than an Array.
- Stability: The application has been designed to handle errors that occur and not terminate unexpectedly.
- Portability: Our clients are programmed in Java, a cross-platform language.
1.4. Description of the general project environment
The project has been developed in two environments different. The first 4 months in a space set up in the University's Database Laboratory degli Studi di Milano as part of an Erasmus exchange and the rest of the course has been alternating between home of the student and some teaching laboratories of the Universidade Positivo de Curitiba (Brazil). In order to check that the project was being developed correctly, a series of weekly interviews were established in which presented the work done to the tutor, in addition to raising possible doubts or discussing some decisions of implementation. When the Erasmus scholarship ended and the exchange with Curitiba began, the weekly meetings were They were done via Skype or email. The computer on which the entire project was developed was an Asus UX31 with an Intel Core I 5 processor. (2.2 GHz) with 4Gb of RAM. The operating system used was Windows 7 and the development tools They are free software. Later in the chapter [5] More details will be given about the development environment.1.5. Document structure
This document reflects the project development process. We begin the project exposing the conclusions that we have made in the initial bibliographic research on NoSQL databases. In the first section, presented as NoSQL Research, the conclusions are presented. obtained about the problem of Big Data for database management. It is divided into different subtasks main ones and describes the four database systems used: Neo4J, MongoDB, Titan Cassandra, Cassandra. The second section presents the ranking methods analyzed from the literature, which algorithms they use. each one and defines in detail the kernel-based Score function applied in the project. Next, it is exposed the concept of cross-validation to evaluate the quality of the ranking. In the third section, with all the initial research completed, the project planning is explained, defining tasks, their duration and estimated completion dates. In the fourth section we are going to present the tools used to carry out this project and why of this election. The fifth section contains how we have built the different database managers and how we have applied the Average Score in each of them. We will begin by explaining in general the Average Score algorithm and cross-validation, and then specify a little more the implementation differences between Neo4J, Titan Cassandra, MongoDB and Cassandra. The fifth chapter explains two very important subtasks. The first we will explain how we have verified the results obtained by the Average Score functions for each of the systems and in the second we will explain how much time has been necessary to perform the calculations for different circumstances. Finally, the final conclusions of the work will be presented in the last chapter.2. Project planning
In this section we are going to comment on the different tasks that have been carried out to carry out the project, as well as a Gantt chart where you can see both the temporal duration of each of them, as well as the different origins that exist between the tasks.2.1. Definition of tasks
Below is They describe what tasks have been necessary to achieve the project. The project can be divided into five major blocks: definition of requirements, learning about Nosql databases, learning about genetic prediction functions, project implementation and results obtained in different examples.- Definition of system requirements This task is divided into two subtasks and its purpose is to obtain the project requirements.
- Investigation of initial requirements Short interviews with the tutor to make clear the functionalities that the project must cover
- Definition of functional requirements Carry out a definition of functional requirements with the data obtained in the previous meeting.
- Research on BigData and the NoSql movement This task is divided into four subtasks and its purpose is to understand what the Big Data problem is and understand how applications are developed to solve this problem using NoSql databases.
- Big Data and the NoSql movement Carry out a search for information about Big Data and analyze the characteristics of the NoSql movement
- Get familiar with Neo4j Learning the basic concepts about Neo4j, its characteristics and the realization of a small algorithm to know its operation.
- Getting to know Titan Cassandra Learning the basic concepts about Titan-Cassandra, its characteristics and carrying out a small algorithm to know how it works.
- Get familiar with MongoDb Learning the basic concepts about MongoDb, its characteristics and the realization of a small algorithm to know how it works.
- Get to know Cassandra Learning the basic concepts about Cassandra, its characteristics and the creation of a small algorithm to know how it works.
- Genetic prediction functions This task is divided into four subtasks and its purpose is to understand what the Big Data problem is and understand how applications are developed to solve this problem using NoSql databases.
- The methods used in reading We analyze whether it is possible to represent a network of genes in a graph, document or columns Subsequently, we will analyze whether it is possible to apply gene identification methods on these structures.
- Kernel-based ranking function Collection of information about this method.
- Cross validation techniques Collecting information about this method for the application in Ranking functions.
- Analysis and development of the different databases used in the project This task is made up of 7 subtasks whose purpose is to carry out different programs that carry out the calculations mathematical requirements demanded by the requirements and compare the efficiency of this operation.
- Analyze and Design the Score function based on Kernels In this task we are going to design the algorithm for a database client. In this way we will define the queries and the methodology to be used later for each database.
- Database implementation in Neo4j Analyze which classes should be created to be part of the system and study the design following the principles performance, usability, availability, scalability, interoperability, stability, operability and cost. You program the corresponding algorithms in Java and check the equality between the results obtained and the theorists.
- Database implementation in Titan Cassandra Analyze which classes should be created to be part of the system and study the design following the principles performance, usability, availability, scalability, interoperability, stability, operability and cost. You program the corresponding algorithms in Java and check the equality between the results obtained and the theorists.
- Database implementation in MongoDb Analyze which classes should be created to be part of the system and study the design following the principles performance, usability, availability, scalability, interoperability, stability, operability and cost. You program the corresponding algorithms in Java and check the equality between the results obtained and the theorists.
- Database implementation in Cassandra Analyze which classes should be created to be part of the system and study the design following the principles performance, usability, availability, scalability, interoperability, stability, operability and cost. You program the corresponding algorithms in Java and check the equality between the results obtained and the theorists.
- Check Results Analyze the results obtained in each of the implementations and verify that they are the desired ones.
- Results This project task consists of applying all the implemented programs on different databases with diverse to analyze the systems with the best performance in each circumstance.
- Conclusions Task to establish conclusions from the results obtained.
- Project documentation Finally, writing the project report can also be considered a task. In this you can see reflected how the project has evolved.

2.2. Gantt chart
The following Gantt chart (figure [2] ) allows view planned durations, start and end dates, and precedence structure at the start of the project development. The work schedule contemplated in the diagram is: Monday to Friday from 9:00 a.m. to 1:00 p.m. and 3:00 p.m. to 16:30.
3.Research on Big Data and the NoSQL movement
Every day humanity produces an increasing amount of information, byte . Suffice it to say that 90% of the information created in the last decades has been produced these last two years. Where do you get all this information from? Virtually everywhere; In today's technological world, You can get information from anything. Whether we are talking about a sensor network, our latest photo uploaded to Instagram or the last message written on Facebook. In this context, the concept of Big Data arises, That is, the term that researchers use to represent the set of information that a organization wants to analyze, but due to its size, analyzing it is very complex. The chapter is organized as follows. In the section [3.1] It introduces a little to the history and concept of Big Data. We explain how the problem evolved and how the NoSQL (Not Only SQL) movement proposed a solution, developing new alternatives to the relational DBMS that existed until now. Among these new database management systems of data, we have explained the basics of: Neo4J in the section [3.2] , Titan Cassandra in section [3.3] , MongoDB in section [3.4] and Cassandra in the section [3.5] . All these systems are characterized by allowing information to be managed organized in graphs, therefore, they allow applying methods for predicting genetic characteristics to meet the objectives of point 1.3.3.1. Big Data and the NoSQL movement
If we analyze the recent history of humanity, in 1995 the The number of people in the world who had access to the Internet was practically non-existent, but in recent years 10 years the situation has taken a turn due to an explosion of the network and an exponential increase in users with new needs. According to data in December 2010, 30% of the world population, approximately 2,000 million people, has access to the Internet and, projections indicate that this tremendous rise will skyrocket in very few years due to the emergence of the mobile Internet and Smartphones (currently an estimated number of 1,038 million Smartphones with Internet access in the world). Thus, the amount of information published, viewed or uploaded by Internet users in today's most popular applications reaches figures simply impressive. Furthermore, it is expected that in the coming years the current amounts of information we are using will be ridiculous as we can see in Figure [3.1] . In the first part of the graph you can see a circle where it compares the amount of information created in 2005 with the information that is expected to be created in 2020. The second graph shows us shows an evolution of the global amount of information and also the existing storage capacity available worldwide. From 2010 to 2012 it is an estimate and from 2012 to 2020 it is a forecast.
- Youtube: Every minute of the day, about 24 hours of video are uploaded to Youtube.
- Twitter: 65 million Tweets are shared by Internet users on this microblogging network; that is, about 45,000 Tweets per minute.
- Facebook: The most popular social network of all and in the entire world has already exceeded 500 million users registered users, who on average produce about 90 units of content each month, which gives a total of 45 billion monthly publications.
- Wikipedia: The popular online encyclopedia that laid the foundations of Web 2.0 by presenting an outline collaborative and open publication has not been immune to this exponential growth, since if in 2001 it had 19,700 pages published, currently this figure is estimated at more than 3.5 million.

- Volume. The volume of data stored in company warehouses has gone from occupying megabytes and gigabytes to petabytes, that is, the physical size of this information is often so large that it is difficult to handle most databases. We can take as an example the New York Stock Exchange, which generates a terabyte of data per day or Twitter, which generates 8 terabytes per day (or 80 MB per second).
- Speed: Information must be processed quickly, often in real time. For example, eBay confronts fraud through PayPal by analyzing five million transactions in real time per day.
- Variety: The variety of data has exploded, going from being stored and structured data, stored in relational databases, to be completely unstructured and contain, for example, audio, video, XML, text, etc.
3.1.1 RDBMS VS NoSQL
Nowadays, any industrial process requires the processing of large amounts of data and to that end paradigms and algorithms oriented to this type of data began to flourish. processing. Big Data analysis generally includes all the data that a company has in its possession and offers several benefits such as leading to new decision-making processes, new marketing ideas or new productive developments. In essence, it allows the company to keep pace with the times and decide its future. Some business processes are capable of producing more than 1 TB of data each day, so they must find a way to parallelize execution and improve query times. First, in response to these new needs, they used relational data management systems ( RDBMS) -- Relational Database Management System) which, with DB2 and Oracle implementations, its simple and intuitive way to represent information in table form. The success of the relational system is was mainly due to the ability to handle operations transactions that comply with the properties ACID:- Atomicity: it is the property that ensures that an operation can never be left halfway in the event of a failure of the system. Then we can consider that an operation is atomic when it is impossible for another part of an system find intermediate steps. For example, in the case of a bank transaction or both the deposit and deduction or no action is taken.
- Consistency: It is the property that ensures that you only start what you can finish. As a consequence, Only those operations will be executed that will not break the integrity rules and guidelines of the database.
- Isolation: it is the property that ensures that one operation cannot affect others. This allows the carrying out two transactions on the same information are independent and do not generate any type of error. This property defines how and when the changes produced by an operation become visible to the other concurrent operations.
- Durability: It is the property that ensures that once the operation is carried out, it will persist and cannot be undo even if the system fails and that in this way the data survives in some way.
- They do not follow a relational model
- They do not use SQL as the main query language
- They have the capacity for horizontal scalability
- efficiently uses indexes and RAM
- has the ability to dynamically add new records and attributes
- they do not follow the ACID property.
- Strong ( c)onsistency: All clients should see the same version of the data.
- High ( TO)vailability: a client must always have at least one copy of the data available, even in the presence of failures.
- ( Q)artition-tolerance: System characteristics should not be degraded, even if the Computation is split across multiple servers.
- Eventual Consistency: Rigid consistency mechanisms such as those present in the bases are not implemented relational data, where the confirmation of a change implies a communication of the same to all nodes let them replicate it. They have a distributed structure where data is generally distributed through distributed hash table mechanisms.
- Horizontal scalability: The system will be able to increase system performance simply by adding more nodes, without the need in many cases to perform any other operation other than indicating to the system which ones are the available nodes. Many NoSQL systems allow you to use Map-Reduce type queries, which can run on all the nodes at once (each operating on a portion of the data) and then gather the results before returning them.
- Fault tolerance and redundancy.
- They do not generate bottlenecks: the underlying problem with SQL systems is that they must transcribe each sentence to be executed and each complex sentence requires, in addition to a further level of execution concrete to be able to be carried out, which is why it constitutes a common, unique and conflictive entry point in performance basis.
- Only what is necessary: they are simple systems that do not have a complex query system or the capacity declarative to perform an exorbitant internal number of operations in a single line.
- Dynamic structure: The data does not have a fixed attribute definition, that is: Each record can contain information in a different form each time, thus being able to store only the attributes that are of interest in each of them, facilitating data polymorphism under the same collection of information. It is also can store complex data structures in a single document, such as storing information about a blog post (title, body text, author, etc.) along with comments and tags poured onto it, all in a single record. Doing so increases clarity (by having all the data related in the same block of information) and performance (you do not have to do a JOIN to obtain the related data, since these are found directly in the same document).
3.1.2 Types of NoSQL databases
The types of NoSQL databases that we can find are:- Key-Value: key-value is the most typical form, like a HashMap where each element is identified by a single key, which allows the recovery of information very quickly. Normally the value is store as an object called blob (Binary Large Objects) which are elements used in databases to store large data that changes dynamically. In this way the content type is not important for the database, only the key and the value associated with it. They are very efficient for readings and writes, plus they can easily scale partitioned values according to their key; by For example, those whose password is between 1 and 1000 go to one SERVER, those from 1001 to 2000 go to another, etc. inside These databases can be found in Google's BigTable, Amazon's SimpleDB, Cassandra, Hadoop, Riak, Voldemort and MemcacheDB among others.
- Document Based: These store information as a document (generally with a structure simple as JSON or XML) and with a unique key. It is similar to Key-value databases, but with the difference that the value is a file that can be understood. If the server understands the data, it can do operations with them. In fact, several of the implementations of this type of database allow very specific queries. advanced over the data, and even establish relationships between them, although they still do not allow joins. We can find MongoDB and CouchDB among the most important of this type.
- Graph Oriented: There are other databases that store information as graphs where the relationships between the nodes are the most important. They are very useful for representing information from social networks. In fact, Relationships can also have attributes and you can make direct queries to relationships, instead of to the nodes. Furthermore, since they are stored in this way, it is much more efficient to navigate between relationships than in a relational model. Obviously, these types of databases are only usable if the information in question can easily be represented as a network. We find Neo4J among others.
- Column Oriented: They store values in columns instead of rows. With this change we gain a lot speed in readings, since if you need to consult a small number of columns, it is very fast to do so but it is not efficient for performing writes. For this reason, this type of solution is used in applications with a low rate of writes but many reads. For example, Cassandra.
3.2. Neo4J
Neo4J is an open source software that allows you to use graph-oriented database and the following configuration is constituted:- Nodes: They are the entities that we are going to represent.
- Relations: They represent associations between entities and always have a start node and another end node. destiny.
- Properties: They represent the attributes that can be stored in both nodes and relationships.
3.2.1 Neo4J in detail
The language used by Neo4J is based on Java and maintains the graph on disk inside an optimized structure. The graph in question will be:- Addressed: Each arc has a direction.
- Fully labeled: Each node has a name that identifies it and each arc has a class.
- Subject to attribute: it is possible to memorize name-value pairs on arcs and nodes.
- Recovery: recovers information after it has been lost due to an error.
- 2-phase-commit: protocol for distributed applications that allows maintaining the ACID property in the transactions.
- Node: contains an entity of our problem and must be associated with a graph. Inside it we can They will define both properties and key-value pairs and will be contained within the same node. Apart from that we can use these properties to access the node that interests us, that is, we can use in queries to find the desired nodes. Additionally, we can access the nodes using two methods. different: indices and traverse that I will explain below.
- Relationship: represents the relationship between the nodes. Each relation has a type that can be used as a search method for when performing an index search. On the other hand, the traverse method does not We could apply here because it serves to consult the nodes. To obtain the nodes through the indexes We have to indicate if we want to obtain the start or end node of the relationship.
- Index: used to obtain a set of nodes or relationships through database queries with parameters associated with the object or objects that we want to obtain.
- Traverse: Used to query the database of a given node. You can analyze the relationships incoming and outgoing through an algorithm (to catch only interested relationships) and define even the number of hops that the algorithm has to complete at most.

3.2.2 Neo4J database management example
To better understand how Neo4J works, we have also built and explained a simple program that allows us to learn everything we need to know before writing more complex algorithms such as Ranking functions for gene analysis.Example
Since our algorithm is going to work with gene graphs, we have considered that the example ideal to show the basic operation of Neo4J could be a simple algorithm that works with a tree genealogical with the following statement: Víctor has adopted a daughter. The first step will be to define all the variables that we want to use during our algorithm and initialize the Neo4J database. To do this we create a HashMap variable <p ,String> with all the properties that we believe are appropriate for our application, which in my case I consider to be they are:
HashMap properties ;
properties.put("online_backup_enabled","false");
properties.put("keep_logical_logs","false");
properties.put("db.mapped_memory","300M");
properties.put("relationshipstore.db.mapped_memory","300M");
properties.put("propertystore.db.mapped_memory","600M");
properties.put("propertystore.db.strings.mapped_memory","500M");
properties.put("propertystore.db.arrays.mapped_memory","0M");
Later we have to start the database. For this we will use the method EmbeddedGraphDatabase() which needs as the first parameter the path where we want to store the information and how optional second parameter the properties we want to give to the database. Immediately after create the system, since the Neo4J documentation [neo4j.com 2014] recommends using the registerShutdownHook method which has been implemented to properly shut down the database when the java virtual machine terminates. So as a result we get:
graphDb = new EmbeddedGraphDatabase(DB_PATH,properties);
registerShutdownHook( graphDb );
The next step in Neo4J is to define the relationships that we are going to use throughout our program, indicating their name and what will be a type of relationship:
enum RelTypes implements RelationshipType { HIJA }
With the relationship created, the The next step is to create the father and daughter nodes, with information about them, for example their name. For We will simply have to carry out the following steps: - First create the nodes:
Node padre;
padre = graphDb.createNode();
Node hija;
hija = graphDb.createNode();
padre.setProperty( "nombre", "Victor " );
hija.setProperty( "nombre", "Andrea" );
Once this is done, now we have to establish the relationship defined as “DAUGHTER” between the parent node and the daughter node:
relacion = padre.createRelationshipTo( hija, RelTypes.HIJA );
In Neo4J it is also allowed add properties to relationships, such as saying that the daughter is adopted:
relacion.setProperty( "tipo", "adoptada" );
As a result we have obtained the figure [3.4] , that is, a graph in which both Víctor and Andrea have represented with two nodes and their family relationship with an arc named “DAUGHTER” that unites them. To store the information that it is adopted, we have simply added a property to the arc that indicates this characteristic. another option that we could use is to create more relationships of the natural daughter and adopted daughter type that will allow us get the same result without giving properties. In our example we see it is very important to quickly access the nodes that identify Victor's daughters and for them the first option is more efficient since with a single consultation we can find all his daughters. 
Relationship r;
padre.getSingleRelationship(RelTypes.HIJA,Direction.OUTGOING );
print("TIENE UNA HIJA DE NOMBRE:")print(r.getEndNode().getProperty("nombre"));
Another very interesting point of Neo4J is access of the nodes through the indices. To do this, our database allows us to define a structure that is called Index. Once it has been created, we only have to indicate what its purpose will be, that is, if it will be used to access nodes or relationships and an identifying name to access it.
public static Index <Node> padreindice;
padreindice=graphDb.index().forNodes("nombre");
With this structure defined, we have to add the nodes that we want to index and the key to access them, such as:
padreindice.add(padre,"nombre","Victor ");
Once this procedure is finished, we can use the get() function provided by the Index interface to obtain the node we want quickly and efficient.
Node recuperar=padreindice.get("nombre", "Victor ").getSingle();
The last type of query What we have left to know is the traverse method. As we had said, it is used to obtain the nodes that we need faster than with indexes. To prepare this type of queries we first have to apply the search algorithm (in our example we have applied breadth first, which consists of analyzing the nodes that are closest to the starting node), the depth of the search, the type of relationship and which node we are interested in (the beginning or the end). As a result, it provides us with a series of vertices that we will have to scroll through to get your information
Traverser t = recuperar.traverse(Order.BREADTH_FIRST,StopEvaluator.DEPTH_ONE,
ReturnableEvaluator.ALL_BUT_START_NODE,RelTypes.HIJA, Direction.OUTGOING);
Finally we have to explain how you use Neo4J transactions. We can see that most of the code exists these two lines of code.
Transaction tx = graphDb.beginTx();tx.success();tx.finish();
Its purpose is to allow the user perform operations on the database without any type of control. At the moment in which we wish store the changes, we will call the success() method and verify that the modifications do not break any rules of system integrity. 3.3. titan cassandra
Titan Cassandra is an open source software that allows you to use database distributed graph-oriented and the following configuration is constituted:- Nodes: They are the entities that we are going to represent.
- Relations: They represent associations between entities and always have a start node and another end node. destiny.
3.3.1 Titan Cassandra in detail.
Titan Cassandra keeps the graph on disk inside a structure oriented to be distributed. The graph in question will be:- Directed or undirected: there are two possible implementations, construct a graph where each arc has a direction or build another one in which all the arches have both directions.
- Fully labeled: each node has a name that identifies it and each arc needs a name to be created.
- Subject to the attribute: it is possible to memorize name-value pairs about arcs and nodes.
- Horizontal scalability. Titan Cassandra has implemented various mechanisms to work with large graphs through the ability to divide the analyzed graph in proportion to the number of clusters that our system has. This philosophy has also been applied to transactions, allowing a simultaneous number of these operations very elevated and even allowing itself to be divided into different servers.
- Consultations. As in all NoSQL database managers, Titan uses Cassandra to perform its queries and manage its structure in a native, effective and intuitive language. Apart from that, the system can make queries by ranges of elements, location or key-value searches and thus locate both vertices and edges.
- Supports the Blueprints System. This property is very interesting because it is an open source interface that offers two advantages:
- Any algorithm written in Blueprints works efficiently and without any adaptation problems on Titan. This also includes all open source software from Tinkerpop, a working group which is responsible for developing new systems for the management and interpretation of graphs.
- Any query written for Titan can be migrated to other graph-oriented database systems which accepts this interface, so there is no dependency on a provider.
- You can transform a graph into JSON. This is very important since there are many applications or even database managers like MongoDB that accept this format.
- It uses a vertex-centered method. Offers the user the possibility of using a special method for the purpose of sorting and indexing the edges incidents (and therefore adjacent vertices) of a vertex according to the labels and properties of the edges. Using this method well when we perform a query on the vertices will provide us with a advantage and linear scans of incident edges (O(n)) can be avoided and graph traversals more fast supervene (O(1) or O(log n)).
- Follow the NoSQL philosophy but try to optimize the space used. Provides optimized disk representation to enable efficient use of storage and speed. access.
- It is open source under the Apache 2 license.
- Node: It contains an entity of our problem and must be associated with a graph. Inside it we can define key-value pairs that will be contained within the same node. Apart from that we can use these properties to access the node that interests us, that is, we can use them in queries to find the desired nodes. It should be said that Titan Cassandra gives by default an id to each node that is created, always has a numerical value and can be used to obtain the nodes we need.
- Relationship: It represents the relationship between the nodes. Each relationship has a name that can be used as a search method for when performing an index search. Apart from that Titan Cassandra also grants an id automatically.
- Index: The system allows us to create indexes to access both vertices and arcs. For them, There are two different methods to differentiate them, one is based on labels (labels) that allow storing indexes to arcs that interest us. The other is based on keys that provide us with the different methods to quickly access vertices.
3.3.2 Titan Cassandra database management example
Once each structure has been explained, the The next step would be to understand a little how you can build an algorithm in Java based on Titan Cassandra to understand all the quirks of your native language before writing more complex algorithms like algorithms for Ranking functions.Example
Since our algorithm is going to work with gene graphs, we have considered the example used in section 4.2.2 as it is ideal for showing the basic operation of Titan Cassandra. to remember the statement we are going to implement a simple algorithm that works with a family tree to represent the following statement: Victor has adopted a daughter named Andrea. The first step of our application will be to initialize the system in order to store the graph. For this, First we will apply the erase( ) method to ensure that there is no other database with the same name as generate conflicts. We have implemented this method because Titan Cassandra does not have any method to delete databases. The algorithm only searches if the folder that we will use to store the database exists. of data and deletes all its content. If we did not use this method, we would have to perform this task manually every time we want to create a new test database Once we are sure that there will be no conflicts, we will have to configure the system. For this, We will have to indicate its characteristics such as, for example, where the information will be stored, if it will be a system local or distributed or what type of indexes we are going to use by applying algorithms such as the following:
BaseConfiguration config;
Configuration storage = config.subset(STORAGE_NAMESPACE);
configuring local backendstorage.setProperty(STORAGE_BACKEND_KEY,"local");
storage.setProperty(STORAGE_DIRECTORY_KEY, directory);
configuring elastic searchindexstorage.subset(INDEX_NAMESPACE).subset("search");
config.setProperty(INDEX_BACKEND_KEY, "lucene");
config.setProperty("local-mode",true);
config.setProperty("client-only", false);
config.setProperty(STORAGE_DIRECTORY_KEY, directory + File.separator + "es");
graph =TitanFactory.open(config);
Once the structure is defined, our graph will fulfill a interface called KeyIndexableGraph that has methods to create indexes and use it for queries on vertices or arches. The methods implemented for this purpose are makeKey intended for vertices and arcs and makeLabel only. for arches. When we apply the sortkey() method to indexes, we are applying the Vertex-Centric philosophy explained previously in subsection 3.2.1. The consequences of this action on the database is a redistribution of the arcs and vertices affected in a special way and more efficient for certain occasions. The only drawback is that to carry out this task we have to invest a lot of time.
.unique().make();tx.makeLabel("hija").manyToMany().sortKey().unidirected().make();With all With this information generated, the next step is to create the father and daughter nodes, with information about them, for example their name. To do this we will simply have to carry out the following steps: - First create the nodes:
Vertex padre = tx.addVertex(null);
Vertex hija = tx.addVertex(null);
padre.setProperty("nombre", "Victor");
hija.setProperty("nombre", "Andrea"); Once this is done, now we have to establish the direct relationship from the parent node to the daughter node as follows:
padre.addEdge("hija", andrea).setProperty("tipo", "Adoptada"); On Titan Cassandra too It is allowed to add properties to relationships, such as saying that the daughter is adopted simply by using the setProperty() method. As a result we have obtained the figure [3.5] , that is, a graph in which both Víctor and Andrea have represented with two nodes and their family relationship with an arc named “DAUGHTER” that unites them. To store the information that it is adopted, we have simply added a property to the arc that indicates this characteristic. another option that we could use is to create more relationships of the natural daughter and adopted daughter type that will allow us get the same result without giving properties. In our example we see it is very important to quickly access the nodes that identify Victor's daughters and for them the first option is more efficient since with a single consultation we can find all his daughters. 
Edge aux=victor.getEdges(Direction.BOTH,"hija");
Vertex resultado=aux.iterator().next().getVertex(Direction.IN);
print(resultado.getProperty("nombre")); Finally, as we had mentioned, Titan Cassandra uses a transaction system that guarantees the integrity of the stored data using the following code:
TitanTransaction tx = graph.newTransaction();tx.commit();
Therefore, all Sentences that are executed between these lines will only be stored if they do not violate any integrity rule. 3.4. MongoDB
MongoDB is an open source software that manages document-oriented databases. In a normal MongoDB system we will always find these three elements:- Document: It is defined as the records or set of data managed by the system. Each of these units is composed of “key-value” pairs where the key is the name of the field and the value is its content, separated by the use of “:” As a value, numbers, strings or binary data can be used as images or any other “key-value” pair.
- Collection: grouping of documents, which could be said to be the equivalent of tables in a relational database. It does not have any limitation regarding the quantity
- Index: The MongoDB system is made to store large amounts of information and, therefore, needs indexes to locate the documents we need and search for the desired values without having to go through all the documents.
3.4.1 MongoDB in detail
MongoDB is an open-source, cross-platform database system. It is written in C++, which gives it a certain proximity to the machine's hardware resources and provides speed to the time to execute your tasks. In addition to being free license software, it works on operating systems Windows, Linux, OS X and Solaris. Its most important features to highlight are:Document-oriented storage
As we have seen in the introduction, MongoDB is oriented to The use of JSON type documents with a dynamic schema called BSON, or Binary JSON, allows searches fast data. To get an idea, BSON explicitly saves the lengths of the fields, the indexes of the arrays, and other useful information for data scanning. This is why, in some cases, the same A document in BSON takes up a little more space than it would if it were stored directly in JSON format. This drawback always exists in NoSQL systems, since it really has a philosophy based on the cheap storage, and as a consequence defends that it is better to use more memory if this introduces a considerable increase in the speed of locating information within a document. An example of this document is the figure [3.6]

Full index support
Indexes in MongoDB have a tree structure called B-Tree. That is, that the data is stored in a tree whose nodes can have a multiple number of children, but keeping all They balanced. This increases the speed when searching and also when returning results. ordered. In fact MongoDB is capable of traversing indexes in both directions, so with a single index, we can achieve both ascending and descending sorting. An important detail that can help us improve our performance efficiency is that the indexes Let's use them with fields that have great cardinality. When we create an index and fill the tree with the information that we want to index, it introduces the elements in certain positions of the tree depending of the content found in the field. Therefore, the more diversity the indexed information has, the more efficient will be the index. In another sense, the system offers us different types of indexes. First, MongoDB indexes all documents with the key _id (explained above), which allows us to quickly access them and avoid having to go through the entire collection to find them. Then it also offers us geospatial indexes, that is, allows indexing of information based on location. Lastly, it also allows indexing fields of a document, to access them without having to go through the entire document.Horizontal scalability
In traditional RDBMS systems, to improve database performance data a more powerful machine is acquired (vertical scaling) while scaling works better in MongoDB horizontal (increase number of machines)Consultations
Other strong points to highlight of MongoDB are its speed and its rich but simple query system for the contents of the database. Following the NoSQL philosophy explained above, has managed to achieve an optimal level of performance and functionality, incorporating types of system queries relational, but without sacrificing performance.Map and Reduce
MongoDB allows us to use Map and Reduce functions to select attributes that interest us in the data, add it, unify it and simplify it as we wish. This is common in many NoSQL systems, and in some cases it is even the only possible way to query data.Absence of transactions
It is really not known whether this is a virtue or a deficiency. what MongoDB not having any system to check that the data entered corrupts the database makes the implemented algorithms are faster but the database manager will not block the “commits” with information wrong3.4.2 MongoDB database management
Once each of its main virtues and deficiencies, the next step would be to understand a little how you can build an algorithm in Java based on MongoDB and thus know its native language before writing the more complex algorithms.Example
Since our algorithm is going to work with gene graphs, we have considered the example used in section 4.4.2 since it is ideal to show the basic operation of MongoDB. To remember the statement we are going to implement a simple algorithm that works with a family tree to represent the following statement: Victor has adopted a daughter named Andrea. The first step will be to define all the variables that we want to use during our algorithm and initialize the MongoDB database. To do this we will first have to know where the server that is located is located. has the MongoDB database stored and connect our program:
MongoClient conn = new MongoClient( "localhost" , 27017 );
Once connected we have to create or search for the database that we are going to use. In the case of the example, first I check that there is nothing in the database and if there is, I delete it and then the structure is created. First the database with the name “Tree” using the getDB() method. This method searches the server if there is a database with that name, if the finds it and returns it, otherwise it creates a new one with that name. Then we create the Family collection within the database “Tree” data that stores all the Documents necessary for its implementation. For this the method getCollection("Family") applied to the db variable will link us to the Family collection if it exists or create it if contrary.
DB db;DBCollection coleccionfamilia;
for (String s : conn.getDatabaseNames()) {
conn.dropDatabase(s);
}
db = conn.getDB("Árbol"); //creamos la base de datos
coleccionfamilia=db.getCollection("Familia");
The last step to finish the construction of our system is create an index to quickly access our document. Indexes in MongoDB are created by applying to the desired collection the createIndex() method and passing it as a parameter the key to access the indexed field that We want together with the value 1 or -1 to indicate whether we want to order them ascending or descending. respectively.
this.coleccionfamilia.createIndex(new BasicDBObject("name", 1));
Once we have created all The structure we want to use the next step would be to store the information within the collection. For We have to remind ourselves that MongoDB works with Documents in JSON format. To do this, Java gives us There are some libraries available that work with this format that will allow us to create and check the structure before enter it into the database. To this end, we have implemented a JSONObject called Victor that inside has stored as properties the name of the person it represents, that is, Victor and the daughters he represents. possesses. This last field has been implemented as a JSONArray, that is, it will be made up of an Array of LinkedHashMap where each of the elements entered must have the name of the girls and the type of relationship she maintains with Víctor (natural or adopted, for example).
JSONObject victor=new JSONObject();
JSONArray hijas=new
JSONArray();
this.victor.put("Nombre","Victor");
LinkedHashMap andrea=new LinkedHashMap();andrea.put("nombre","Andrea");
andrea.put("tipo", "adoptada");
this.victor.put("hijas",andrea);
familia.add(victor);
As a result of this work we have obtained the figure [3.8] . shown below. 
Object classaux = com.MongoDB.util.JSON.parse(x.toString());
DBObject dbObjaux = (DBObject) classaux;
this.coleccionfamilia.insert(dbObjaux);
Once the process is finished we can see the result real in figure 8, that is, a document that represents the person Victor and the number of daughters he has and the relationship that unites them. The important thing about this figure is that in this document we have really stored easy and intuitive the same information as in the graph in the figure [3.9] . 
BasicDBObject query=new BasicDBObject("Nombre","Victor");
System.out.print("Victor TIENE UNA HIJA DE NOMBRE:");
DBCursor f =coleccionfamilia.find(query);while ( f.hasNext()) {
print((f.next().get("hijas")).get("nombre"));
} 3.5. cassandra
Cassandra is an open source software that manages column-oriented databases. In a normal Cassandra system we will always find these elements:- Column: It is the most basic element of the database and is similar to the concept of a field in databases. relational. It has a structure very similar to an associative array since each Column consists of the following three fields:
- Name: array of bytes used to access the stored value.
- Worth: array of bytes that can contain any type of information.
- Timestamp: int64 variable where the last time the Column was modified is stored. There are no restrictions on what the fields can contain. We can enter both in the name as in the value the fields that we want, since as in all NoSQL systems there is no restrictions on stored information.
- SuperColumn: It is an aggregation of n-columns that can be referenced by a name. It is quite a resource useful, since it allows you to have a collection of values associated with a value. As before, there is no restriction on what attributes can contain.
- Row: It is an aggregation of columns or super columns that are referenced with a name contained within a String. That name is the key that uniquely identifies a record. At this point it is important not to confuse a row with a super column. The row is just a keyword, it is not a structure, it lacks attributes such as super columns.
- Column Family: It is an aggregation of rows referenced by a String. It is a similar idea to a Table in the RBDMS model.
- KeySpace: It is an aggregation of column families that can be referenced by a name. It is not a structure with attributes, it is just another container accessed by a String. If we look for the equivalent with the RBDMS models would be a similar idea to the schemas (set of tables) in the relational model.
- Cluster: It is the highest level element that can be referenced by a name. It is more physical in nature. than the previous ones, more related to hardware, since it groups the nodes (machines) on which it runs Cassandra. It can contain one or more keyspaces.

3.5.1 Cassandra in detail
Cassandra is an open source database, developed in Java and multiplatform. Its main feature is the merger of Dynamo, from Amazon, with BigTable, from Google, both being closed source implementations. If we look for a little history about this system, we will realize that it was developed in response to the problems of Big Data described in the introduction. Facebook had a need to improve the performance of the search engine, specifically those related to communication between users (“Inbox Search”) since this functionality involves managing a large volume of data, with a very high growth perspective (we have to think that the social media boom occurred after the implementation of Cassandra). To solve this problem, this system was designed where its main characteristics were: highly scalable queries, horizontal and with a profitable economic cost. After investing Cassandra, in 2008 the Cassandra license was released by Facebook, becoming be open source, and is currently maintained by Apache. This characteristic is what makes Cassandra a really interesting NoSQL database, as it combines the best of Dynamo (eventual consistency) with the best of BigTable (column families) for free. We can observe the consequences of this story in the following characteristics that the system:- Fault tolerance: Data is automatically replicated to multiple nodes. Losing a node does not cause deregister from the cluster.
- Flexible scheme: We have already mentioned previously that columns, super columns and column families can store the values we want.
- Symmetric: All nodes in the cluster are identical, which avoids problems related to bottlenecks.
- Horizontally scalable: As we had already mentioned, it is normal for NoSQL systems to increase their efficiency as more servers are introduced into the system
- Big data support: The ability to scale to hundreds of gigabytes of data.
3.5.2 Cassandra database management
Once each of its main virtues and deficiencies, the next step would be to understand a little how you can build an algorithm in Java based on Cassandra and thus know your native language before writing the more complex algorithms.Example
Since our algorithm is going to work with gene graphs, we have considered the example used in section 4.4.2 as it is ideal for showing basic operation. To remember the statement We are going to implement a simple algorithm that works with a family tree to represent the following statement: Victor has adopted a daughter named Andrea. The first step will be to define all the variables that we want to use during our algorithm and initialize the Cassandra database. To do this we will first have to know where the server is located and connect our program using the connect() method:
connect("127.0.0.1");session = cluster.connect();
Once the connection is made, the session variable will allow us to make modifications or create structures within the system. We can see how in For example, we have used it to perform any task such as defining the structures of our database. data for: - Delete if a Keyspace called Family exists and avoid possible conflicts.
DROP KEYSPACE IF EXISTS Familia; - Create, if it does not exist, a Keyspace called Family. Cassandra allows us to give features to our Keyspace, in order to further optimize the efficiency of the system. In our case we have indicated that it belongs to the SimpleStrategy class (recommended for databases with a single server) and made up of one node.
CREATE KEYSPACE IF NOT EXISTS Familia WITH replication = { 'class':
'SimpleStrategy', 'replication_factor' : 1 };
CREATE TABLE Familia.perez (nombre text PRIMARY KEY, hijas map<text,text>);
INSERT INTO Familia.perez (nombre , hijas) VALUES (“Victor”, { "nombre": "Andrea","tipo": "adoptada"});
As a result we have obtained the [3.11] , that is, a structure in columns that represents the person Victor, the number of daughters he has and the relationship that unites them. We can observe that one of the main features of Cassandra since we have stored it in an easy, intuitive way and without any restrictions information that the graph provided us. 
4. Genetic prediction functions
Ranking functions are those functions that process a set of data, predict the probability of that its elements are associated with each other and indicate the degree of belonging to a certain characteristic, functions or field, that is, a cataloging of data based on already cataloged data. These functions are used in any technological or scientific field, since they create new data from previously information obtained. In this project, ranking functions will be applied to the context of genes, called GFP (Gene Function Prediction).The networks used in GFP always have a large amount of data and therefore we will always have issues related to scalability and performance. If we also add to this that the amount of information grows day after day, there is an urgent need to study and improve the procedures used in studies. As a result of these events, in a few years the use of existing computational methods to identifying characteristics and models have led to the cataloging of millions of genes and the creation of genetic interaction networks that They promise to improve knowledge in this field. To achieve this, a computational approach is used that leads to the definition of a gene and a set of characteristics that characterize it. Then the techniques of machine learning to identify new information from what we know [Pavlidis et al, 2001].The emergence of gene interaction networks has made it possible to analyze data in a different context than that of a single dimension. One of these networks is PPI (protein-protein interaction) and contains associations between the human genes and those of other species [Aebersold et al, 2003]. The data it contains is summarized in the form of graphs or documents and section 4.1 will show its structure.The objective in the analysis methods is to be able to calculate the characteristics associated with each gene in the different types of databases listed in section 2. We have to analyze whether it is possible to use the databases of data for this purpose and what method is most efficient for these systems.As we have mentioned, there are several approaches to solving these problems and we will start by analyzing whether A genetic network can be represented in graphs, documents and columns. We will present these conclusions in the section 4.1. In section 4.2 we will talk a little about the methods of reading data on graphs. In section 4.3 We will analyze the most interesting function for our systems, the kernel-based function. In the last section We will talk about the concept of cross validation, using a kernel-based function.4.1. Data representation
We will use three structures to represent gene networks and their interrelationships, which will be:- Graph for Neo4J and Titan Cassandra
- Document for MongoDb
- Columns for Cassandra
4.1.1 Graph (Neo4J and Titan Cassandra)
This representation will use a graph defined as the pair G = (V, E) where V represents the vertices, which correspond to the genes, and E the arcs that connect them, that is, the relationships between the pairs of genes. The latter may be associated with a weight. The graph structure can be represented in a matrix of adjacency that has the genes as a row and column header and the value in which corresponds to the importance relative of the relationship that connects them. This adjacency matrix, which will be identified with W, is clearly conveyed that is, the number of zeros that contained therein far exceeds the number of relations with different weights from scratch. This is due to the fact of that each gene is put into correspondence with all the other genes and by their nature many genes are not connected by relations, then, a zero appears in the matrix. For this reason, we try to define the algorithms that do use of this feature. An example of matrix W is found in the figure [4.1] , which also represents an example of a format called adjacency list.
- [a)] example of a graph that represents a network of genes. Each node contains a gene, each arc contains a weight which corresponds to the similarity between genes.
- [b)] example of matrix W, corresponding to graph a)
- [c)] formatting the W matrix into an adjacency list takes up less space.
4.1.2 Bson Documents (MongoDB)
The second option to represent the data is through Documents. More exactly JSON style documents with a dynamic schema called BSON, or Binary JSON, already explained in the section 2.4. These documents will be made up of key-value fields (or I put key-value) that will contain the information from each vertex of our network. Each network vertex will be represented with a document that will contain a field called _id, another with the name of the gene and finally an array where we will have stored all the names of the genes. genes that it is linked to and its similarity value with respect to them.As an example, we have made a conversion of the graph in the figure [4.2] to document and we have obtained figure 15 as a result, which is the following:
4.1.3 Columns (Cassandra)
The last of the three representations is in columns. This format is a bit special since it uses keys to access the information. To represent our network in a context like this, we will have to define several fields to place them. First a name to the set of all networks, for example, how our systems are going to represent genes, we can call it “Genes” and it would represent the Keyspace. The next step would be to define its context a little more, such as what purpose our network would have, example genesHumanSpecies and we would have the ColumnFamily defined. And lastly would come each of the columns, corresponding to the vertices of our network. This last structure is really where our vertex because on the one hand it has stored the key-value field with the name of the gene and on the other an array formed by key-value variables with the vertices that have a relationship and the similarity value. In the figure [4.3] We can observe this structure graphically to make this format better understood.
4.2. The methods used in reading
Described below briefly some of the main methods used to predict genetic function. Each method follows one of these approaches:- Direct method: identifies the characteristics of a gene from the connections in the network.
- Assisted method: identifies genes similar to those analyzed, thus the analyzed genes that lack cataloging inherit the properties of those who are similar.
4.2.1 Direct method
To understand the direct methods we are going to use the figure [4.4] shown below.
- [1] Shown is a network in which the functions of certain genes are known (colored in colors different) and others (blank) that are not known.
- [2] The arcs are shown with direction to mark the influence of a gene with respect to another gene
- [3] Finally, it shows us in diagram 3 how the white genes change color after finishing the process. It can also be seen in the image that there are cases where, for example, we have a gene that may have an associated two or more characteristics.
- Neighborhood counting: This method [Schwikowski et al, 2000] predicts gene functions based on the characteristics already known from its immediate neighbors. The problem we have found is its simplicity and, Apart from that, it does not take into account the overall topology of the network, only a very small part.
- Graph: If we think that most networks are essentially a graph, it is normal to think that a method that is Taking advantage of this feature will be more beneficial to us and, if on top of that, the method takes into account the entire topology network (unlike the previous method) we get a more efficient algorithm. Searching for algorithms in this context, we have found the graph method [Nabieva et al, 2005] where takes into account both the global topology and the concept of local neighborhood for each genetic function that we want to analyze. The basic concept is to treat each gene that already has an associated function as the source node of a flow chart. After the simulation, each gene lacking a genetic function is associated with the probability that its function is equal to that of the output gene. This process is carried out for all the genes that They already have an associated function.
- Probabilistic methods: They are based on the concept of MRF (Markov Random Field) and were initially proposed in the article [Deng et al, 2003]. With this method, the function associated with a gene is semi-independent of that of its neighbors. To know if a gene has a genetic function associated with it we will have to use a logarithmic formula which takes into account the number of times said function appears in the network and the number of genes associated with the function. itself and that have relationships with the starting gene.

4.2.2 Assisted Method
As in the previous section, to understand the methods assisted I will explain from the figure [4.6] shown below.
- [1] Shown is a network in which the functions of certain genes are known (colored in colors different) and others (blank) that are not known.
- [2] A division of the network into sets based on density is shown.
- [3] Finally, graph 3 shows us how the white genes change color after finishing the process, taking the color of the one that predominates in the set. You can also see in the image there are cases where, for example, we have a gene, it may have two or more characteristics associated with it.
Generic methods
In these methods the choice of the group is based on the interaction between genes and the decomposition of the network into its topology. One of these methods is MCODE [Bader et al, 2003] which is consists of two main stages:- Nodes are weighted according to a coefficient calculated from the density of neighboring nodes and, therefore, Therefore, they will have a higher weight than nodes with many connections.
- In the second step, the graph is processed by dividing it into sections whose nodes have a large number among them. of connections
Method with hierarchical clustering
This method uses a hierarchical clustering concept to distribute the data into their sets. The advantage of using this approach is being able to choose the measure of similarity between gene pairs. These topics are discussed in [Rives et al, 2003].Graph partitioning methods
There are several methods that follow this approach for graphs. In the article [Spirin et al, 2003] by For example, two quite different categories are presented: those based on SPC (Superparamagnetic clustering) [ Blatt et al, 1996 ] and based on the Monte Carlo method. In both categories they require as input the size of the cluster , but the difference between the two is that SPC works better in densely connected structures, that is That is, if we take this information for the graphs, they would be those with a large number of arcs. Later, based on these methods, other new algorithms were introduced such as RNSC (Restricted Neighborhood Search Clustering) [King et al, 2004] and the MCl [Krogan et al, 2006]:- RNC is an algorithm that, given a network, divides its elements into different sets according to a cost function. Its procedure begins with the creation of a random cluster and subsequently processes all its elements and the reallocates based on maximization of the cost function. To finish the algorithm filters the different groupings according to their size and density.
- In another sense we have The MCL. This algorithm creates an adjacency matrix based on the input network and identifies highly connected areas by creating a set with the elements.)
Conclusion assisted methods
Among the assisted methods that have been listed, MCL is the most robust and with better performance regardless of the chosen graph, whether it has real or simulated data. The tests that performed RNSC that was very intolerant with respect to the input parameters. MCODE and SPC appear lower if the We compare it with the MCL algorithm, although there are some aspects to take into account such as:- MCODE works better if the data is random, it provides a lower number of false positives.
- SPC generates complex structures to promote better sensitivity but at the cost of worsening the specificity.
4.3. Kernel-based ranking function
Among all the algorithms analyzed, the most efficient for To carry out our study on graphs, a kernel-based ranking method included in the direct methods. Presents always the following formula: Its task is to associate a real number with a gene that identifies the degree of membership in a genetic class. The higher this number is, the greater the probability that the gene belongs to that genetic class. The criterion of the distance using a scoring function refers to a Hilbert space, that is, a concept mathematical defined as an inner product space that is complete with respect to the defined vector norm by the inner product [Wikipedia Hilbert 2014]. If there are no arcs in the graph where the exit and entry nodes are identical (that is, all the are equal to 0 for each ) the formula can be reduced by eliminating the first term from the algorithm.To facilitate the understanding of the operations, we have presented an example in the figure [4.7] .
4.4. Cross validation techniques
Cross-validation techniques are used to evaluate the performance of an algorithm based on machine learning. Therefore, we can use this technique to evaluate the efficiency of kernel-based ranking functions. Machine learning deals with algorithms based on the observation of existing data for the synthesis of new knowledge. The learning We can obtain it through information provided by examples, data structures or sensors, with the purpose to analyze and evaluate the relationships between the observed variables. The totality of available data is called dataset and is divided into two parts: a training set and a test set. The training set represents the known data and is consists of a set of elements already cataloged, while the test set is a set of elements lacking cataloging. The algorithm must use the knowledge of the training set to classify with it the elements of the test set. In some cases, however, we can have a training set with few elements or the analysis carried out on the training set has lasted too long. These situations are known as overfitting and although the elements are part of the training set are correct, obtaining new information is difficult. To avoid this drawback, cross-validation techniques have been developed applied in programs discussed in Chapter 6. Cross-validation techniques require a data set of size considerable and provide a criterion of membership, in this way each element can be divided into two sets different, one that has all the positive elements and another with the negative ones. If we talk about genes, the Membership criterion could be, for example, the association of the gene to a genetic class. At this point, all dataset is divided into N sets of similar sizes called folds. The algorithm is performed in cycles of N times changing the fold as an example. Each fold used in a cycle will be considered the test set and has the set of positives and negatives. Once this procedure has finished it is time to perform a estimation of the entire dataset and we can make the necessary estimates. An example of this technique is the figure [4.8] , where we can see how we have divided the genes into two sets, those positive and those negative to a certain class genetics. Subsequently, all genes have been divided equally into 5 folds.
5.Tools and technologies used in the project
In this section we are going to comment on the technologies used to carry out the project. We will start in the first section choosing the programming language we will use. In the second section we are going to comment that tools we have used to develop the project.5.1. Choice of programming language
have to Carrying out programming from scratch gives us the advantage of being able to choose the programming language to be used. use. In this case, 3 languages were initially proposed:- C++
- Python
- Java
5.2. Development tools
For To develop the project the following tools have been used:- Eclipse: used as a Java programming environment.
- Dropbox: as a tool to save backup copies of the project and at the same time have control of versions of each new feature.
- TexMaker: used to make the project report.
5.2.1 Eclipse
Eclipse is an IDE very useful when it comes to Java programming, since it provides many functionalities so that the programming is much more comfortable. Below are the features that have been most useful and that They have undoubtedly reduced the time spent on the project:- Text editor with syntax highlighting.
- Compilation in real time.
- Smart autocomplete.
- Templates to create pieces of code, such as new classes, constructors, loops, etc.
- Automatic reporting of errors and build warnings and suggestions to resolve them.
- Navigation between classes and methods.
- Automatic generation of javadoc, jars and tgzs.
5.2.2 Dropbox
Dropbox is a cross-platform cloud file hosting service, operated by the Dropbox company. The service allows users to store and sync files online and between computers and share files and folders with others. There are free and paid versions, each of which with varied options5.2.3 Texmaker
Texmaker is a free editor distributed under the GPL license for write text documents, cross-platform, that integrates many tools necessary to develop documents with LaTeX, in a single application Texmaker includes Unicode support, spell checking, autocompletion, code folding and a built-in pdf viewer with synctex support and view mode continue.6. Desarrollo del Software
Como ya se ha comentado en el capítulo 1, el objetivo de este proyecto es implementar la función ranking en diferentes sistemas de gestión de bases de datos para comparar su eficiencia y rapidez en el manejo de grandes cantidades de información utilizando un ordenador sin grandes recursos hardware. En la etapa de diseño se intentará crear un diseño flexible y reutilizable de tal forma que permita extender y modificar la aplicación fácilmente. Esta parte se considera fundamental, ya que es probable que en el futuro se disponga de más operaciones para agregar a la aplicación que surja de este proyecto. De esta forma hemos dividido este apartado en varios subapartados como serán: 6.1 Donde analizaremos el análisis y el diseño del proyecto, 6.2 Implementación de la función score basada en kernels para cada una de las tecnologías expuestas, 6.2 Resultados, 6.3 Conclusiones6.1. Análisis y diseño de la función Score basada en kernels
Durante el inicio de esta etapa se ha prestado mucha atención a la distribución de los requisitos del proyecto en diferentes funcionalidades evitando complejidades innecesarias y crear clases o procedimientos inútiles, siempre intentando crear sistemas más fáciles de entender.6.1.1 Diagrama de casos de uso
Se ha comenzado definiendo los posibles casos de uso que puede realizar el usuario. De esta forma se ha obtenido la información sobre la funcionalidad que requiere el sistema. En la figura [6.1] se muestra el diagrama de casos de uso.
6.2. Implementación de la función Score basada en kernels
En este apartado del proyecto vamos a definir la implementación de la función Average Score. Para ello vamos a presentar los diferentes documentos que dispondremos como entrada para generar nuestras bases de datos en la sección 6.2.1 y el resultado final proporcionado en la sección 6.2.2. También expondremos en la sección 6.2.3 cómo hemos implementado los cálculos expuestos en el apartado 3 para obtener las probabilidades y cada uno de los detalles que hemos tenido que enfrentarnos en cada uno de los diferentes sistemas que hemos utilizado: Neo4J, MongoDB, Cassandra , Titan Cassandra.6.2.1 Formato de datos de entrada
Para generar la base de datos donde aplicaremos los cálculos utilizaremos los tres archivos de texto expuestos a continuaciónFile gene.txt
Contiene una columna con todos los genes con todos los nombres de los genes que vamos introducir en la base de datos. Podemos ver un ejemplo de fichero en la siguiente figura [6.2]
6.2.1.2 File geneclasse.txt
Contiene la matriz de adyacencia entre los genes y sus respectivas clases. Cuando en la matriz aparece un valor de 1 corresponde a que el gen de la fila pertenece a la clase de la columna y cuando aparece 0 viceversa. Esta matriz siempre cumplirá la siguiente característica: una clase es definida para un gen y este último puede pertenecer a varias clases. Como se muestra a continuación, en el archivo la primera fila contiene una lista con los identificadores para las clases. Después, las siguientes filas (separadas con un salto de línea) empiezan por el identificador del gen, y una listas de valores con 0 o 1 que nos informan si pertenece (1) o no pertenece (0) un gen a esa clase determinada. Podemos ver un ejemplo de fichero en la siguiente figura [6.3]
File gene-classe.txt
Contiene el valor de similitud entre un par de genes. Las dos primeras columnas obtendremos el identificador de los genes y en la tercera columna su valor de similitud, que siempre será mayor de 0 y menor o igual a 1. En la figura [6.4] se muestra un fichero de ejemplo:
6.2.2 Explicación general del Algoritmo
La finalidad del código que vamos a implementar es generar bases de datos que representen redes de genes en 4 sistemas diferentes, utilizando para ello los tres archivos de entrada que se describen en la introducción de este capítulo. Con este fin los diferentes sistemas nos proporcionan una serie de posibles configuraciones, para optimizar al máximo los recursos de la máquina que disponemos y mejorar la eficiencia en servidores locales sin grandes recursos. Una vez clara estas configuraciones en cada situación, todos nuestros algoritmos siempre empezaran creando bases de datos vacías listas para introducir información y realizar todas las consultas necesarias. El segundo objetivo que tendremos que implementa, son los métodos que se encargará de introducir los vértices que representan los genes, las clases y los arcos que los relacionan entre sí. Para hacer esta tarea, podemos aplicar diferentes filosofías para aumentar más la robustez, la eficiencia o rapidez dependiendo de las necesidades del proyecto. En nuestro caso, nosotros hemos optado por utilizar una versión más robusta ya que si analizamos todo el algoritmo podemos comprobar que los dos últimos métodos requieren la búsqueda de vértices que ya han sido instanciados en los métodos anteriores, es decir, que si analizamos un poco más el código, sería más interesante realizar solamente la llamada de uno o dos métodos y reducir el número de búsquedas en la base de datos y, por lo tanto, disminuir los tiempos necesarios para crear la base de datos. Pero, realmente es preferible realizarlo de este modo porque al estar tratando con bases de datos tan grandes y con tantos elementos existe una probabilidad muy alta de que se produzca un problema en mitad de la ejecución, un fallo en la implementación o un error en la transición, y, en todos esos casos nos resultaría mucho más fácil solucionar el problema si resulta fácil entender la base de datos y en qué estado se encuentra. Los principales pasos para crear la base de datos en cada uno de los sistemas tienen muchas partes comunes que vamos a explicar en los siguientes subapartadosCreación de los genes
Este método se encarga de leer el fichero gene.txt (analizado en el apartado 6.2.1) para poder obtener la lista de genes con la que vamos a interactuar durante el programa. Nuestro algoritmo leerá el fichero de texto línea por línea para ir obteniendo y almacenado cada uno de los nombres de los genes que vamos a utilizar.Creación de las classes
Este método empieza leyendo la primera fila del archivo geneclasse.txt y aplica un split en ella, utilizando como elemento separador el espacio. El contenido obtenido corresponderá a todas las clases de genes posibles que posee nuestra base de datos y será almacenada esta información en un vector. El siguiente paso es recorrer el vector y con cada uno de sus elementos almacenados crear las estructuras que representen las clases.Creación de las conexiones entre genes y clases
Este método empieza igual que el anterior, leemos la primera fila del archivo geneclasse.txt y aplica un split en ella. El contenido será almacenado en un vector que después será utilizado en otra parte del algoritmo. Posteriormente, el método continuará leyendo el resto de información del documento, donde en cada una de las filas realizará el mismo procedimiento:- Realiza un split en la fila para obtener toda la información separada y accesible.
- Lee el primer elemento de la fila (el nombre de los genes) para poder realizar una búsqueda del gen que corresponde.
- Lee los siguientes elementos de la fila que se corresponden con la información de la tabla explicada en el apartado anterior y, por lo tanto, si la celda correspondiente tiene un valor 1, insertamos en la base de datos una relación que indique esta pertenencia del gen a la clase, y si el valor es 0, lo contrario.
- Realizaremos este proceso hasta acabar de leer todo el documento.
Creación de las conexiones entre genes
Este método se encarga de leer el fichero genegene.txt para obtener el valor de similitud entre dos genes, es decir, identificar genes en la base de datos con similares características. El archivo en cuestión está formado por una serie de filas donde, como hemos dicho en el apartado anterior, y mediante un split podremos obtener la información que nos interese y almacenarla en un vector. Los dos primeras partes tendrán almacenado los nombres de los genes que podremos utilizar posteriormente para realizar consultas en la base de datos. Y en la tercera parte del vector tendremos almacenado el valor en forma de entero que representa la similitud entre ellos. Este algoritmo tiene una característica especial. Durante la implementación surgieron problemas de fallos en la creación al tratar con cantidades muy grande de genes y por lo tanto cada vez que se alcanza las 10.000 relaciones analizadas se almacena la información nueva dentro de la base de datos y en caso de parada es necesario que realizar todas las transacciones desde el principio.6.2.3 Validación cruzada
El primer problema que hay que abordar antes de analizar la función de Score para una determinada clase es subdividir los genes en 5 folds. Para realizar los cálculos de una forma más sencilla y optimizada hemos decidido dividir cada uno de los folds en dos subestructuras que almacenen de forma separada los genes positivos y negativos. Todas estas estructuras las hemos creado e implementado en una clase especial llamada Fold donde su constructor será el encargado de realizar todo el proceso. Este método recibe como parámetro una referencia a una clase genética e implementará el pseudocódigo expuesto en la figura [6.5]
- n_fold : cantidad de folds que vamos a utilizar en nuestro algoritmo. Normalmente utilizaremos un valor 5 que es el valor estándar utilizado en la bibliografía consultada.
- positiveGenFold e negativeGenFold : Contendrán almacenados tantos ArrayList como número de fold utilicemos en nuestro algoritmo y su finalidad será ser rellenados con los genes positivos o los negativos respecto a una clase analizada.

6.2.4 Función Score
Una vez que hemos terminado de crear los fold tenemos que proceder con el cálculo de la función de Score, representado en pseudocódigo en la siguiente figura [6.7]
- Obtener todos los genes que pertenecen a la clase investigada, excepto aquellos que ya están dentro del fold analizado. Podemos entender más fácil este proceso en la siguiente figura [6.8]

6.8 Representación de todos los genes que pertenecen a la clase investigada, excepto aquellos que ya están dentro del fold analizado - Recorremos el fold con el objetivo de aplicar el método average score a cada gen que hay almacenado. Como parámetros, este algoritmo necesita el gen que vamos a estudiar junto con la estructura GenesPositive para la clase a la cual puede pertenecer. Para mejorar el rendimiento del programa, hemos implementado el array de GenesPositivo como un hashset ya que las búsquedas de elementos en esta estructura tiene un coste constante y resulta mucho más beneficioso que un array. Respecto al método AvgScore cabe comentar que se encarga de simular los cálculos matemáticos expuestos en la sección 4.2. es decir simulara la función de ranking basada en kernels. El procedimiento empieza obteniendo el valor correspondiente al del gen analizado, es decir, el resultado de dividir 1 entre la raíz cuadrada del valor total de la suma de la similitud que tiene con todos los genes conectados. El siguiente paso es, para todos aquellos genes con los cuales está relacionado y pertenezcan a la clase analizada (está contenido en él has dado por parámetro), realizar el siguiente producto entre:
- el valor de del gen analizado, es decir,
- el valor del gen que está relacionado (se obtiene de la misma forma que el pero lo haces respecto al gen j, que sería en este caso aquel con el que se encuentra conectado).
- el peso de la relación que existe entre ellos.
- Un hastable rellenado con los pares de gen y probabilidad de pertenecer a las clases
- una lista con las clases que hay en la base de dato
- el nombre final que queremos otorgar al fichero.
6.3. Implementación en Neo4J
La primera parte del proyecto se basa en la implementación del algoritmo para Neo4J. Para realizar este experimento hemos utilizado la versión 1.8.2 obtenida del sitio oficial de Neo4J. Esta versión aun no permite la distribución de la información en diferentes servidores pero el equipo desarrollador trabaja en una futura versión que permita esta mejora sustancial.En el siguiente apartado explicaremos cómo hemos utilizado los diferentes mecanismos que nos proporciona Neo4J para resolver los algoritmos expuestos anteriormente. Los subapartados que nos vamos a encontrar son los siguientes:- Diagrama de clases
- Representación de la estructura de la base de datos
- Utilización del método validación cruzada.
- Implementación de la función Score.
- Diagrama de actividades.
6.3.1 Diagrama de Clases

6.3.2 Creación de la estructura
Para crear una base de datos de Neo4J tenemos que diseñar su configuración a partir de la máquina donde realizamos el trabajo. Siguiendo la filosofía NoSQL hemos hemos optado por ejemplo evitar saturar el sistema ocupando mucha memoria, y evitando crear un backup o logs de estados que ocupen mucha memoria. Con la construcción finalizada, tendremos que implementar los métodos que se encargará de introducir los nodos que representan los genes, las clases y los arcos que los relacionan entre sí. Para hacer esta tarea hemos implementado los algoritmos expuestos en el apartado 6.2.2 que utilizara diferentes implementaciones para ver que opción proporciona una respuesta más rápida y eficiente. Como vimos en apartados anteriores, Neo4J es un sistema que gestiona nodos y relaciones. Cada nodo va a representar un gen de nuestra red, cuyo nombre figura en la propiedad “name” dentro del nodo. Cada vez que Neo4J crea un nuevo nodo le asocia una id automáticamente que comienza con 1 y se incrementa para cada nodo añadido. Esta id se convierte en índice automáticamente pero no ocurre lo mismo con la propiedad nombre. Si queremos aumentar la eficiencia en la búsqueda y obtención de nodos la forma más correcta de hacerlo es creando un índice (llamado gene) respecto al nombre, ya que utilizando este parámetro podremos crear consultas a la base de datos mucho más eficientes respecto al tiempo. Cabe señalar que tanto los nombres como los id que crea el Neo4J son únicos y por lo tanto a cualquier consulta que realicemos utilizando este parámetro obtendremos como respuesta un único nodo. Respecto a los nodos que van a representar las clases va a tener una estructura muy similar, la única diferencia con respecto a la creación de los nodos anteriores es que ahora el nombre de la clase se utilizará para crear el índice llamado “class”. Por último, las relaciones van a representar las conexiones que existen entre los genes y las clases de la red. En el caso que la conexión se produzca entre genes lo vamos a representar creando una relación “SIM” y cuando se produzca entre genes y clases la etiquetamos como “class”. Aparte de eso, en las relaciones de tipo “sim” almacenaremos el valor de la similitud entre los dos genes, creando una propiedad llamada “SIM”. Otros aspectos a comentar son las mejoras de rendimiento y robustez que hemos introducido en la implementación de este apartado. Para buscar los nodos que necesitamos en una relación utilizaremos los índices que hemos implementado ya que proporciona una disminución en los tiempos de búsqueda. Respecto a la robustez hemos introducido en todos los métodos que hemos trabajado las transacciones. Las transacciones es una herramienta que nos proporciona Neo4J para que solamente se guarden las modificaciones en el caso en que no se produzca o exista ningún error. El resultado de la implementación de este apartado se muestra en la siguiente figura [6.10]
- : contendrá el valor explicado en la sección 6.2.2.
- type: indicará que el Vertex es un gen. Esta propiedad la utilizaremos en la implementación sin índices para buscar en la base de datos todos los genes que hay almacenados.
- Las relaciones entre los genes las almacenamos de dos formas diferentes para ver el rendimiento del sistema utilizando variables HashMap o ArrayList. Por ello crearemos:
- Relacionesmap: contendrá una variable Hashmap con las relaciones que posee en el nodo. Cada elemento tendrá almacenado como clave el nodo con el que existe la relación y el peso de la relación.
- Relaciones: Propiedad que almacena un ArrayList con el nombre de todas las relaciones.
- Relpesos: Propiedad que almacena un ArrayList con el peso de todas las relaciones.
- type: indicará que el Class es un gene. Esta propiedad la utilizaremos en la implementación sin índices para buscar en la base de datos todos los genes que hay almacenados.
- Positive: tendrá almacenado todos los genes que pertenece a este Nodo.
- Negative: tendrá almacenado todos los genes que no pertenecen a este Nodo.

- Anyadirpropiedadesclases(): Se encarga de añadir a los nodos que representan las clases genéticas las propiedades type, positive, negative.
- Anyadirpropiedadesclases(): Se encarga de añadir a los nodos que representan los genes las propiedades type, relaciones, relpesos, relacionesmap.
- Neo4Jstore(String, int , int, String): Constructor de la clase. El primer parámetro que recibimos puede contener la siguiente información
- “crea”: Construye una nueva base de datos.
- “aggiorna”: Actualiza la base de datos
- “aggiornadati”: Actualiza datos que están dentro de la base de datos
- aggiorna(): Método para actualizar la base de datos.
- aggiornadati():Actualiza datos que están dentro de la base de datos
6.3.3 Validación cruzada
Las modificaciones que permiten adaptar este algoritmo (explicado en la sección 6.2) a las bases de datos de Neo4J son pocos, como por ejemplo que los arrays positiveGenFold e negativeGenFold van a gestionar Nodos. La única diferencia sustancial la vamos a encontrar en el método findNodesClassType() ya que es posible desarrollarla con diferentes filosofías. Los dos métodos de la clase Fold resultantes han sido:- findNodesClassType():Esta función se encargará de realizar rápidamente una consulta en la base de datos para buscar todos los arcos del tipo “class” que salgan del nodo proporcionado como argumento. Como podemos observar Neo4J es muy intuitivo, al ser una base de datos NOSQL orientada a grafos, nuestra consulta simplemente tendrá qué buscar todos los arcos salientes del tipo “class” que salgan del nodo de la clase analizada. Para realizar la consulta podremos utilizar parámetros como por ejemplo que el tipo de búsqueda utilizaremos en el grafo, que relaciones vamos a buscar, a qué profundidad o cuántos nodos vamos a analizar. El resultado será devuelto mediante una variable del tipo iterable y por lo tanto con un simple for podemos recorrerla y almacenar en un array el contenido de la búsqueda, es decir todos los genes positivos respecto la clase. Con esa información podremos obtener la lista de los genes negativos y, por lo tanto, todos los genes que no estén en esta lista, serán negativos respecto a la clase y tendremos también el array con los vértices negativos.
- findNodesClassTypelocal():Esta función utiliza la implementación más local de la información. Como no existen las relaciones, para obtener los genes positivos a la clase solamente tenemos que buscar la propiedad positive que contiene esta información. Una vez obtenida es almacenada en una variable y devuelta para realizar los cálculos necesarios. El mayor problema que nos vamos a encontrar para crear esta función es que Neo4J solamente puede gestionar String en las propiedades. La solución por la que hemos optado es utilizar las funciones replace() y split() de la librería String de Java para obtener los nombres de los genes y mediante la función getGeneByName obtener el gen deseado.
6.3.4 Score
En la clase Scoring las modificaciones también están relacionadas con el sistema de consultas de Neo4J.Primero de todo hemos implementado 3 métodos especiales para conseguir el correcto funcionamiento de la función Score que son:- setD(): este método recorre todos los genes de la base de datos para calcular el valor de que posee el gen analizado. Una vez que ha sido calculado lo almacena en el Nodo como . Para realizar esta tarea simplemente recorre todas las relaciones tipo “Sim” que posee el nodo analizado con el método getRelationships(). Este método de Neo4J va asociado a los vértices, recibe como parámetro el tipo de relación que estamos buscando y nos ofrece como resultado un iterador que recorre todas aquellas que están conectadas a nuestro nodo. El siguiente paso es ir cogiendo el valor de similitud almacenado anteriormente y sumar todos los valores para obtener el .
- AvgScore(): Con la función getRelationships() podremos recorrer todas las conexiones del gen analizado para obtener los valores de similitud y de los vertex que necesitamos.
- AvgScoreVersiónLocal() Este método utiliza las propiedades que hemos almacenado en el nodo y que contiene toda la información de sus relaciones. Podemos obtener el nombre de las conexiones a través de la propiedad “relaciones”, el valor de la propiedad llamada igual, el valor de similitud de sus conexiones a través de la propiedad “relpesos” y el valor Djj del Nodo con el método getGeneByName() dando como parametro el gen que nos interesa.
- AvgScoremap(): Misma metodología que el anterior pero ahora la información de las relaciones y el valor de la similitud la obtendremos de la misma estructura, un hashmap almacenado en la propiedad relacionesmap.
- rankingAvg() Función encargada de realizar los procedimientos para llevar los cálculos de ranking
6.3.5 Modelo de ejecución/navegación
Una vez descritos los posibles casos de uso que puede ejecutar el usuario junto con sus flujos de eventos vamos a describir la navegación que se puede realizar en la aplicación.figura [6.12]
6.4. Implementación en Titan Cassandra
A continuación vamos a comentar la implementación del AvgScore para Titan utilizando Cassandra como base. Para realizar este experimento hemos utilizado la versión 0.4.0 de Titan para la gestión de grafos y 1.2.2 de Cassandra para almacenar la información, ambas obtenidas del sitio oficial de Titan. En los siguientes apartados explicaremos cómo hemos utilizado los diferentes mecanismos que nos proporciona Titan para resolver los algoritmos expuestos anteriormente. Los subapartados que nos vamos a encontrar son los siguientes:- Diagrama de clases
- Representación de la estructura de la base de datos
- Utilización del método validación cruzada.
- Implementación de la función Score.
- Diagrama de actividades.
6.4.1 Diagrama de clases

6.4.2 Creación de la estructura
Para crear una base de datos de Titan tenemos que diseñar su configuración a partir de las características del sistema que vamos a utilizar, es decir, un sistema no distribuido, en local y con índices de estructura Lucene que aprovechan estas características. Antes de continuar con la creación de los genes y sus conexiones tenemos que definir todos los índices que utilizaremos para aumentar la eficiencia de nuestro algoritmo, ya que el sistema necesita primero crear los índices para después rellenarlos con los vértices que contienen la información de forma automática. Con la estructura finalizada, tendremos que implementar los métodos que se encargará de introducir los genes, las clases genéticas y los arcos que los relacionan entre sí. Para hacer esta tarea hemos implementado los algoritmos expuestos en la sección 6.2.2 pero adoptando el código para este sistema y sus necesidades. En este sentido tenemos que recordar el sección 3.3 del proyecto donde hemos presentado las característica del sistema Titan y hemos explicado como no soporta eficientemente grafos con una cantidad muy elevada de conexiones. Sabiendo este hecho y para intentar obtener la mejor implementación posible de nuestros algoritmos hemos creado dos estructuras muy diferentes, una primera que crea las conexiones básicas para realizar consultas mediante arcos y otra en la que introduce esta información en las propiedades de los genes almacenados en la base de datos. Nuestra intención es comparar en los resultados estas dos implementaciones para ver cuál obtiene los mejores resultados.Versión con Vertex y Edge
Para hacer este experimento lo primero que debemos recordar es que Titan es un sistema que gestiona objetos llamados Vertex y Edges. Estas clases se corresponden a los vértices y los arcos de un grafo y las vamos a utilizar para representar los genes y sus conexiones respectivamente. Para ellos crearemos genes a través de los métodos de la clase Vertex con las siguientes propiedades:- nameGen: almacena el nombre del gen.
- type: indicará que el Vertex es un vertex
- nameClass: nombre de las clases.
- type: indicará que el Vertex es una clase.

Versión con Vertex
La otra implementación posible es almacenar toda la información necesaria para los cálculos en los vértices. Aparte de las propiedades comentadas en la implementación anterior, al no existir la posibilidad de utilizar arcos para encontrar sus conexiones, tendremos que crear más propiedades en el Vertex que representa el gen para almacenar esta nueva información. Con esa idea hemos añadido las siguientes propiedades:- : contendrá la división de 1 entre la raíz cuadrada del valor de la suma de todas las relaciones.
- relaciones: array con todos los genes que tiene una conexión de similitud.
- pesosrelaciones: array con el valor numérico de la similitud. Existe una correlación entre este array y la propiedad relaciones.
- pesosrelacionesdjj: array con el valor numérico de Djj. Existe una correlación entre este array y la propiedad relaciones.

- create(String,String):El primer parámetro que recibimos contiene el nombre del directorio donde crear nuestra base de datos y el segundo donde almacenar los tiempos de nuestro programa. Dentro de este método está todos los procesos para la creación de nuestra estructura.
- setD(): este método recorre todos los genes de la base de datos para calcular el valor de que posee el gen analizado. Una vez que ha sido calculado lo almacena en el Vertex como una propiedad llamada “ ”. Para realizar esta tarea simplemente obtenemos el array con todos los valores de similitud llamado “pesosrelaciones” y realizamos los cálculos matemáticos pertinentes.
6.4.3 Validación cruzada
Las modificaciones que permiten adaptar este algoritmo (explicado en el apartado 6.2.2) a las bases de datos de Titan empiezan por modificar en la clase Fold los arrays positiveGenFold e negativeGenFold para gestionar Vertex, las clases que van a representar nuestros genes. La siguiente diferencia la vamos a encontrar en el método findGenesClassType(). Esta función nos proporciona como resultado todos los Vertex positivos y negativos a una clase y para este sistema de gestión de bases de datos hemos implementado dos métodos diferentes para realizar esta tarea: findGenesClassTypeEdge y findGenesClassTypefindGenesClassTypeEdge
Esta función se encargará de realizar una consulta en la base de datos para buscar todos los arcos del tipo “class” que salgan del Vertex proporcionado como argumento. La consulta simplemente tendrá que buscar todos los arcos salientes del tipo “class” que salgan del nodo de la clase analizada utilizando el getEdges().El resultado será devuelto mediante una variable del tipo iterable y por lo tanto con un simple for podemos recorrerla y almacenar en un array el contenido de la búsqueda, es decir todos los genes positivos respecto la clase. Con esa información podremos obtener la lista de los genes negativos y, por lo tanto, todos los genes que no estén en esta lista, serán negativos respecto a la clase y tendremos también el array con los vértices negativos.findGenesClassType
Esta función utiliza la implementación más local de la información. Como no existen las relaciones, para obtener los genes positivos a la clase solamente tenemos que buscar la propiedad positive que contiene esta información. Una vez obtenida es almacenada en una variable y devuelta para realizar los cálculos necesarios. El mayor problema que nos vamos a encontrar para crear esta función es que Titan cassandra no puede gestionar arrays de mucho tamaño. La solución por la que hemos optado es dividir los arrays en diferentes propiedades y por lo tanto tendremos que leer más de una propiedad para obtener los genes positivos y negativos a la clase.Otros métodos
Aparte de estos dos métodos la implementación de la validación cruzada se realizará en la clase Fold.6.4.4 Score
En la clase Scoring las modificaciones también están relacionadas con el sistema de consultas de Titan. Hemos implementado métodos especiales para conseguir el correcto funcionamiento de la función Score con la intención de adaptar todas las consultas al sistema Titan utilizado. Los métodos utilizados más importantes en esta clase son:- AvgScore(): Esta función realiza los cálculos matemáticos a partir de las propiedades que hemos almacenado en los Vertex. A partir de las etiquetas “ ” , ”pesosrelaciones” y “pesosrelacionesdjj” podremos obtener el valor de , el peso de similitud y los valores Djj respectivamente.
- AvgScore(): Esta función utiliza la clase Edge para obtener la información necesaria para realizar el Average Score. Mediante la función gedEdge podremos recorrer todas las conexiones del gen analizado para obtener los valores de similitud y de los vertex que necesitamos o, por otra parte, AvgScoreVertex().
6.4.5 Modelo de ejecución/navegación
Una vez descritos los posibles casos de uso que puede ejecutar el usuario junto con sus flujos de eventos vamos a describir la navegación que se puede realizar en la aplicación.
6.5. MongoDb
En los siguientes apartados explicaremos cómo hemos utilizado los diferentes mecanismos que nos proporciona MongoDb para resolver los algoritmos expuestos anteriormente. Los subapartados que nos vamos a encontrar son los siguientes:- Diagrama de clases
- Representación de la estructura de la base de datos
- Utilización del método validación cruzada.
- Implementación de la función Score.
- Diagrama de actividades.
6.5.1 Diagrama de clase

6.5.2 Representación de la estructura
El siguiente punto del proyecto es la implementación del algoritmo para MongoDb. Para realizar este experimento hemos utilizado la versión 2.11.3 de MongoDb obtenida del sitio oficial. En el próximo apartado explicaremos cómo hemos utilizado los diferentes mecanismos que nos proporciona este sistema para resolver los algoritmos expuestos anteriormente. Empezaremos primero con la creación de la base de datos y como representa la información almacenada para después implementar la función del Score, utilizando siempre como método de verificación el algoritmo validación cruzada.Estructura
Como habíamos expuesto en el apartado 3.3, MongoDb tiene una estructura orientada a documentos del tipo Json y, por lo tanto, tendremos que empezar creando los documentos que posteriormente vamos a introducir en la base de datos. Los documentos que representen a los genes los almacenaremos en la colección genes y tendrán siempre la siguiente propiedades clave valor:- _id: Campo hexadecimal utilizado como identificador del documento. Utilizaremos las id proporcionadas por el sistemas, explicadas en el apartado 2.
- name: Nombre del gen analizado.
- clases: Array donde almacenamos las clases en las que pertenece el gen representado.
- : valor numérico que representa este concepto matemático.
- rel : array donde almacenamos el valor de los genes con los que tiene relación.
- inforel:array con los valores de similitud de cada relación
- rel: array con el valor de la similitud que existe con los genes que está relacionado
- relname: array con los nombres de los genes que posee relación.

- _id: Campo hexadecimal utilizado como identificador del documento. Utilizaremos las id proporcionadas por el sistemas, explicadas en el apartado de Mongodb 3.2.
- Nombre: Nombre de la clase analizada.
- Gene: Array con los nombre de los genes que pertenecen a la clase
- Genenoclass”: Array con los nombre de los genes que no pertenecen a la clase
- "tuttoclass" : que contendrá "infclass" almacenado.
- infclass”: Array con los nombre de las clases almacenadas en el sistema.

- id: Campo hexadecimal utilizado como identificador del documento. Utilizaremos las id proporcionadas por el sistemas.
- Nombre: Nombre de la conexión genética analizada. Estará formada por el nombre de los dos genes entre los que hay una relación, primero el saliente y después el entrante. Hemos optado por crear las relaciones en ambos sentidos, es decir si existe una conexión entre X e Y hemos creado dos documentos diferentes, uno llamado XY y otro YX.
- Weight: Valor numérico que contiene el valor de similitud de la conexión genética
- : Valor numérico que contiene que correspondería a este campo matemático
- Djj: Valor numérico que contiene que correspondería a este campo matemático

6.5.3 Validación cruzada
Las modificaciones que permiten adaptar este algoritmo (explicado en el apartado 6.2.2) a las bases de datos de MongoDb empiezan modificando los arrays positiveGenFold e negativeGenFold para gestionar String. El método findNodesClassType() ya no realizará búsquedas en vértices de grafos . Esta función se encargará de realizar consultas en la base de datos para buscar los documentos que poseen propiedades otorgados por parámetros. Con el lenguaje nativo de MongoDb, simplemente buscaremos y obtendremos de la colección de clases el documento que representa a la clase analizada. De este documento le indicaremos que queremos obtener obtener las propiedades gene y genenoclass para devolver la lista de los genes positivos y negativos a esa clase. Aparte de estos dos métodos la implementación de la validación cruzada se realizará en la clase Fold.6.5.4 Score
En la clase Scoring las modificaciones están relacionadas con el sistema de consultas de MongoDB y sus diferentes implementaciones. Primero de todo hemos implementado 3 métodos especiales para conseguir el correcto funcionamiento de la función Score que son:- AvgScore(): Para utilizar este método en la implementación las modificaciones que deberemos realizar estarán relacionadas con la búsqueda de documentos y extracción de sus propiedades. El primer paso es localizar en la colección de documentos de genes el documento que representa nuestro gen. Para ello simplemente tendremos que comprobar que el campo “name” de nuestro documento coincide con el nombre de Gen. Una vez encontrado tendremos que extraer los campos “ ”, “rel” y “info ” y a partir de ellos extraer toda la información que nos proporcionan y realizar las operaciones matemáticas necesarias.
- AvgScoreVersionRelaciones() Este método utiliza la colección relaciones para obtener la información de los genes conectados entre sí. Para obtenerla tenemos que buscar la relación y extraer la información, de un tamaño menos que el AvgScore()o el AvgScoreHashMap();
- AvgScoreVersionHashMap():En esta implementación pasamos de utilizar estructuras del tipo arrayList para almacenar la información de las relaciones para utilizar HashMap. De este modo las consultas devuelven menos información y puede ser gestionada más eficientemente. Para llevar a cabo esta idea utilizaremos la información almacenada en la propiedad "rel".
6.5.5 Modelo de ejecución/navegación
Una vez descritos los posibles casos de uso que puede ejecutar el usuario junto con sus flujos de eventos vamos a describir la navegación que se puede realizar en la aplicación.
6.6. Implementación en Cassandra
El siguiente punto del proyecto es la implementación del algoritmo para Cassandra. Para realizar este experimento hemos utilizado la versión 2.0.6 obtenida del sitio oficial. En los siguientes apartados explicaremos cómo hemos utilizado los diferentes mecanismos proporcionados por Cassandra para resolver la función Score basada en Kernels. Los subapartados que nos vamos a encontrar son los siguientes:- Diagrama de clases
- Representación de la estructura de la base de datos
- Utilización del método validación cruzada.
- Implementación de la función Score.
- Diagrama de actividades.
6.6.1 Diagrama de clase

6.6.2 Representación de la estructura
Como habíamos expuesto en la sección 2.5, Cassandra tiene una estructura orientada a columnas y, por lo tanto, empezaremos definiendo como son estas estructura que posteriormente vamos a introducir en la base de datos. Las dividiremos en tres apartados según representen a genes, clases o relaciones. Las column que representen a los genes los almacenaremos en la ColumnFamily llamada Genes y tendrán siempre los siguientes campos clave valor:- name: Nombre del gen analizado.Esta propiedad es la encargada de identificar la columna.
- clases: Array donde almacenamos las clases en las que pertenece el gen representado.
- : valor númerico que representa este concepto matemático.
- rel : array donde almacenamos el valor matemático de los genes con los que tiene relación.
- inforel:array con los valores de similitud de cada relación
- rel: array con el valor de la similitud que existe con los genes que está relacionado
- relname: array con los nombres de los genes que posee relación.

- Nombre: Nombre de la clase analizada.
- Gene: Array con los nombre de los genes que pertenecen a la clase
- Genenoclass: Array con los nombre de los genes que no pertenecen a la clase

- Nombre: Nombre de la conexión genética analizada. Estará formada por el nombre de los dos genes entre los que hay una relación, primero el saliente y después el entrante. Hemos optado por crear las relaciones en ambos sentidos, es decir si existe una conexión entre X e Y hemos creado dos documentos diferentes, uno llamado XY y otro YX. Esta propiedad es la encargada de identificar la columna.
- Weight: Valor numérico que contiene el valor de similitud de la conexión genética
- : Valor numérico que contiene que correspondería a este campo matemático
- Djj: Valor numérico que contiene que correspondería a este campo matemático

6.6.3 Validación cruzada
Las modificaciones que permiten adaptar este algoritmo (explicado en el apartado 6.2.3) a las bases de datos de Cassandra son muy parecidos a los de MongoDb, como por ejemplo que los arrays positiveGenFold e negativeGenFold van a gestionar String. El método findNodesClassType() Esta función se encargará de realizar consultas en la base de datos la columna con el nombre dado por parámetros. Con el CQL, simplemente buscaremos y obtendremos la columna que representa a la clase analizada. De esta columna le indicaremos que queremos obtener las filas que corresponden a gene y genenoclass para devolver el conjunto de los genes positivos y negativos a esa clase. Aparte de estos dos métodos la implementación de la validación cruzada se realizará en la clase Fold.6.6.4 Score
En la clase Scoring las modificaciones están relacionadas con el sistema de consultas de Cassandra y sus diferentes implementaciones . Primero de todo hemos implementado 3 métodos especiales para conseguir el correcto funcionamiento de la función Score que son:- AvgScore():El primer paso es localizar la columna que representa nuestro gen. Para ello simplemente tendremos que buscar la columna identificada con el nombre del gen. Una vez encontrado tendremos que extraer los campos “ ”, “rel” y “info ” y a partir de ellos extraer toda la información que nos proporcionan y realizar las operaciones matemáticas necesarias.
- AvgScoreVersionRelaciones() A partir de las columnas de la Column Family relaciones para obtener la información de los genes conectados entre sí. Para obtenerla tenemos que buscar la relación y extraer la información, de un tamaño menor que el AvgScore()o el AvgScoreHashMap();
- AvgScoreVersionHashMap():En esta implementación pasamos de utilizar estructuras del tipo arrayList para almacenar la información de las relaciones para utilizar HashMap. De este modo las consultas devuelven menos información y puede ser gestionada más eficientemente. Para llevar a cabo esta idea utilizaremos la información almacenada en la propiedad "rel".
6.6.5 Modelo de ejecución/navegación
Una vez descritos los posibles casos de uso que puede ejecutar el usuario junto con sus flujos de eventos vamos a describir la navegación que se puede realizar en la aplicación.
6.7. Verificación de resultados
Para verificar todos los resultados obtenidos en las implementaciones realizadas, el profesor Marco Messeti nos ha proporcionado los resultados obtenidos por un algoritmo escrito en R para une serie de ejemplos. La siguiente tabla nos muestra los resultados para el sample1 una base de datos con 10 genes y dos clases.

6.8. Resultados
Una vez verificados todos los resultados en todos los sistemas y en todas las posibles implementaciones, hemos empezado con el siguiente punto de nuestro proyecto, comparar todos los programas y sus implementaciones para analizar cuales poseen rendimientos mejores o una mayor eficiencia en determinadas circunstancias. Como hemos comentado ya, el mayor interés de nuestro proyecto es el análisis del rendimiento para la gestión de diferentes bases de datos con cantidades de información muy elevadas y, por lo tanto, no nos va importar el tiempo de creación de nuestro sistema o el tiempo que vamos a invertir devolviendo los resultados. El mayor interés lo vamos a encontrar en el tiempo que necesita una base de datos para responder las consultas que le enviemos. Con esta idea, hemos analizado todas las clases de cada programa y hemos observado que todas las consultas al sistema son realizadas por dos métodos: rankingAvg() y Fold(). Por lo tanto, hemos añadido a estos métodos para medir el tiempo y analizar el coste temporal de realizar estas consultas como muestra en la siguiente figura [6.29] :
- Muestras de control: Son 6 ejemplos de bases de datos que han sido proporcionadas por el profesor Marco Mesiti. No siguen ningún patrón de tamaño y sirven para realizar comprobaciones de tamaño.

6.30 Muestras de verificación - Muestras con gran cantidada de genes y clases: Son 5 bases de datos genéticas con una gran cantidad de genes y muy pocas conexiones entre ellos y las clases. (cambiar el nombre de las muestras por el correcto)

6.31 Muestras con gran cantidad de Vertex - Muestras con gran cantidad de conexiones: Son 5 bases de datos genéticas con una gran cantidad de conexiones entre genes y una cantidad menor de vértices.

6.32 Muestras con gran cantidad de conexiones
6.8.1 Resultados Neo4J.
cprovechando la estructura que hemos generado con Neo4J , hemos realizado 5 ejecuciones diferentes en nuestro sistema aprovechando las diferentes posibilidades que nos ofrecían y explicaremos a continuación.- Implementación 1 Utilizamos los métodos findNodesClassTypelocal() y AvgScore() fusionamos dos estructuras diferentes. Utilizaremos por una parte la propiedad positive de los nodos que representan las clases para generar los folds mientras que para calcular el Average Score utilizaremos las clases relationships.
- Implementación 2 Utilizamos las métodos findNodesClassType() y AvgScore() . Estos métodos utilizan la clase Relationships y Node para realizar las consultas.
- Implementación 3 Utilizamos los métodos findNodesClassTypelocal() y AvgScoreVersiónLocal(). El primer método utiliza la propiedad positive de los nodos que representan las clases para generar los folds mientras que para calcular el Average Score utilizaremos la propiedad relacionesmap que tiene almacenados los vertex con los que está relacionado y el valor de similitud en forma de HashMap.
- Implementación 4 Utilizamos las métodos findNodesClassType() y AvgScoreVersiónmap() fusionamos otra vez dos estructuras diferentes. Utilizaremos por una parte la clase relationships para generar los folds mientras que para calcular el Average Score utilizaremos la propiedad relacionesmap.
- Implementación 5 Esta última implementación es un poco especial. Hemos utilizado la implementación findNodesClassTypelocal() ya explicada en los casos anteriores y además ahora hemos introducido dos propiedades “relname” y “relpesos” donde hay almacenados arrays con los nombre de los genes que están conectados y los valores de similitud.

Cambios en la implementación no previstos.
El primer problema que nos hemos encontrado es que las propiedades en Neo4J sólo pueden almacenar información en String. Es decir que para todas los cosas donde hemos implementado una versión basada en estas estructuras, si queríamos almacenar algún dato en formato Array o HashMap teníamos que transformarlo en String y después hacer una conversión cuando realizamos la consulta mediante métodos como split o Replece de la clase String. Hemos desestimado después de las primeras pruebas con bases de datos de grandes dimensiones la opción de utilizar una propiedad “negative” en los nodos que generan las clases. Este hecho se ha producido después de que hayamos observado que la cantidad de memoria utilizada era demasiado grande y ralentizaba bastante cuando generaba los folds. Hemos sustituido esta implementación por otra que simplemente recorre todos los Nodos a través de un índice y comprueba si están contenidos en la propiedad positive.6.8.2 Resultados MongoDb.
Aprovechando la estructura que hemos generado con MongoDb hemos realizado 3 ejecuciones diferentes en nuestro sistema aprovechando las diferentes posibilidades que nos ofrecían y explicaremos a continuación.- Implementación 1 Utilizamos el método getsimandrel() con la intención de realizar una única consulta nos devuelva una gran cantidad de información y no tengamos la necesidad de realizar más
- Implementación 2 Utilizamos las métodos getHASHrel() y getelement() para obtener la información necesaria más específicamente. Realizamos más consultas pero las transacciones de información son más pequeñas
- Implementación 3 Utilizamos la colección relaciones. Realizamos consultas mucho más rápidas pero manejamos menos información. El proceso de construcción de esta implementación y la cantidad de memoria que necesita el constructor es mucho más elevado.

Cambios en la implementación no previstos.
Al momento de crear la base de datos, mongoDb no ha soportado la cantidad de insets enviados por el cliente. Para intentar no saturar el sistema hemos introducido un sleep cada 5.000 inserts o updates, consiguiendo nuestro objetivo de evitar saturar el sistema.6.8.3 Cassandra
Aprovechando la estructura que hemos generado con Cassandra explicado , hemos realizado 3 ejecuciones diferentes en nuestro sistema aprovechando las diferentes posibilidades que nos ofrecían y explicaremos a continuación.- Implementación 1 Utilizamos el método getsimandrel() con la intención de realizar una única consulta nos devuelva una gran cantidad de información y no tengamos la necesidad de realizar más
- Implementación 2 Utilizamos las métodos getHASHrel() y getelement() para obtener la información necesaria más específicamente. Realizamos más consultas pero las transacciones de información son más pequeñas
- Implementación 3 Utilizamos la colección relaciones. Realizamos consultas mucho más rápidas pero manejamos menos información. El proceso de construcción de esta implementación y la cantidad de memoria que necesita el constructor es mucho más elevado.
6.8.4 Resultados Titan Cassandra
Aprovechando la estructura que hemos generado con Neo4J, hemos realizado 4 ejecuciones diferentes en nuestro sistema aprovechando las diferentes posibilidades que nos ofrecían las estructuras creadas. Las implementaciones utilizadas son:- Implementación 1 Utilizamos el AvgScore() para aprovechar la información almacenada en las propiedades de los vértices y lo fusionamos con el método findGenesClassTypeEdge que utiliza la clase Edge para encontrar las clases de los elementos.
- Implementación 2 Utilizamos las métodos findGenesClassType() y AvgScore(), ambos basados en el uso de propiedades.
- Implementación 3 Utilizamos los métodos findGenesClassTypeEdge() y AvgScoreVersiónVertex(). Ambos basados en utilizar las clases Vertex y las clases Edge para obtener información y realizar cálculos.
- Implementación 4 Utilizamos los métodos findGenesClassType() y AvgScoreVersiónVertex(). El método para crear los folds se basa en las propiedades almacenadas en las clases mientras que el Average Score utiliza la clase Vertex y Edge para realizar los cálculos.

Cambios en la implementación no previstos
Hemos desestimado después de las primeras pruebas con bases de datos de grandes dimensiones la opción de utilizar una propiedad “negative” en los Vertex que generen las clases. Este hecho se ha producido después de que hayamos observado que la cantidad de memoria utilizada era demasiado grande y ralentizaba bastante cuando generaba los folds. Hemos sustituido esta implementación por otra que simplemente recorre todos los Vertex a través de un índice y comprueba si están contenidos en la propiedad positive.7. Conclusiones
7.1. Neo4J
Como podemos observar entre los diferentes diseños de implementación realizados en Neo4J, su mejor rendimiento se ha producido en la implementación más orientada a grafos (en comparación a otras más orientadas a las propiedades claves-valor). Estos resultados los ha repetido en todas las pruebas realizada con diferentes tamaños y cantidades de vértices .Las observaciones posteriores han reafirmado la eficiencia más elevada de una implementación utilizando el método getRelationships para aquellas bases de datos que tengan más relaciones. Esta causa es debida a una indexación optimizada para todas las conexiones entre nodos. Dado un nodo cualquiera, podemos obtener de forma muy veloz todos los nodos relacionados a través de sus conexiones. Respecto a las versión más locales, cabe decir que Neo4J solo permite almacenar datos del tipo String o tipo Double en sus propiedades. Este hecho ralentiza mucho las versiones que utilicen propiedades de forma abundante (3,4,5), ya que, aunque el tiempo necesario para consultar una propiedad en nodo Nodo no es muy elevado, el hecho de no poder almacenar pares clave-valor con valores tipo lista o hasmap obliga al analista a leer y tratar esta información para realizar cálculos con ellas. Esto significa que debes a partir de una fila de texto generar la estructura que vas a utilizar utilizando funciones como split o Replece con alto coste temporal. Para ver mejor las diferencia entre las implementaciones observa la figura [7.36] :
7.2 Titan Cassandra
Como podemos observar entre los diferentes diseños de implementación realizados en Titan Cassandra, su mejor rendimiento se ha producido en la implementación más local, es decir, aquella que utiliza las propiedades para obtener la información en las consultas. Estos resultados los ha repetido en todas las pruebas realizadas con diferentes tamaños y cantidades de vértices. En la documentación de Titan hallada en la web ya advertía sobre la ineficacia del sistema para grafos con muchas conexiones. Como no especificaba una cantidad exacta de conexiones a partir de los cuales el rendimiento empiece a escasear, hemos intentando probar con grafos con pocas conexiones en nuestros ejemplos pero el rendimiento obtenido ha dejado mucho que desear. A pesar de ser un sistema muy orientado a la distribución en diferentes computadores, hemos podido observar como la integración entre Cassandra y Titan para crear un gestor híbrido de bases de datos orientada a grafos ha sido aproximadamente 5 veces más lento en su versión más óptima que la utilizada por un gestor de grafos puro como Neo4J. También otro aspecto a comentar, aunque nuestras pruebas no miden este valor, son los tiempos de creación de una base de datos Titan Cassandra. Para crear una nueva base de datos como el Sample3 y la muestra11 ha llegado a sobrepasar las 24 horas, mientras que en Neo4J por ejemplo el caso más costoso ha sido creado en 50 minutos como máximo. Todos los resultados obtenidos se pueden compararse en la siguiente figura [7.37] :
7.3. MongoDb
Como podemos observar entre los diferentes diseños de implementación realizados en MongoDb, su mejor rendimiento se ha producido en la implementación tanto utilizando los documentos de la colección relaciones como a través de la colección genes y sus propiedades. La implementación 2 ha utilizado métodos de la librería String para elaborar el algoritmo y, usar sus métodos métodos, genera una pérdida muy grande de prestaciones. Aparte de eso, en la documentación también advierten de una correlación entre la memoria ram disponible del ordenador con la velocidad de acceso a los documentos. Esto quiere decir que si invertimos mas ram en el computador funcionaria más rápidamente la implementación 3 que la 1, es decir, encontraríamos antes un documento en la colección relaciones y podríamos extraer la información en una consulta muy pequeñas que si lo comparamos en la implementación 1 con menos documentos donde buscar pero consultas más grandes y que necesitan más tiempo. Un pequeño detalle, es que la implementación 3, cuando ha tenido menos carga de documentos, es decir, en las muestras 11,10 y 9 ha sido más rápido que la implementación 1 con mucha más cantidad de vértices.Dicho todo esto los resultados los hemos expuesto en la siguiente figura.
7.4 Cassandra
Respecto a Cassandra la verdad no ha cumplido las expectativas. Teóricamente una base de datos NoSQL está diseñada para ser soportada por ordenadores sin grandes recursos hardware pero un ordenador personal no ha conseguido soportar este sistema en condiciones. Según las investigaciones realizadas, cassandra (a parte de necesitar una cantidad de recursos muy elevada) cuando se implementa en local actúa igual como si estuviera siendo un sistema distribuido, por lo tanto si para hacer un insert o realizar una consulta realiza todas las comprobaciones correspondientes a los sistemas distribuidos en un ordenador con recursos muy limitados generan tiempos de lecturas y tiempos de escritura demasiados elevados. Por lo tanto, este sistema queda totalmente desestimado.7.5. Resultados en común
Al comparar todos los sistemas en los cuales hemos obtenidos resultados analizables, observamos que los gestores de bases de datos orientados a grafos son los sistemas que han proporcionado mejores prestaciones para realizar los cálculos más rápidamente. Por ejemplo con Neo4J hemos obtenido unos resultados entre 6 y 7 veces más veloces que en MongoDb. La razón de estos hechos, puede ser debida a la utilización de un ordenador personal con una memoria ram no muy elevada. Buscando información acerca de este aspecto en la documentación de MongoDb hemos comprobado comentarios de los usuarios están exponiendo problemas de lentitud en las consultas para servidores con una memoria ram no muy elevada. Exponen que para utilizar la indexación de los documentos y encontrar la información necesaria es necesario una cantidad de ram elevada para funcionar a un nivel veloz. Aparte de esto, el sistema está hecho más para bases de datos distribuidas, es decir, situaciones con escalabilidad horizontal donde se puede compartir recursos entre las diferentes máquinas. Realmente ha ocurrido un caso similar con Cassandra, pero mucho más extremo. Este sistema de gestión de base de datos está diseñado para utilizar y dividir la información en diversos nodos y, de este modo, poder aprovechar los recursos de cada una de las máquinas. Cuando hemos intentado implementar una versión local de esta base de datos, no hemos podido obtener información de forma muy optimizada y eficiente porque realizaba los mismos pasos analizados en la figura 2.11 para sistemas distribuidos utilizando una única máquina, es decir, realiza mucho trabajo innecesario. Este hecho ha impedido realizar consultas de forma masiva a la base de datos ya que los tiempos de espera eran demasiado elevados. Por último, comparar Neo4J y Titan Cassandra también nos resulta muy útil. Titan es un gestor de grafo muy deficiente. En la documentación básica que hemos analizado en el punto 2.5 ya hemos comentado el hecho que Titan no puede gestionar eficientemente los grafos con una cantidad muy elevada de aristas. La solución que hemos intentado implementar fue utilizar la clase Vertex fusionada con el motor de base de datos de Cassandra, una versión antigua adaptada para Titan que permite almacenar las propiedades de los nodos de forma rápida. Se considero que si implementabamos una versión más local, sin utilizar edges y almacenado la información de las aristas en los propoios Nodos podriamos llegar a obtener unos resultados del estilo de Neo4J. Pero no fue así. El rendimiento obtenido es de unas 5 o 6 veces más lento que Neo4J en los casos más grandes. Respecto a Neo4J cabe mencionar que de entre todas las versiones disponibles en el site, hemos buscado aquella que nos ofrecía más rendimiento en modo local ya que por ejemplo a partir de la versión 2.0 empieza a estar más diseñada para versiones distribuidas y por lo tanto no sería tan eficiente para nuestros experimentos. Otro punto importante a comentar como conclusión es la impotencias de no poder almacenar solamente doubles y strings en los Nodos. Si nuestro experimento necesitará almacenar otro tipo de información, deberíamos transformar la estructura a string y después realizar las conversiones que deseamos, con un coste computacional muy elevado. Por último presentamos una comparación de resultados, para ver claramente las diferencias de tiempo para cada implementación. Recordamos que en la sección 6.3 de este capítulo pueden encontrar el tamaño de las bases de datos utilizadas.