Browse Source

calls_sms_features() now returns all communication features.

communication
junos 10 months ago
parent
commit
777e6f0a58
  1. 18
      features/communication.py
  2. 4
      test/test_communication.py

18
features/communication.py

@ -14,7 +14,7 @@ FEATURES_CALLS = (
+ ["duration_total_" + call_types.get(1), "duration_total_" + call_types.get(2)]
+ ["duration_max_" + call_types.get(1), "duration_max_" + call_types.get(2)]
+ ["no_" + call_types.get(1) + "_ratio", "no_" + call_types.get(2) + "_ratio"]
+ ["no_contacts"]
+ ["no_contacts_calls"]
)
# FEATURES_CALLS =
@ -29,7 +29,7 @@ FEATURES_SMS = (
["no_sms_all"]
+ ["no_" + sms_type for sms_type in sms_types.values()]
+ ["no_" + sms_types.get(1) + "_ratio", "no_" + sms_types.get(2) + "_ratio"]
+ ["no_contacts"]
+ ["no_contacts_sms"]
)
# FEATURES_SMS =
# ["no_sms_all",
@ -156,6 +156,7 @@ def count_comms(comm_df: pd.DataFrame) -> pd.DataFrame:
* the number of communication contacts by type.
"""
if "call_type" in comm_df:
data_type = "calls"
comm_counts = (
comm_df.value_counts(subset=["participant_id", "call_type"])
.unstack()
@ -197,6 +198,7 @@ def count_comms(comm_df: pd.DataFrame) -> pd.DataFrame:
# If there were no missed calls, this exception is raised.
# But we are dropping the column anyway, so no need to deal with the exception.
elif "message_type" in comm_df:
data_type = "sms"
comm_counts = (
comm_df.value_counts(subset=["participant_id", "message_type"])
.unstack()
@ -216,7 +218,7 @@ def count_comms(comm_df: pd.DataFrame) -> pd.DataFrame:
enumerate_contacts(comm_df)
.groupby(["participant_id"])
.nunique()["contact_id"]
.rename("no_contacts")
.rename("no_contacts_" + data_type)
)
# Number of communication contacts
comm_features = comm_features.join(comm_contacts_counts)
@ -282,7 +284,7 @@ def calls_sms_features(df_calls: pd.DataFrame, df_sms: pd.DataFrame) -> pd.DataF
df_calls_sms: pd.DataFrame
The list of features relating calls and sms data for every participant.
These are:
* proportion_calls:
* proportion_calls_all:
proportion of calls in total number of communications
* proportion_calls_incoming:
proportion of incoming calls in total number of incoming/received communications
@ -295,9 +297,7 @@ def calls_sms_features(df_calls: pd.DataFrame, df_sms: pd.DataFrame) -> pd.DataF
"""
count_calls = count_comms(df_calls)
count_sms = count_comms(df_sms)
count_joined = count_calls.merge(
count_sms, on="participant_id", suffixes=("_calls", "_sms")
).assign( # Merge calls and sms features
count_joined = count_calls.join(count_sms).assign(
proportion_calls_all=(
lambda x: x.no_calls_all / (x.no_calls_all + x.no_sms_all)
),
@ -314,7 +314,5 @@ def calls_sms_features(df_calls: pd.DataFrame, df_sms: pd.DataFrame) -> pd.DataF
lambda x: x.no_contacts_calls / (x.no_contacts_calls + x.no_contacts_sms)
)
# Calculate new features and create additional columns
)[
FEATURES_CONTACT
] # Filter out only the relevant features
)
return count_joined

4
test/test_communication.py

@ -86,8 +86,8 @@ class CallsFeatures(unittest.TestCase):
def test_calls_sms_features(self):
self.features_call_sms = calls_sms_features(self.calls, self.sms)
print(self.features_call_sms)
self.assertIsInstance(self.features_call_sms, pd.DataFrame)
self.assertCountEqual(
self.features_call_sms.columns.to_list(), FEATURES_CONTACT
self.features_call_sms.columns.to_list(),
FEATURES_CALLS + FEATURES_SMS + FEATURES_CONTACT,
)
Loading…
Cancel
Save