<jupyter_start><jupyter_text>Improve Existing Homograph Groundtruth<jupyter_code>df_path = '../../output/TUS/'
g_path = '../../../graph_construction/combined_graphs_output/TUS/bipartite/bipartite.graph'

df = pd.read_pickle(df_path + 'graph_stats_with_groundtruth_df.pickle')
G = pickle.load(open(g_path, "rb"))
# Create the 'graph_stats_with_groundtruth_updated_homographs_df.pickle'
# Uncomment this cell if the dataframe has not been produced

# # Improve the derived homograph groundtruth by identifying values with more than one meaning by considering the column names where they are found
# vals_with_more_than_1_meaning = set()
# all_col_names = set()
# for idx, row in tqdm(df.iterrows(), total=df.shape[0]):
#     col_names =  utils.graph_helpers.get_cell_node_column_names(G, row['node'])
#     num_meanings = len(col_names)
#     all_col_names |= set(col_names)
#     if num_meanings > 1:
#         vals_with_more_than_1_meaning.add(row['node'])
# print('Nodes with more than 1 meaning:', len(vals_with_more_than_1_meaning))
# print('Number of unique column names', len(all_col_names))

# # Update the 'is_homograph' column, to be true for only nodes found in 'vals_with_more_than_1_meaning'
# df['is_homograph'] = False
# df.loc[df['node'].isin(vals_with_more_than_1_meaning), 'is_homograph'] = True

# # Save updated dataframe
# df.to_pickle(df_path+'graph_stats_with_groundtruth_updated_homographs_df.pickle')
df = pd.read_pickle(df_path+'graph_stats_with_groundtruth_updated_homographs_df.pickle')

# Remove nodes with degree 1 from the dataframe
df = stp.process_df(df, G)

# Compute the groundtruth for the number of meanings for each homograph
df = utils.num_meanings.get_num_meanings_groundtruth(df, G)
df.sort_values(by='betweenness_centrality', ascending=False).head(30)
df['num_meanings_groundtruth'].value_counts()
plt.hist(df['num_meanings_groundtruth'], log=True, bins=20)
plt.xticks(np.arange(0, 21, 1.0))
plt.xlabel('# of meanings of homographs');plt.ylabel('Frequency');plt.tight_layout()
plt.savefig('../../figures/num_meanings/TUS/num_meanings_histogram.svg')<jupyter_output><empty_output><jupyter_text>Evaluation (Top-300)<jupyter_code># Get a list with the top 300 nodes
json.dumps(df['node'][:300].tolist(), ensure_ascii=False)
output_dir_incomplete = '../../output/TUS/num_of_meanings_incomplete_coverage/'
output_dir_complete = '../../output/TUS/num_of_meanings_complete_coverage/'

with open(output_dir_incomplete + 'output.json') as json_file:
    out_dict_incomplete = json.load(json_file)

with open(output_dir_complete + 'output.json') as json_file:
    out_dict_complete = json.load(json_file)<jupyter_output><empty_output><jupyter_text>Incomplete Coverage<jupyter_code>df_incomplete = utils.num_meanings.process_num_meanings_df(df.copy(), out_dict_incomplete, G)
df_incomplete.to_pickle(output_dir_incomplete+'df_processed.pickle')

df_incomplete[df_incomplete['node'].isin(out_dict_incomplete['marked_homographs'].keys())]<jupyter_output>100%|██████████| 300/300 [03:03<00:00,  1.64it/s]<jupyter_text>Complete Coverage<jupyter_code>df_complete = utils.num_meanings.process_num_meanings_df(df.copy(), out_dict_complete, G)
df_complete.to_pickle(output_dir_complete+'df_processed.pickle')

df_complete[df_incomplete['node'].isin(out_dict_complete['marked_homographs'].keys())]
df_incomplete = pd.read_pickle(output_dir_incomplete+'df_processed.pickle')
df_complete = pd.read_pickle(output_dir_complete+'df_processed.pickle')
# Precision using propagation and connected components:
df_incomplete_300 = df_incomplete[df_incomplete['node'].isin(out_dict_complete['marked_homographs'].keys())]
df_complete_300 = df_complete[df_complete['node'].isin(out_dict_complete['marked_homographs'].keys())]

print('Incomplete coverage with propagation precision:', df_incomplete_300['is_num_meanings_correct'].value_counts()[True] / len(df_incomplete_300.index))
print('Complete coverage with propagation precision:', df_complete_300['is_num_meanings_correct'].value_counts()[True] / len(df_complete_300.index))

print('Incomplete coverage with connected components precision:', df_incomplete_300['is_num_components_correct'].value_counts()[True] / len(df_incomplete_300.index))
print('Complete coverage with connected components precision:', df_complete_300['is_num_components_correct'].value_counts()[True] / len(df_complete_300.index))

# Identify how many truly unambiguous values were identified to have only 1 meaning
df_incomplete_300_uv = df_incomplete_300[df_incomplete_300['is_homograph'] == False]
df_complete_300_uv = df_complete_300[df_complete_300['is_homograph'] == False]

print('UV Incomplete coverage with propagation correct:', df_incomplete_300_uv['is_num_meanings_correct'].value_counts()[True])
print('UV Complete coverage with propagation correct:', df_complete_300_uv['is_num_meanings_correct'].value_counts())

print('UV Incomplete coverage with connected components correct:', df_incomplete_300_uv['is_num_components_correct'].value_counts()[True])
print('UV Complete coverage with connected components correct:', df_complete_300_uv['is_num_components_correct'].value_counts())
# Precision of the marked unambiguous values
print('Incomplete coverage UV precision:', df_incomplete_300['marked_unambiguous_values_precision'].mean())
print('Complete coverage UV precision:', df_complete_300['marked_unambiguous_values_precision'].mean())
df_300 = df.sort_values(by='betweenness_centrality', ascending=False).head(300)
df_300['is_homograph'].value_counts()
plt.hist(df_300['num_meanings_groundtruth'], bins=20)
plt.xlabel('# of meanings of top-300 values');plt.ylabel('Frequency');plt.tight_layout()
plt.xticks(np.arange(0, 21, 1.0))
plt.savefig('../../figures/num_meanings/TUS/num_meanings_top_300_histogram.svg')
ax = plt.hist([df_300['num_meanings_groundtruth'], df_incomplete_300['num_meanings'], df_complete_300['num_meanings']], bins=20, label=['Ground Truth', 'Incomplete Coverage (propagation)', 'Complete Coverage (Propagation)'])
plt.xticks(np.arange(0, 21, 1.0))
plt.xlabel('# of meanings of top-300 values');plt.ylabel('Frequency');plt.legend();plt.tight_layout()
plt.savefig('../../figures/num_meanings/TUS/num_meanings_top_300_propagation_histogram.svg')
ax = plt.hist([df_300['num_meanings_groundtruth'], df_incomplete_300['num_connected_components'], df_complete_300['num_connected_components']], bins=20, label=['Ground Truth', 'Incomplete Coverage (# Connected Components)', 'Complete Coverage (# Connected Components)'])
plt.xticks(np.arange(0, 21, 1.0))
plt.xlabel('# of meanings of top-300 values');plt.ylabel('Frequency');plt.legend();plt.tight_layout()
plt.savefig('../../figures/num_meanings/TUS/num_meanings_top_300_connected_components_histogram.svg')
df_incomplete_300.sort_values(by='num_meanings_groundtruth',  ascending=False).head(20)
utils.graph_helpers.get_cell_node_column_names(G, 'Common')
df_incomplete_300[df_incomplete_300['is_homograph']==False]<jupyter_output><empty_output><jupyter_text>Test<jupyter_code>df[df['is_homograph'] == False].head(50)
utils.graph_helpers.get_cell_node_column_names(G, 'Music Faculty')
utils.graph_helpers.get_cell_node_column_names(G, ' ')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1335559265442404, 'fraction_numerical': 0.027267668336115748, 'mean_word_length': 9.373737373737374, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '310610', 'license': 'MIT', 'n_tokens_mistral': 2648, 'n_tokens_neox': 2423, 'n_words': 374, 'path': 'network_analysis/notebooks/num_meanings/TUS_analysis.ipynb', 'repo_name': 'northeastern-datalab/domain_net', 'size': '7188'}