Skip to content

Commit

Permalink
feat: Added actions matrix creation!
Browse files Browse the repository at this point in the history
note: We still need to update the assess_egagement and it is the core_analyzer library.
  • Loading branch information
amindadgar committed Mar 5, 2024
1 parent 911f07e commit f62113b
Show file tree
Hide file tree
Showing 5 changed files with 327 additions and 24 deletions.
2 changes: 1 addition & 1 deletion discord_analyzer/analysis/analytics_interactions_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def per_account_interactions(
# flatten the list
samples_flattened = list(itertools.chain(*samples))

for i, sample in enumerate(samples_flattened):
for _, sample in enumerate(samples_flattened):
account_name = sample[0]["account"]
interaction_count = sample[0]["count"]

Expand Down
71 changes: 64 additions & 7 deletions discord_analyzer/analysis/compute_interaction_matrix_discord.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
# compute_interaction_matrix_discord.py
#
# Author Ene SS Rawa / Tjitse van der Molen

from discord_analyzer.analysis.utils.activity import Activity
from typing import Any
import copy
from tc_core_analyzer_lib.utils.activity import DiscordActivity
from discord_analyzer.DB_operations.mongodb_access import DB_access
from discord_analyzer.DB_operations.mongodb_query import MongodbQuery
from numpy import ndarray
Expand All @@ -21,7 +22,13 @@ def compute_interaction_matrix_discord(
dates: list[str],
channels: list[str],
db_access: DB_access,
activities: list[str] = [Activity.Mention, Activity.Reply, Activity.Reaction],
activities: list[str] = [
DiscordActivity.Mention,
DiscordActivity.Reply,
DiscordActivity.Reaction,
DiscordActivity.Lone_msg,
DiscordActivity.Thread_msg,
],
) -> dict[str, ndarray]:
"""
Computes interaction matrix from discord data
Expand All @@ -34,7 +41,7 @@ def compute_interaction_matrix_discord(
db_access - obj : database access object
activities - list[Activity] :
the list of activities to generate the matrix for
default is to include all 3 `Activity` types
default is to include all activity types
minimum length is 1
Output:
Expand All @@ -45,8 +52,7 @@ def compute_interaction_matrix_discord(
"""

feature_projection = {
"thr_messages": 0,
"lone_messages": 0,
"channelId": 0,
"replier": 0,
"replied": 0,
"mentioner": 0,
Expand Down Expand Up @@ -77,15 +83,66 @@ def compute_interaction_matrix_discord(
db_results = list(cursor)

per_acc_query_result = prepare_per_account(db_results=db_results)
per_acc_interaction = process_non_reactions(per_acc_query_result)

# And now compute the interactions per account_name (`acc`)
int_mat = {}
# computing `int_mat` per activity
for activity in activities:
int_mat[activity] = generate_interaction_matrix(
per_acc_interactions=per_acc_query_result,
per_acc_interactions=per_acc_interaction,
acc_names=acc_names,
activities=[activity],
)

return int_mat


def process_non_reactions(
heatmaps_data_per_acc: dict[str, list[dict[str, Any]]],
skip_fields: list[str] = [
"reacted_per_acc",
"mentioner_per_acc",
"replied_per_acc",
"account_name",
"date",
],
) -> dict[str, list[dict[str, Any]]]:
"""
process the non-interactions heatmap data to be like interaction
we will make it self interactions
Parameters
-----------
heatmaps_data_per_acc : dict[str, list[dict[str, Any]]]
heatmaps data per account
the keys are accounts
and the values are the list of heatmaps documents related to them
skip_fields : list[str]
the part of heatmaps document that we don't need to make them like interaction
can be interactions itself and account_name, and date
Returns
--------
heatmaps_interactions_per_acc : dict[str, list[dict[str, Any]]]
the same as before but we have changed the non interaction ones to self interaction
"""
heatmaps_interactions_per_acc = copy.deepcopy(heatmaps_data_per_acc)

for account in heatmaps_interactions_per_acc.keys():
# for each heatmaps document
for document in heatmaps_interactions_per_acc[account]:
activities = document.keys()
actions = set(activities) - set(skip_fields)

for action in actions:
action_count = sum(document[action])
if action_count:
document[action] = [
[{"account": account, "count": sum(document[action])}]
]
else:
# action count was zero
document[action] = []

return heatmaps_interactions_per_acc
11 changes: 6 additions & 5 deletions discord_analyzer/analysis/compute_member_activity.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,13 @@ def compute_member_activity(
last_start = time_diff - relativedelta(days=window_param["period_size"] - 1)

# # # ACTUAL ANALYSIS # # #

assess_engagment = EngagementAssessment(
activities=[
DiscordActivity.Mention,
DiscordActivity.Reply,
DiscordActivity.Reaction,
DiscordActivity.Lone_msg,
DiscordActivity.Mention,
],
activities_ignore_0_axis=[DiscordActivity.Mention],
activities_ignore_1_axis=[],
Expand Down Expand Up @@ -288,10 +289,10 @@ def compute_member_activity(
acc_names, date_list_w_str, channels, db_access
)

# for each int_mat type
for key in list(int_mat.keys()):
# remove interactions with self
int_mat[key][np.diag_indices_from(int_mat[key])] = 0
# # for each int_mat type
# for key in list(int_mat.keys()):
# # remove interactions with self
# int_mat[key][np.diag_indices_from(int_mat[key])] = 0

# assess engagement
(graph_out, *activity_dict) = assess_engagment.compute(
Expand Down
21 changes: 10 additions & 11 deletions discord_analyzer/analysis/utils/compute_interaction_mtx_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from discord_analyzer.analysis.analytics_interactions_script import (
per_account_interactions,
)
from discord_analyzer.analysis.utils.activity import Activity
from tc_core_analyzer_lib.utils.activity import DiscordActivity


def prepare_per_account(db_results: list) -> dict[str, list[dict]]:
Expand All @@ -29,13 +29,9 @@ def prepare_per_account(db_results: list) -> dict[str, list[dict]]:

# a dictionary for results of each account
for db_record in db_results:
# if the data for a specific account was not created before, create one as list
acc_name = db_record["account_name"]
if acc_name not in per_acc_query_result.keys():
per_acc_query_result[acc_name] = [db_record]
# else, append
else:
per_acc_query_result[acc_name].append(db_record)
per_acc_query_result.setdefault(acc_name, [])
per_acc_query_result[acc_name].append(db_record)

return per_acc_query_result

Expand Down Expand Up @@ -66,7 +62,6 @@ def generate_interaction_matrix(
an array of integer values
each row and column are representative of account interactions
"""

int_matrix = np.zeros((len(acc_names), len(acc_names)), dtype=np.uint16)

for acc in per_acc_interactions.keys():
Expand Down Expand Up @@ -117,12 +112,16 @@ def prepare_interaction_field_names(activities: list[str]) -> list[str]:
"""
field_names = []
for activity in activities:
if activity == Activity.Mention:
if activity == DiscordActivity.Mention:
field_names.append("mentioner_per_acc")
elif activity == Activity.Reply:
elif activity == DiscordActivity.Reply:
field_names.append("replied_per_acc")
elif activity == Activity.Reaction:
elif activity == DiscordActivity.Reaction:
field_names.append("reacted_per_acc")
elif activity == DiscordActivity.Thread_msg:
field_names.append("thr_messages")
elif activity == DiscordActivity.Lone_msg:
field_names.append("lone_messages")
else:
logging.warning("prepare_interaction_field_names: Wrong activity given!")

Expand Down
Loading

0 comments on commit f62113b

Please sign in to comment.