calls_sms_features() now returns all communication features.

communication
junos 2021-08-18 15:41:47 +02:00
parent 2d78aacd18
commit 777e6f0a58
2 changed files with 10 additions and 12 deletions

View File

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

View File

@ -86,8 +86,8 @@ class CallsFeatures(unittest.TestCase):
def test_calls_sms_features(self): def test_calls_sms_features(self):
self.features_call_sms = calls_sms_features(self.calls, self.sms) 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.assertIsInstance(self.features_call_sms, pd.DataFrame)
self.assertCountEqual( self.assertCountEqual(
self.features_call_sms.columns.to_list(), FEATURES_CONTACT self.features_call_sms.columns.to_list(),
FEATURES_CALLS + FEATURES_SMS + FEATURES_CONTACT,
) )