From 4e20dce18834f7276776a1ab824ff95e8c44ef99 Mon Sep 17 00:00:00 2001 From: Nate E TeBlunthuis Date: Thu, 24 Dec 2020 22:38:04 -0800 Subject: [PATCH] Updating to support wang-style user overlaps. --- clustering/Makefile | 12 +- .../subreddit_comment_authors_10000_a.feather | Bin 0 -> 146762 bytes clustering/clustering.py | 0 density/job_script.sh | 4 + density/overlap_density.py | 21 ++- similarities/Makefile | 8 + similarities/cosine_similarities.py | 55 +------ similarities/job_script.sh | 2 +- similarities/similarities_helper.py | 141 ++++++++++++++++-- similarities/wang_similarity.py | 18 +++ similarities/weekly_cosine_similarities.py | 2 +- 11 files changed, 193 insertions(+), 70 deletions(-) create mode 100644 clustering/affinity/subreddit_comment_authors_10000_a.feather mode change 100644 => 100755 clustering/clustering.py create mode 100755 density/job_script.sh create mode 100644 similarities/wang_similarity.py diff --git a/clustering/Makefile b/clustering/Makefile index c97cb0d..115b218 100644 --- a/clustering/Makefile +++ b/clustering/Makefile @@ -1,4 +1,10 @@ -srun_cdsc='srun -p comdata-int -A comdata --time=300:00:00 --time-min=00:15:00 --mem=100G --ntasks=1 --cpus-per-task=28' -affinity/subreddit_comment_authors_10000.feather:clustering.py /gscratch/comdata/output/reddit_similarity/subreddit_comment_authors_10000.parquet +#srun_cdsc='srun -p comdata-int -A comdata --time=300:00:00 --time-min=00:15:00 --mem=100G --ntasks=1 --cpus-per-task=28' +all:/gscratch/comdata/output/reddit_clustering/comment_authors_10000.feather /gscratch/comdata/output/reddit_clustering/comment_terms_10000.feather + +/gscratch/comdata/output/reddit_clustering/comment_authors_10000.feather:clustering.py /gscratch/comdata/output/reddit_similarity/comment_authors_10000.feather # $srun_cdsc python3 - clustering.py /gscratch/comdata/output/reddit_similarity/subreddit_comment_authors_10000.feather affinity/subreddit_comment_authors_10000.feather ---max_iter=400 --convergence_iter=15 --preference_quantile=0.85 --damping=0.85 + ./clustering.py /gscratch/comdata/output/reddit_similarity/comment_authors_10000.feather /gscratch/comdata/output/reddit_clustering/comment_authors_10000.feather ---max_iter=400 --convergence_iter=15 --preference_quantile=0.85 --damping=0.85 + +/gscratch/comdata/output/reddit_clustering/comment_terms_10000.feather:clustering.py /gscratch/comdata/output/reddit_similarity/comment_terms_10000.feather +# $srun_cdsc python3 + ./clustering.py /gscratch/comdata/output/reddit_similarity/comment_terms_10000.feather /gscratch/comdata/output/reddit_clustering/comment_terms_10000.feather ---max_iter=1000 --convergence_iter=15 --preference_quantile=0.9 --damping=0.5 diff --git a/clustering/affinity/subreddit_comment_authors_10000_a.feather b/clustering/affinity/subreddit_comment_authors_10000_a.feather new file mode 100644 index 0000000000000000000000000000000000000000..21e15e473bf8bf64c4dcee0a7b02e0626566d47a GIT binary patch literal 146762 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 literal 0 HcmV?d00001 diff --git a/clustering/clustering.py b/clustering/clustering.py old mode 100644 new mode 100755 diff --git a/density/job_script.sh b/density/job_script.sh new file mode 100755 index 0000000..553d0a1 --- /dev/null +++ b/density/job_script.sh @@ -0,0 +1,4 @@ +#!/usr/bin/bash +start_spark_cluster.sh +spark-submit --master spark://$(hostname):18899 overlap_density.py wang_overlaps --inpath=/gscratch/comdata/output/reddit_similarity/tfidf_weekly/comment_authors.parquet --to_date=2020-04-13 +stop-all.sh diff --git a/density/overlap_density.py b/density/overlap_density.py index 2bddb8b..a1e9f6d 100644 --- a/density/overlap_density.py +++ b/density/overlap_density.py @@ -2,6 +2,14 @@ import pandas as pd from pandas.core.groupby import DataFrameGroupBy as GroupBy import fire import numpy as np +import sys +sys.path.append("..") +sys.path.append("../similarities") +from similarities.similarities_helper import read_tfidf_matrix, reindex_tfidf, reindex_tfidf_time_interval + +# this is the mean of the ratio of the overlap to the focal size. +# mean shared membership per focal community member +# the input is the author tf-idf matrix def overlap_density(inpath, outpath, agg = pd.DataFrame.sum): df = pd.read_feather(inpath) @@ -20,6 +28,16 @@ def overlap_density_weekly(inpath, outpath, agg = GroupBy.sum): res.to_feather(outpath) return res + +# inpath="/gscratch/comdata/output/reddit_similarity/tfidf/comment_authors.parquet"; +# min_df=1; +# included_subreddits=None; +# topN=10000; +# outpath="/gscratch/comdata/output/reddit_density/wang_overlaps_10000.feather" + +# to_date=2019-10-28 + + def author_overlap_density(inpath="/gscratch/comdata/output/reddit_similarity/comment_authors_10000.feather", outpath="/gscratch/comdata/output/reddit_density/comment_authors_10000.feather", agg=pd.DataFrame.sum): if type(agg) == str: @@ -54,4 +72,5 @@ if __name__ == "__main__": fire.Fire({'authors':author_overlap_density, 'terms':term_overlap_density, 'author_weekly':author_overlap_density_weekly, - 'term_weekly':term_overlap_density_weekly}) + 'term_weekly':term_overlap_density_weekly, + 'wang_overlaps':wang_overlap_density}) diff --git a/similarities/Makefile b/similarities/Makefile index d5187c9..51fd0fa 100644 --- a/similarities/Makefile +++ b/similarities/Makefile @@ -1,3 +1,11 @@ +all: /gscratch/comdata/output/reddit_similarity/subreddit_comment_terms_25000.parquet /gscratch/comdata/output/reddit_similarity/subreddit_comment_authors_25000.parquet /gscratch/comdata/output/reddit_similarity/subreddit_comment_authors_10000.parquet /gscratch/comdata/output/reddit_similarity/comment_terms_10000_weekly.parquet + +/gscratch/comdata/output/reddit_similarity/subreddit_comment_terms_25000.parquet: cosine_similarities.py /gscratch/comdata/output/reddit_similarity/tfidf/comment_terms.parquet + start_spark_and_run.sh 1 cosine_similarities.py term --outfile=/gscratch/comdata/output/reddit_similarity/subreddit_comment_terms_25000.feather + +/gscratch/comdata/output/reddit_similarity/subreddit_comment_authors_25000.parquet: cosine_similarities.py /gscratch/comdata/output/reddit_similarity/tfidf/comment_authors.parquet + start_spark_and_run.sh 1 cosine_similarities.py author --outfile=/gscratch/comdata/output/reddit_similarity/subreddit_comment_authors_25000.feather + /gscratch/comdata/output/reddit_similarity/subreddit_comment_authors_10000.parquet: cosine_similarities.py /gscratch/comdata/output/reddit_similarity/tfidf/comment_authors.parquet start_spark_and_run.sh 1 cosine_similarities.py author --outfile=/gscratch/comdata/output/reddit_similarity/subreddit_comment_authors_10000.feather diff --git a/similarities/cosine_similarities.py b/similarities/cosine_similarities.py index 54b9599..609e477 100644 --- a/similarities/cosine_similarities.py +++ b/similarities/cosine_similarities.py @@ -1,64 +1,21 @@ -from pyspark.sql import functions as f -from pyspark.sql import SparkSession import pandas as pd import fire from pathlib import Path -from similarities_helper import prep_tfidf_entries, read_tfidf_matrix, select_topN_subreddits, column_similarities +from similarities_helper import similarities +def cosine_similarities(infile, term_colname, outfile, min_df=None, included_subreddits=None, topN=500, exclude_phrases=False,from_date=None, to_date=None): + return similiarities(infile=infile, simfunc=column_similarities, term_colname=term_colname, outfile=outfile, min_df=min_df, included_subreddits=included_subreddits, topN=topN, exclude_phrases=exclude_phrases,from_date=from_date, to_date=to_date) -def cosine_similarities(infile, term_colname, outfile, min_df=None, included_subreddits=None, topN=500, exclude_phrases=False): - spark = SparkSession.builder.getOrCreate() - conf = spark.sparkContext.getConf() - print(outfile) - print(exclude_phrases) - - tfidf = spark.read.parquet(infile) - - if included_subreddits is None: - included_subreddits = select_topN_subreddits(topN) - else: - included_subreddits = set(open(included_subreddits)) - - if exclude_phrases == True: - tfidf = tfidf.filter(~f.col(term_colname).contains("_")) - - print("creating temporary parquet with matrix indicies") - tempdir = prep_tfidf_entries(tfidf, term_colname, min_df, included_subreddits) - tfidf = spark.read.parquet(tempdir.name) - subreddit_names = tfidf.select(['subreddit','subreddit_id_new']).distinct().toPandas() - subreddit_names = subreddit_names.sort_values("subreddit_id_new") - subreddit_names['subreddit_id_new'] = subreddit_names['subreddit_id_new'] - 1 - spark.stop() - - print("loading matrix") - mat = read_tfidf_matrix(tempdir.name, term_colname) - print('computing similarities') - sims = column_similarities(mat) - del mat - - sims = pd.DataFrame(sims.todense()) - sims = sims.rename({i:sr for i, sr in enumerate(subreddit_names.subreddit.values)}, axis=1) - sims['subreddit'] = subreddit_names.subreddit.values - - p = Path(outfile) - - output_feather = Path(str(p).replace("".join(p.suffixes), ".feather")) - output_csv = Path(str(p).replace("".join(p.suffixes), ".csv")) - output_parquet = Path(str(p).replace("".join(p.suffixes), ".parquet")) - - sims.to_feather(outfile) - tempdir.cleanup() - -def term_cosine_similarities(outfile, min_df=None, included_subreddits=None, topN=500, exclude_phrases=False): +def term_cosine_similarities(outfile, min_df=None, included_subreddits=None, topN=500, exclude_phrases=False, from_date=None, to_date=None): return cosine_similarities('/gscratch/comdata/output/reddit_similarity/tfidf/comment_terms.parquet', 'term', outfile, min_df, included_subreddits, topN, - exclude_phrases) + exclude_phrasesby.) -def author_cosine_similarities(outfile, min_df=2, included_subreddits=None, topN=10000): +def author_cosine_similarities(outfile, min_df=2, included_subreddits=None, topN=10000, from_date=None, to_date=None): return cosine_similarities('/gscratch/comdata/output/reddit_similarity/tfidf/comment_authors.parquet', 'author', outfile, diff --git a/similarities/job_script.sh b/similarities/job_script.sh index e1031ce..e79a061 100755 --- a/similarities/job_script.sh +++ b/similarities/job_script.sh @@ -1,4 +1,4 @@ #!/usr/bin/bash start_spark_cluster.sh -spark-submit --master spark://$(hostname):18899 weekly_cosine_similarities.py term --outfile=/gscratch/comdata/output/reddit_similarity/subreddit_comment_terms_10000_weely.parquet +spark-submit --master spark://$(hostname):18899 wang_similarity.py --infile=/gscratch/comdata/output/reddit_similarity/tfidf/comment_authors.parquet --max_df=10 --outfile=/gscratch/comdata/output/reddit_similarity/wang_similarity_1000_max10.feather stop-all.sh diff --git a/similarities/similarities_helper.py b/similarities/similarities_helper.py index 88c830c..69516a6 100644 --- a/similarities/similarities_helper.py +++ b/similarities/similarities_helper.py @@ -1,3 +1,4 @@ +from pyspark.sql import SparkSession from pyspark.sql import Window from pyspark.sql import functions as f from enum import Enum @@ -5,15 +6,108 @@ from pyspark.mllib.linalg.distributed import CoordinateMatrix from tempfile import TemporaryDirectory import pyarrow import pyarrow.dataset as ds -from scipy.sparse import csr_matrix +from scipy.sparse import csr_matrix, issparse import pandas as pd import numpy as np import pathlib +from datetime import datetime +from pathlib import Path class tf_weight(Enum): MaxTF = 1 Norm05 = 2 +infile = "/gscratch/comdata/output/reddit_similarity/tfidf_weekly/comment_authors.parquet" + +def reindex_tfidf_time_interval(infile, term_colname, min_df=None, max_df=None, included_subreddits=None, topN=500, exclude_phrases=False, from_date=None, to_date=None): + term = term_colname + term_id = term + '_id' + term_id_new = term + '_id_new' + + spark = SparkSession.builder.getOrCreate() + conf = spark.sparkContext.getConf() + print(exclude_phrases) + tfidf_weekly = spark.read.parquet(infile) + + # create the time interval + if from_date is not None: + if type(from_date) is str: + from_date = datetime.fromisoformat(from_date) + + tfidf_weekly = tfidf_weekly.filter(tfidf_weekly.week >= from_date) + + if to_date is not None: + if type(to_date) is str: + to_date = datetime.fromisoformat(to_date) + tfidf_weekly = tfidf_weekly.filter(tfidf_weekly.week < to_date) + + tfidf = tfidf_weekly.groupBy(["subreddit","week", term_id, term]).agg(f.sum("tf").alias("tf")) + tfidf = _calc_tfidf(tfidf, term_colname, tf_weight.Norm05) + tempdir = prep_tfidf_entries(tfidf, term_colname, min_df, max_df, included_subreddits) + tfidf = spark.read_parquet(tempdir.name) + subreddit_names = tfidf.select(['subreddit','subreddit_id_new']).distinct().toPandas() + subreddit_names = subreddit_names.sort_values("subreddit_id_new") + subreddit_names['subreddit_id_new'] = subreddit_names['subreddit_id_new'] - 1 + return(tempdir, subreddit_names) + +def reindex_tfidf(infile, term_colname, min_df=None, max_df=None, included_subreddits=None, topN=500, exclude_phrases=False): + spark = SparkSession.builder.getOrCreate() + conf = spark.sparkContext.getConf() + print(exclude_phrases) + + tfidf = spark.read.parquet(infile) + + if included_subreddits is None: + included_subreddits = select_topN_subreddits(topN) + else: + included_subreddits = set(open(included_subreddits)) + + if exclude_phrases == True: + tfidf = tfidf.filter(~f.col(term_colname).contains("_")) + + print("creating temporary parquet with matrix indicies") + tempdir = prep_tfidf_entries(tfidf, term_colname, min_df, max_df, included_subreddits) + + tfidf = spark.read.parquet(tempdir.name) + subreddit_names = tfidf.select(['subreddit','subreddit_id_new']).distinct().toPandas() + subreddit_names = subreddit_names.sort_values("subreddit_id_new") + subreddit_names['subreddit_id_new'] = subreddit_names['subreddit_id_new'] - 1 + spark.stop() + return (tempdir, subreddit_names) + +def similarities(infile, simfunc, term_colname, outfile, min_df=None, max_df=None, included_subreddits=None, topN=500, exclude_phrases=False, from_date=None, to_date=None): + + if from_date is not None or to_date is not None: + tempdir, subreddit_names = reindex_tfidf_time_interval(infile, term_colname='author', min_df=min_df, max_df=max_df, included_subreddits=included_subreddits, topN=topN, exclude_phrases=False, from_date=from_date, to_date=to_date) + + else: + tempdir, subreddit_names = reindex_tfidf(infile, term_colname='author', min_df=min_df, max_df=max_df, included_subreddits=included_subreddits, topN=topN, exclude_phrases=False) + + print("loading matrix") + # mat = read_tfidf_matrix("term_tfidf_entries7ejhvnvl.parquet", term_colname) + mat = read_tfidf_matrix(tempdir.name, term_colname) + print('computing similarities') + sims = simfunc(mat) + del mat + + if issparse(sims): + sims = sims.todense() + + print(f"shape of sims:{sims.shape}") + print(f"len(subreddit_names.subreddit.values):{len(subreddit_names.subreddit.values)}") + sims = pd.DataFrame(sims) + sims = sims.rename({i:sr for i, sr in enumerate(subreddit_names.subreddit.values)}, axis=1) + sims['subreddit'] = subreddit_names.subreddit.values + + p = Path(outfile) + + output_feather = Path(str(p).replace("".join(p.suffixes), ".feather")) + output_csv = Path(str(p).replace("".join(p.suffixes), ".csv")) + output_parquet = Path(str(p).replace("".join(p.suffixes), ".parquet")) + + sims.to_feather(outfile) + tempdir.cleanup() + def read_tfidf_matrix_weekly(path, term_colname, week): term = term_colname term_id = term + '_id' @@ -33,8 +127,6 @@ def write_weekly_similarities(path, sims, week, names): sims = sims.melt(id_vars=['subreddit','week'],value_vars=names.subreddit.values) sims.to_parquet(p / week.isoformat()) - - def read_tfidf_matrix(path,term_colname): term = term_colname term_id = term + '_id' @@ -44,6 +136,15 @@ def read_tfidf_matrix(path,term_colname): entries = dataset.to_table(columns=['tf_idf','subreddit_id_new',term_id_new]).to_pandas() return(csr_matrix((entries.tf_idf,(entries[term_id_new]-1, entries.subreddit_id_new-1)))) +def column_overlaps(mat): + non_zeros = (mat != 0).astype('double') + + intersection = non_zeros.T @ non_zeros + card1 = non_zeros.sum(axis=0) + den = np.add.outer(card1,card1) - intersection + + return intersection / den + def column_similarities(mat): norm = np.matrix(np.power(mat.power(2).sum(axis=0),0.5,dtype=np.float32)) mat = mat.multiply(1/norm) @@ -51,13 +152,16 @@ def column_similarities(mat): return(sims) -def prep_tfidf_entries_weekly(tfidf, term_colname, min_df, included_subreddits): +def prep_tfidf_entries_weekly(tfidf, term_colname, min_df, max_df, included_subreddits): term = term_colname term_id = term + '_id' term_id_new = term + '_id_new' if min_df is None: min_df = 0.1 * len(included_subreddits) + tfidf = tfidf.filter(f.col('count') >= min_df) + if max_df is not None: + tfidf = tfidf.filter(f.col('count') <= max_df) tfidf = tfidf.filter(f.col("subreddit").isin(included_subreddits)) @@ -86,19 +190,22 @@ def prep_tfidf_entries_weekly(tfidf, term_colname, min_df, included_subreddits): return(tempdir) -def prep_tfidf_entries(tfidf, term_colname, min_df, included_subreddits): +def prep_tfidf_entries(tfidf, term_colname, min_df, max_df, included_subreddits): term = term_colname term_id = term + '_id' term_id_new = term + '_id_new' if min_df is None: min_df = 0.1 * len(included_subreddits) + tfidf = tfidf.filter(f.col('count') >= min_df) + if max_df is not None: + tfidf = tfidf.filter(f.col('count') <= max_df) tfidf = tfidf.filter(f.col("subreddit").isin(included_subreddits)) # reset the subreddit ids sub_ids = tfidf.select('subreddit_id').distinct() - sub_ids = sub_ids.withColumn("subreddit_id_new",f.row_number().over(Window.orderBy("subreddit_id"))) + sub_ids = sub_ids.withColumn("subreddit_id_new", f.row_number().over(Window.orderBy("subreddit_id"))) tfidf = tfidf.join(sub_ids,'subreddit_id') # only use terms in at least min_df included subreddits @@ -221,15 +328,9 @@ def build_weekly_tfidf_dataset(df, include_subs, term_colname, tf_family=tf_weig return df - - -def build_tfidf_dataset(df, include_subs, term_colname, tf_family=tf_weight.Norm05): - +def _calc_tfidf(df, term_colname, tf_family): term = term_colname term_id = term + '_id' - # aggregate counts by week. now subreddit-term is distinct - df = df.filter(df.subreddit.isin(include_subs)) - df = df.groupBy(['subreddit',term]).agg(f.sum('tf').alias('tf')) max_subreddit_terms = df.groupby(['subreddit']).max('tf') # subreddits are unique max_subreddit_terms = max_subreddit_terms.withColumnRenamed('max(tf)','sr_max_tf') @@ -240,9 +341,7 @@ def build_tfidf_dataset(df, include_subs, term_colname, tf_family=tf_weight.Norm # group by term. term is unique idf = df.groupby([term]).count() - N_docs = df.select('subreddit').distinct().count() - # add a little smoothing to the idf idf = idf.withColumn('idf',f.log(N_docs/(1+f.col('count')))+1) @@ -271,6 +370,18 @@ def build_tfidf_dataset(df, include_subs, term_colname, tf_family=tf_weight.Norm df = df.withColumn("tf_idf", (0.5 + 0.5 * df.relative_tf) * df.idf) return df + + +def build_tfidf_dataset(df, include_subs, term_colname, tf_family=tf_weight.Norm05): + term = term_colname + term_id = term + '_id' + # aggregate counts by week. now subreddit-term is distinct + df = df.filter(df.subreddit.isin(include_subs)) + df = df.groupBy(['subreddit',term]).agg(f.sum('tf').alias('tf')) + + df = _calc_tfidf(df, term_colname, tf_family) + + return df def select_topN_subreddits(topN, path="/gscratch/comdata/output/reddit_similarity/subreddits_by_num_comments.csv"): rankdf = pd.read_csv(path) diff --git a/similarities/wang_similarity.py b/similarities/wang_similarity.py new file mode 100644 index 0000000..99dc3cb --- /dev/null +++ b/similarities/wang_similarity.py @@ -0,0 +1,18 @@ +from similarities_helper import similarities +import numpy as np +import fire + +def wang_similarity(mat): + non_zeros = (mat != 0).astype(np.float32) + intersection = non_zeros.T @ non_zeros + return intersection + + +infile="/gscratch/comdata/output/reddit_similarity/tfidf/comment_authors.parquet"; outfile="/gscratch/comdata/output/reddit_similarity/wang_similarity_10000.feather"; min_df=1; included_subreddits=None; topN=10000; exclude_phrases=False; from_date=None; to_date=None + +def wang_overlaps(infile, outfile="/gscratch/comdata/output/reddit_similarity/wang_similarity_10000.feather", min_df=1, max_df=None, included_subreddits=None, topN=10000, exclude_phrases=False, from_date=None, to_date=None): + + return similarities(infile=infile, simfunc=wang_similarity, term_colname='author', outfile=outfile, min_df=min_df, max_df=None, included_subreddits=included_subreddits, topN=topN, exclude_phrases=exclude_phrases, from_date=from_date, to_date=to_date) + +if __name__ == "__main__": + fire.Fire(wang_overlaps) diff --git a/similarities/weekly_cosine_similarities.py b/similarities/weekly_cosine_similarities.py index 54856b0..4d496f0 100644 --- a/similarities/weekly_cosine_similarities.py +++ b/similarities/weekly_cosine_similarities.py @@ -35,7 +35,7 @@ def cosine_similarities_weekly(tfidf_path, outfile, term_colname, min_df = None, subreddit_names['subreddit_id_new'] = subreddit_names['subreddit_id_new'] - 1 spark.stop() -d weeks = sorted(list(subreddit_names.week.drop_duplicates())) + weeks = sorted(list(subreddit_names.week.drop_duplicates())) for week in weeks: print(f"loading matrix: {week}") mat = read_tfidf_matrix_weekly(tempdir.name, term_colname, week) -- 2.39.5