semantic-scholar-data-pipeline
Science Score: 31.0%
This score indicates how likely this project is to be science-related based on various indicators:
-
✓CITATION.cff file
Found CITATION.cff file -
✓codemeta.json file
Found codemeta.json file -
○.zenodo.json file
-
○DOI references
-
○Academic publication links
-
○Committers with academic emails
-
○Institutional organization owner
-
○JOSS paper metadata
-
○Scientific vocabulary similarity
Low similarity (6.8%) to scientific vocabulary
Repository
Basic Info
Statistics
- Stars: 6
- Watchers: 2
- Forks: 1
- Open Issues: 0
- Releases: 0
Metadata Files
Readme.md
Extracting CS Citation Graph From Semantic Scholar Corpus
Load Data From Semscholar
!aws s3 cp --no-sign-request --recursive s3://ai2-s2-research-public/open-corpus/2020-05-27/ corpus_dataUpload this Data To your Bucket which is specified in
~/.metaflowconfig/config.jsonto a path like$S3_PATH/datasets/semantics_scholar_corpus_data/``pythonfrom metaflow import S3 import os
datapath = '/'.join(S3.getrootfromconfig([]).split('/')[:-1]) s3root = os.path.join(datapath,'datasets')
def syncfoldertos3(rootpath,basepath='',s3root=s3root): syncpath = os.path.join(s3root,basepath)
file_paths = [(os.path.normpath(os.path.join(r,file)),os.path.join(r,file)) for r,d,f in os.walk(root_path) for file in f] # return file_paths for normpth,pth in file_paths: with S3(s3root=s3_root) as s3: file_paths = s3.put_files([(normpth,pth)]) print(f"Finished Writing Path : {pth}") sync_path = os.path.join( sync_path,os.path.normpath(root_path )) return sync_path,file_pathssyncpath,filepaths = syncfoldertos3('corpusdata',basepath='semanticsscholarcorpusdata') ```
Flow Descriptions
The flow are follow the following pattern: 1. Create clean data from large mound of semantic scholar cropus. Cleaning can be removing all uncited material. 2. Use the cleaned data to extract the CS based 3. Use the CS based info to create Graph and classify ontology 4. Use graph to calc page rank and collate that with ontology results. 5. Dump this final processed information to elasticsearch
1. SemScholarCorpusFlow
- citationharvestflow.py contains
SemScholarCorpusFlowwhich will extract and remove all uncited material and saves dataframe for Each chunk under the Bucket$CONFIG_S3_ROOT/processed_data/SemScholarCorpusFlow/s2-corpus-{i}/usefull_citations.csv
2. CSDataExtractorFlow
CSDataExtractorFlow-----Requires-->SemScholarCorpusFlow- cscitationextractor.py contains
CSDataExtractorFlowwhich will use the Chunks set bySemScholarCorpusFlowand extractComputer Sciencerelated Articles. It stores each chunk under the Bucket$CONFIG_S3_ROOT/processed_data/CSDataExtractorFlow/s2-corpus-{i}/category_citations.csv
3. CSDataConcatFlow
CSDataConcatFlow----Requires-->CSDataExtractorFlow- concatcsflow.py contains
CSDataConcatFlowwhich concatenates the data into a single dataframe. This doesn't turn out that useful as csv becomes 22GB in size. The concat csv is stored at$CONFIG_S3_ROOT/processed_data/CSDataConcatFlow/cs-concat-data.csv.
4. CSOntologyClassificationFlow
CSOntologyClassificationFlow----Requires-->CSDataExtractorFlow- ontologyclassifyflow.py contains
CSOntologyClassificationFlow. It will use thecso_classifier.TODO: Push submodule which works as a relative import and Link it to repo.This module will classify the data in the chunked csvs according to ontology described here. The chunked dataframes are stored at$CONFIG_S3_ROOT/processed_data/CSOntologyClassificationFlow/s2-corpus-{i}/ontology_processed.csv
5. CSGraphBuilderFlow
CSGraphBuilderFlow----Requires-->CSDataExtractorFlow- ontologyclassifyflow.py contains
CSGraphBuilderFlowwhich will use theinCitationsandoutCitationsinformation from the chunked csv stored fromCSDataExtractorFlowand store the graph to S3. The graph will be stored under$CONFIG_S3_ROOT/processed_data/CSGraphBuilderFlow/citation_network_graph.json
6. CSPageRankFinder
CSPageRankFinder----Requires-->CSGraphBuilderFlow- pagerankflow.py will use the graph stored via
CSGraphBuilderFlowand performs page rank based on parameters. Finally stores the rank dictionary to$CONFIG_S3_ROOT/processed_data/CSPageRankFinder/page-rank-{run-id}.json
7. PageRankCollateFlow
PageRankCollateFlow----Requires-->CSPageRankFinderPageRankCollateFlow----Requires-->CSOntologyClassificationFlowcollatepagerank_flow.py contains the flow that will collate Page-Rank results from
CSPageRankFinderflow and ontology classification results fromCSOntologyClassificationFlow. This will finally store chunked csvs to$CONFIG_S3_ROOT/processed_data/PageRankCollateFlow/s2-corpus-{i}/ontology_processed.csv
Utility Files
to_elastic.py
- Extracts then csv chunks created by the
PageRankCollateFlow(which have ontology and page rank collated results) and throws the data to elasticsearch.
mf_utils.py
- Utility module for data-syncing/s3 looksup and Dataroot path fixing when creating the flows.
TODO
- Cleanup Readmes
- Add More information about running flows properly.
- Create flow dependency graph
- Replace Memory Hogging Networkx with https://github.com/VHRanger/CSRGraph for PageRank
Owner
- Name: Valay Dave
- Login: valayDave
- Kind: user
- Location: San Francisco, CA
- Website: https://valaydave.info/
- Repositories: 8
- Profile: https://github.com/valayDave
Citation (citation_harvest_flow.py)
import mf_utils
import os
import json
from metaflow import Parameter,FlowSpec,step,batch,conda
S3_TAR_DATA_PATH = os.path.join(mf_utils.data_path,'datasets','corpus_data')
PROCESSED_DATA_PATH = os.path.join(mf_utils.data_path,'processed_data')
def chunks(lst, n):
"""Yield successive n-sized chunks from lst."""
for i in range(0, len(lst), n):
yield lst[i:i + n]
def get_ctndf_from_gz(ctn_file,doc_filter=None):
import pandas
import gzip
cite_data = []
n=0
with gzip.open(ctn_file,'r') as f :
for l in f:
# if n==1000:
# break
dx = json.loads(l)
if len(dx['inCitations']) > 0 or len(dx['outCitations']) > 0:
n+=1
cite_data.append(dx) # = [json.loads(l) for l in lines if journal_filter in l]
return pandas.DataFrame(cite_data)
class SemScholarCorpusFlow(FlowSpec):
'''
Flow Requires `S3_TAR_DATA_PATH` to be set as some Path of S3 From which the semantic scholar Dataset will be Cleaned/Parsed For a Citation Graph.
'''
sample = Parameter('sample',default=None,type=int,help=f'Use a sample of TAR Balls from {S3_TAR_DATA_PATH}')
chunk_size = Parameter('chunksize',default=2,type=int,help='Number of the Chunks To Process in Parallel for individual Foreach')
@step
def start(self):
# s3_tar_paths = [ os.path.join('datasets','corpus_data',p) for p in mf_utils.list_folders('datasets/corpus_data',with_full_path=False)]
s3_tar_paths = mf_utils.list_folders('datasets/corpus_data',with_full_path=False)
if self.sample is not None:
import random
s3_tar_paths = random.sample(s3_tar_paths,self.sample)
s3_tar_paths = list(set(s3_tar_paths) - set(['license.txt','sample-S2-records.gz','manifest.txt']))
self.s3_tar_path_chunks = list(chunks(s3_tar_paths,self.chunk_size))
self.next(self.process_chunk,foreach='s3_tar_path_chunks')
@batch(cpu=8,memory=30000)
@step
def process_chunk(self): # Todo: Add Conda Deps to this.
'''
This will be a foreach process where each Chunk's Following data will be extracted:
1. useful citation(content with citn in/out)
2. num in citation
2. num out citation
Additionally a CSV of the DF will be stored in the S3 Repo with one json representing the following:
{
useful_ids:set(),
in_citn:set(),
out_citn:set(),
}
'''
from metaflow import parallel_map
s3_paths = self.input
print(f"Running Parallel Map For {s3_paths}")
self.chunk_dicts =[ self.extract_individual_chunk(i) for i in s3_paths]
self.next(self.join_citations)
@batch(cpu=16,memory=164000)
@step
def join_citations(self,inputs):
self.useful_ids = set()
self.in_citn = set()
self.out_citn = set()
for inp in inputs:
for c in inp.chunk_dicts:
self.useful_ids.update(c['citation_meta_object']['citation_ids'])
self.in_citn.update(c['citation_meta_object']['in_citations'])
self.out_citn.update(c['citation_meta_object']['out_citations'])
self.next(self.end)
def extract_individual_chunk(self,s3_chunk_url):
from metaflow import S3
import io
s = io.StringIO()
csv_str = None
with S3(s3root=S3_TAR_DATA_PATH) as s3:
s3_obj = s3.get(s3_chunk_url)
print(f"Extracted S3 Data {s3_obj.path}")
ss_df = get_ctndf_from_gz(s3_obj.path)
ss_df['num_out_ctn'] = ss_df['outCitations'].apply(lambda x: len(x))
ss_df['num_in_ctn'] = ss_df['inCitations'].apply(lambda x: len(x))
useful_df = ss_df[~ss_df.apply(lambda row:row['num_in_ctn'] == 0 and row['num_out_ctn'] == 0,axis=1)]
flat_in_ids = list(set([item for sublist in useful_df['inCitations'].values for item in sublist]))
flat_out_ids = list(set([item for sublist in useful_df['outCitations'].values for item in sublist]))
present_ids = list(set(useful_df['id']))
useful_df.to_csv(s)
csv_str = s.getvalue()
print(f"Extracted UseFul Information {s3_obj.path}")
citation_meta_object = dict(
citation_ids = present_ids,in_citations=flat_in_ids,out_citations=flat_out_ids
)
print("Now Starting Uploading Of Parsed Data")
tar_file_name = s3_chunk_url.split('/')[-1].split('.gz')[0]
s3_save_path = os.path.join(
PROCESSED_DATA_PATH,self.__class__.__name__,tar_file_name
)
with S3(s3root=s3_save_path) as s3:
print("Saving Metadata")
df_save_path = s3.put( # Add the Citation File.
'usefull_citations.csv',csv_str
)
print("DF Saved")
meta_save_path = s3.put(
'citation_info.json',json.dumps(citation_meta_object)
)
print(f"Saved Metadata {s3_obj.path}")
return_object = dict(
meta_save_path = meta_save_path,
df_save_path = df_save_path,
citation_meta_object = citation_meta_object,
)
return return_object
@step
def end(self):
print("Done Computation")
if __name__=='__main__':
SemScholarCorpusFlow()
GitHub Events
Total
- Watch event: 4
Last Year
- Watch event: 4
Committers
Last synced: over 1 year ago
Top Committers
| Name | Commits | |
|---|---|---|
| Valay Dave | v****g@g****m | 61 |
Issues and Pull Requests
Last synced: over 1 year ago
All Time
- Total issues: 0
- Total pull requests: 0
- Average time to close issues: N/A
- Average time to close pull requests: N/A
- Total issue authors: 0
- Total pull request authors: 0
- Average comments per issue: 0
- Average comments per pull request: 0
- Merged pull requests: 0
- Bot issues: 0
- Bot pull requests: 0
Past Year
- Issues: 0
- Pull requests: 0
- Average time to close issues: N/A
- Average time to close pull requests: N/A
- Issue authors: 0
- Pull request authors: 0
- Average comments per issue: 0
- Average comments per pull request: 0
- Merged pull requests: 0
- Bot issues: 0
- Bot pull requests: 0
Top Authors
Issue Authors
Pull Request Authors
Top Labels
Issue Labels
Pull Request Labels
Dependencies
- metaflow *