calls_sms_features() now returns all communication features.
parent
2d78aacd18
commit
777e6f0a58
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue