CoolFace
Apppublic

GIZ/Development-Project-Synergy-Finder

sourceHugging Facemitupdated 4mo agoView on Hugging Face
2likes
multi_project_matching.py82 linesDownload Raw Back to functions
1import numpy as np
2from scipy.sparse import csr_matrix
3
4"""
5Function to calculate the multi project matching results
6
7The Multi-Project Matching Feature uncovers synergy opportunities among various development banks and organizations by facilitating the search for similar projects 
8within a selected filter setting (filtered_df) and all projects (project_df).
9"""
10
11def calc_multi_matches(filtered_df, project_df, similarity_matrix, top_x, identical_country=False):
12    """
13    filtered_df: df with applied filters
14    project_df: df with all projects
15    similarity_matrix: np sparse matrix with all similarities between projects
16    top_x: top x project which should be displayed
17    identical_country: boolean flag to filter matches where country is identical
18    """
19
20    # convert npz sparse matrix into csr matrix
21    if not isinstance(similarity_matrix, csr_matrix):
22        similarity_matrix = csr_matrix(similarity_matrix)
23
24    # extract indices of the projects
25    filtered_indices = filtered_df.index.to_list()
26    project_indices = project_df.index.to_list()
27
28    # size down the matrix to only projects within the filter and convert to dense matrix and flatten it
29    match_matrix = similarity_matrix[project_indices, :][:, filtered_indices] # row / column
30    dense_match_matrix = match_matrix.toarray()
31    flat_matrix = dense_match_matrix.flatten()
32    
33    # get the indices of the top X values in the flattened matrix
34    top_indices = np.argsort(flat_matrix)[-top_x:]
35
36    # Convert flat indices back to 2D indices
37    top_2d_indices = np.unravel_index(top_indices, dense_match_matrix.shape)
38    
39    # Extract the corresponding values
40    top_values = flat_matrix[top_indices]
41
42    # Prepare the result with row and column indices from original dataframes
43    org_rows = []
44    org_cols = []
45    for value, row, col in zip(top_values, top_2d_indices[0], top_2d_indices[1]):
46        original_row_index = project_indices[row]
47        original_col_index = filtered_indices[col]
48        org_rows.append(original_row_index)
49        org_cols.append(original_col_index)
50    
51    # create two result dataframes
52
53    """
54    p1_df: first results of match
55    p2_df: matching result
56
57    matches are displayed through the indices of p1 and p2 dfs
58
59    match1 p1_df.iloc[0] & p2_df.iloc[0]
60    match2 p1_df.iloc[1] & p2_df.iloc[1]
61    """
62    p1_df = filtered_df.loc[org_cols].copy()
63    p1_df['similarity'] = top_values
64    # filter out rows with similarity score less than 50
65    p1_df = p1_df[p1_df['similarity'] > 0.50]
66
67    p2_df = project_df.loc[org_rows].copy()
68    p2_df['similarity'] = top_values
69    p2_df = p2_df[p2_df['similarity'] > 0.50]
70
71    if identical_country:
72        # Reset indices before comparison
73        p1_df = p1_df.reset_index(drop=True)
74        p2_df = p2_df.reset_index(drop=True)
75        # Filter to only include matches with identical countries
76        identical_country_mask = p1_df['country'] == p2_df['country']
77        p1_df = p1_df[identical_country_mask]
78        p2_df = p2_df[identical_country_mask]
79
80    # return both results df with matching projects
81    return p1_df, p2_df
82