(7)使用 Plotly Express 创建了一个柱状图,显示了每周的投诉趋势,具体来说,它显示了每周不同天的投诉数量。具体实现代码如下所示。
fig = px.bar(df['dow'].value_counts(ascending=False).to_frame(),y='dow',
template='plotly_white',height=300,
title='Day of the Week Complaint Trends')
fig.update_traces(marker_line_color='#F1A424',marker_line_width=0.1,
marker={'color':'#F1A424'},width=0.5)
fig.update_traces(textfont_size=12, textangle=0, textposition="outside", cliponaxis=False)
fig.show("png")
执行效果如图10-31所示。
图10-31 每周不同天的投诉数量
(8)使用 Plotly Express 创建了一个柱状图,展示投诉地区的分布情况。具体来说,它显示了每个州的投诉数量,并只显示了数量较多的前 50 个州。具体实现代码如下所示。
ldf = df['state'].value_counts(ascending=True).to_frame()[50:]
fig = px.bar(ldf,x='state',template='plotly_white',
title='State of Complaint',height=400)
fig.update_traces(marker_line_color='#F1A424',marker_line_width=1,
marker={'color':'#F1A424'},width=0.4)
fig.show("png")
执行效果如图10-32所示。
图10-32 每个州的投诉数量
(9)创建了一个直方图,用于可视化产品类别、消费者是否争议以及月份之间的关系。具体实现代码如下所示。
disputed = df[['product','consumer disputed?','month']]
fig = px.histogram(disputed, y='product',
color='consumer disputed?',
template='plotly_white',
height = 700,
barmode='group',
color_discrete_sequence=['#F1A424','#3b3745'],
facet_col_wrap=3,
facet_col='month')
fig.update_layout(showlegend=False)
fig.update_layout(barmode="overlay")
fig.update_traces(opacity=0.5)
fig.show("png")
执行效果如图10-33所示,这个直方图可用于比较不同产品类别在不同月份中消费者是否争议的情况。
图10-33 可视化产品类别、消费者是否争议以及月份之间的关系
(10)计算'product' 列中不同产品类别的计数,并将结果转换为 DataFrame,然后使用sum() 方法计算了这些计数的总和。这样,可以用来确定总共有多少投诉记录在 'product' 列中。具体实现代码如下所示。
df['product'].value_counts(ascending=False).to_frame().sum()
执行后会输出:
product 184012
dtype: int64
(11)计算'product'列中不同产品类别的计数,并将结果转换为 DataFrame,然后使用tail(3) 方法查看了计数最少的三个产品类别。具体实现代码如下所示。
df['product'].value_counts(ascending=False).to_frame().tail(3)
执行后会输出:
product
prepaid card 1450
other financial service 292
virtual currency 16
(12)从数据框中选择'virtual currency' 产品类别的投诉记录,并将它们存储在名为 vc 的数据框中。然后,通过 iloc[[0]] 选择了第一条投诉记录,并提取了该记录的 'consumer complaint narrative' 字段的值,用于打印投诉的内容。具体实现代码如下所示。
print('Sample from virtual currency:')
vc = dict(tuple(df.groupby(by='product')))['virtual currency']
vc.iloc[[0]]['consumer complaint narrative'].values[0]
执行后会输出:
Sample from virtual currency:
'Signedup XXXX family members for referrals on Coinbase.com. Coinbase at that time offered {$75.00} for each person referred to their service. I referred all XXXX and they met the terms Coinbase intially offered. Signup took a while do to money transfer timeframes setup by Coinbase. In that time, Coinbase changed their promotion and terms to {$10.00} for referrals. When asked why, they said they could change terms at anytime ( even if signup up for {$75.00} referral bonus ) and that family members did not meet the terms either. Felt like they just change terms to disclude giving out referral bonuses.'
(13)定义函数remove_subset,功能是从数据框中移除指定的子集数据。具体实现代码如下所示。
# 定义函数 remove_subset,用于移除数据框中的指定子集
def remove_subset(df, feature, lst_groups):
# 创建数据框的副本以进行操作
ndf = df.copy()
# 将数据框按照特征分组,并将分组后的结果转换为字典
group = dict(tuple(ndf.groupby(by=feature)))
# 获取所有子组的特征值
subset_group = list(group.keys())
# 检查要移除的子集是否存在于特征值的子组中
if set(lst_groups).issubset(subset_group):
# 遍历要移除的子集列表
for k in lst_groups:
# 从字典中移除特定的子组(如果存在)
group.pop(k, None)
# 使用 pd.concat 函数重新组合剩余的子组数据
df = pd.concat(list(group.values()))
# 重新设置索引,并删除旧的索引
df.reset_index(inplace=True, drop=True)
# 返回经过处理的新数据框 df
return df
(14)定义函数downsample_subset,其主要功能是对数据框中指定的子集进行下采样。下采样是一种减少数据量的方法,通常用于处理不均衡的数据集,以确保不同类别的样本数量接近。具体实现代码如下所示。
# 下采样选定的子集
def downsample_subset(df, feature, lst_groups, samples=4000):
# 创建数据框的副本以进行操作
ndf = df.copy()
# 让我们对所有频数超过 4k 的类别进行下采样
group = dict(tuple(ndf.groupby(by=feature)))
subset_group = list(group.keys())
# 检查要下采样的子集是否存在于特征值的子组中
if set(lst_groups).issubset(subset_group):
dict_downsamples = {}
# 针对每个要下采样的子集
for feature in lst_groups:
# 从该子集中随机抽样指定数量的样本
dict_downsamples[feature] = group[feature].sample(samples)
# 移除旧数据
for k in lst_groups:
group.pop(k, None)
# 将下采样后的数据添加回原数据中
group.update(dict_downsamples)
df = pd.concat(list(group.values()))
df.reset_index(inplace=True, drop=True)
return df
else:
print('数据框中未找到指定的特征')
上述函数的主要用途是帮助处理不均衡的数据集,确保不同类别的样本数量较为均衡,以提高模型的性能和准确性。如果某些子集的数据量较大,可以使用该函数将其减少到指定数量的样本。
(15)选择并下采样数据框中拥有超过 4000 个样本的特定子集特征,保留数据框中样本数量超过 4000 的子集特征,并将每个子集的样本数量下采样到 4000 个,以确保数据集的平衡性。这对于处理不均衡的数据集以及提高模型性能很有帮助。具体实现代码如下所示。
subset_list = list(df['product'].value_counts()[df['product'].value_counts().values > 4000].index)
df = downsample_subset(df,'product',subset_list,samples=4000)
(16)统计数据框 df 中每个子集特征(在这里是 "product" 特征)的样本数量,并按降序排列,以便了解每个子集的样本分布情况。具体实现代码如下所示。
df['product'].value_counts()
通过运行这行代码,可以查看每个子集类别的样本数量分布,以便更好地理解数据集的特性。执行后会输出:
debt collection 4000
mortgage 4000
credit reporting 4000
credit card 4000
student loan 4000
bank account or service 4000
payday loan 1746
money transfers 1497
prepaid card 1450
other financial service 292
virtual currency 16
Name: product, dtype: int64
(17)从原始数据框 df 中选择两列数据,并将它们重新命名为 "text" 和 "label",然后显示前几行数据。具体实现代码如下所示。
df_data = df[['consumer complaint narrative','product']]
df_data.columns = ['text','label']
df_data.head()
执行后可以创建一个包含文本数据和标签的数据框,以便用于文本分类任务。这通常是构建自然语言处理模型的第一步。执行后会输出:
text label
0 I made a wire transfer through Citibank to XXX... money transfers
1 I purchased a money order on XX/XX/2016 ( to c... money transfers
2 I have complained of false online transfer num... money transfers
3 I paid by bank wire transfer on XXXX/XXXX/XXXX... money transfers
4 I found a XXXX Bulldog for sale on XXXX after ... money transfers