<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Making a network
For this class most of the types of network you will want to make can be produced by metaknowledge. The first three co-citation network, citation network and co-author network are specialized versions of the last three one-mode network, two-mode network and multi-mode network.
First we need to import metaknowledge and because we will be dealing with graphs the graphs package networkx as should be imported
Step1:  And so we can visualize the graphs
Step2:  Before we start we should also get a RecordCollection to work with.
Step3:  Now lets look at the different types of graph.
Making a co-citation network
To make a basic co-citation network of Records use coCiteNetwork().
Step4:  graphStats() is a function to extract some of the statists of a graph and make them into a nice string.
coCites is now a networkx graph of the co-citation network, with the hashes of the Citations as nodes and the full citations stored  as an attributes. Lets look at one node
Step5:  and an edge
Step6:  All the graphs metaknowledge use are networkx graphs, a few functions to trim them are implemented in metaknowledge, here is the example section, but many useful functions are implemented by it. Read the documentation here for more information.
The coCiteNetwork() function has many options for filtering and determining the nodes. The default is to use the Citations themselves. If you wanted to make a network of co-citations of journals you would have to make the node type 'journal' and remove the non-journals.
Step7:  Lets take a look at the graph after a quick spring layout
Step8:  A bit basic but gives a general idea. If you want to make a much better looking and more informative visualization you could try gephi or visone. Exporting to them is covered below in Exporting graphs.
Making a citation network
The citationNetwork() method is nearly identical to coCiteNetwork() in its parameters. It has one additional keyword argument directed that controls if it produces a directed network. Read Making a co-citation network to learn more about citationNetwork().
One small example is still worth providing. If you want to make a network of the citations of years by other years and have the letter 'A' in them then you would write
Step9:  Making a co-author network
The coAuthNetwork() function produces the co-authorship network of the RecordCollection as is used as shown
Step10:  Making a one-mode network
In addition to the specialized network generators metaknowledge lets you make a one-mode co-occurence network of any of the WOS tags, with the oneModeNetwork() function. For examples the WOS subject tag 'WC' can be examined.
Step11:  Making a two-mode network
If you wish to study the relationships between 2 tags you can use the twoModeNetwork() function which creates a two mode network showing the connections between the tags. For example to look at the connections between titles('TI') and subjects ('WC')
Step12:  The network is directed by default with the first tag going to the second.
Step13:  quickVisual() makes a graph with the different types of nodes coloured differently and a couple other small visual tweaks from networkx's draw_spring.
Making a multi-mode network
For any number of tags the nModeNetwork() function will do the same thing as the oneModeNetwork() but with any number of tags and it will keep track of their types. So to look at the co-occurence of titles 'TI', WOS number 'UT' and authors 'AU'.
Step14:  Beware this can very easily produce hairballs
Step15:  Post processing graphs
If you wish to apply a well known algorithm or process to a graph networkx is a good place to look as they do a good job at implementing  them.
One of the features it lacks though is pruning of graphs, metaknowledge has these capabilities. To remove edges outside of some weight range, use drop_edges(). For example if you wish to remove the self loops, edges with weight less than 2 and weight higher than 10 from coCiteJournals.
Step16:  Then to remove all the isolates, i.e. nodes with degree less than 1, use drop_nodesByDegree()
Step17:  Now before the processing the graph can be seen here. After the processing it looks like
Step18:  Hm, it looks a bit thinner. Using a visualizer will make the difference a bit more noticeable.
Exporting graphs
Now you have a graph the last step is to write it to disk. networkx has a few ways of doing this, but they tend to be slow. metaknowledge can write an edge list and node attribute file that contain all the information of the graph. The function to do this is called write_graph(). You give it the start of the file name and it makes two labeled files containing the graph.
Step19:  These files are simple CSVs an can be read easily by most systems. If you want to read them back into Python the read_graph() function will do that.
<ASSISTANT_TASK:>
Python Code:
import metaknowledge as mk
import networkx as nx
Explanation: Making a network
For this class most of the types of network you will want to make can be produced by metaknowledge. The first three co-citation network, citation network and co-author network are specialized versions of the last three one-mode network, two-mode network and multi-mode network.
First we need to import metaknowledge and because we will be dealing with graphs the graphs package networkx as should be imported
End of explanation
import matplotlib.pyplot as plt
%matplotlib inline
import metaknowledge.visual as mkv
Explanation: And so we can visualize the graphs
End of explanation
RC = mk.RecordCollection('../savedrecs.txt')
Explanation: Before we start we should also get a RecordCollection to work with.
End of explanation
coCites = RC.coCiteNetwork()
print(mk.graphStats(coCites, makeString = True)) #makestring by default is True so it is not strictly necessary to include
Explanation: Now lets look at the different types of graph.
Making a co-citation network
To make a basic co-citation network of Records use coCiteNetwork().
End of explanation
coCites.nodes(data = True)[0]
Explanation: graphStats() is a function to extract some of the statists of a graph and make them into a nice string.
coCites is now a networkx graph of the co-citation network, with the hashes of the Citations as nodes and the full citations stored  as an attributes. Lets look at one node
End of explanation
coCites.edges(data = True)[0]
Explanation: and an edge
End of explanation
coCiteJournals = RC.coCiteNetwork(nodeType = 'journal', dropNonJournals = True)
print(mk.graphStats(coCiteJournals))
Explanation: All the graphs metaknowledge use are networkx graphs, a few functions to trim them are implemented in metaknowledge, here is the example section, but many useful functions are implemented by it. Read the documentation here for more information.
The coCiteNetwork() function has many options for filtering and determining the nodes. The default is to use the Citations themselves. If you wanted to make a network of co-citations of journals you would have to make the node type 'journal' and remove the non-journals.
End of explanation
nx.draw_spring(coCiteJournals)
Explanation: Lets take a look at the graph after a quick spring layout
End of explanation
citationsA = RC.citationNetwork(nodeType = 'year', keyWords = ['A'])
print(mk.graphStats(citationsA))
nx.draw_spring(citationsA, with_labels = True)
Explanation: A bit basic but gives a general idea. If you want to make a much better looking and more informative visualization you could try gephi or visone. Exporting to them is covered below in Exporting graphs.
Making a citation network
The citationNetwork() method is nearly identical to coCiteNetwork() in its parameters. It has one additional keyword argument directed that controls if it produces a directed network. Read Making a co-citation network to learn more about citationNetwork().
One small example is still worth providing. If you want to make a network of the citations of years by other years and have the letter 'A' in them then you would write:
End of explanation
coAuths = RC.coAuthNetwork()
print(mk.graphStats(coAuths))
Explanation: Making a co-author network
The coAuthNetwork() function produces the co-authorship network of the RecordCollection as is used as shown
End of explanation
wcCoOccurs = RC.oneModeNetwork('WC')
print(mk.graphStats(wcCoOccurs))
nx.draw_spring(wcCoOccurs, with_labels = True)
Explanation: Making a one-mode network
In addition to the specialized network generators metaknowledge lets you make a one-mode co-occurence network of any of the WOS tags, with the oneModeNetwork() function. For examples the WOS subject tag 'WC' can be examined.
End of explanation
ti_wc = RC.twoModeNetwork('WC', 'title')
print(mk.graphStats(ti_wc))
Explanation: Making a two-mode network
If you wish to study the relationships between 2 tags you can use the twoModeNetwork() function which creates a two mode network showing the connections between the tags. For example to look at the connections between titles('TI') and subjects ('WC')
End of explanation
mkv.quickVisual(ti_wc, showLabel = False) #default is False as there are usually lots of labels
Explanation: The network is directed by default with the first tag going to the second.
End of explanation
tags = ['TI', 'UT', 'AU']
multiModeNet = RC.nModeNetwork(tags)
mk.graphStats(multiModeNet)
mkv.quickVisual(multiModeNet)
Explanation: quickVisual() makes a graph with the different types of nodes coloured differently and a couple other small visual tweaks from networkx's draw_spring.
Making a multi-mode network
For any number of tags the nModeNetwork() function will do the same thing as the oneModeNetwork() but with any number of tags and it will keep track of their types. So to look at the co-occurence of titles 'TI', WOS number 'UT' and authors 'AU'.
End of explanation
tags = mk.tagsAndNames #All the tags, twice
sillyMultiModeNet = RC.nModeNetwork(tags)
mk.graphStats(sillyMultiModeNet)
mkv.quickVisual(sillyMultiModeNet)
Explanation: Beware this can very easily produce hairballs
End of explanation
minWeight = 3
maxWeight = 10
proccessedCoCiteJournals = mk.drop_edges(coCiteJournals, minWeight, maxWeight, dropSelfLoops = True)
mk.graphStats(proccessedCoCiteJournals)
Explanation: Post processing graphs
If you wish to apply a well known algorithm or process to a graph networkx is a good place to look as they do a good job at implementing  them.
One of the features it lacks though is pruning of graphs, metaknowledge has these capabilities. To remove edges outside of some weight range, use drop_edges(). For example if you wish to remove the self loops, edges with weight less than 2 and weight higher than 10 from coCiteJournals.
End of explanation
proccessedCoCiteJournals = mk.drop_nodesByDegree(proccessedCoCiteJournals, 1)
mk.graphStats(proccessedCoCiteJournals)
Explanation: Then to remove all the isolates, i.e. nodes with degree less than 1, use drop_nodesByDegree()
End of explanation
nx.draw_spring(proccessedCoCiteJournals)
Explanation: Now before the processing the graph can be seen here. After the processing it looks like
End of explanation
mk.write_graph(proccessedCoCiteJournals, "FinalJournalCoCites")
Explanation: Hm, it looks a bit thinner. Using a visualizer will make the difference a bit more noticeable.
Exporting graphs
Now you have a graph the last step is to write it to disk. networkx has a few ways of doing this, but they tend to be slow. metaknowledge can write an edge list and node attribute file that contain all the information of the graph. The function to do this is called write_graph(). You give it the start of the file name and it makes two labeled files containing the graph.
End of explanation
 FinalJournalCoCites = mk.read_graph("FinalJournalCoCites_edgeList.csv", "FinalJournalCoCites_nodeAttributes.csv")
mk.graphStats(FinalJournalCoCites)
Explanation: These files are simple CSVs an can be read easily by most systems. If you want to read them back into Python the read_graph() function will do that.
End of explanation
<END_TASK>