自然语言处理在消费者投诉分类中的应用

大家好!在这篇文章中,将详细探讨如何使用自然语言处理(NLP)的基本理念来解决一个实际的商业问题——消费者投诉分类。

假设已经熟悉自然语言处理的基本概念,比如特征提取、处理原始数据以及在文本数据上训练模型。如果对NLP的基础知识不太熟悉,可以参考写的一系列从零开始的详细文章。

目录

  • 引言与目标
  • 加载数据
  • 特征工程与特征提取
  • 探索性数据分析(EDA)
  • 文本预处理
  • 训练多类分类模型
  • 召回率、精确度、F1分数
  • 预测

金融保护局是一个组织,它发送成千上万的消费者对金融服务(如抵押贷款、学生贷款等)和产品(如信用卡、借记卡)的投诉,以获得一些回应。

投诉需要被分类并交付给相关部门,这提高了投诉的响应时间,因为减少了人工干预来分类投诉类别。

因此,需要构建一个模型,该模型可以阅读投诉内容,并告诉相关的部门,例如,与抵押贷款相关的投诉必须转发给抵押贷款部门,信用卡投诉则转发给银行产品部门。

目标

本项目的目标是将投诉归类到它们相关的产品或类别部门。由于投诉可能涉及多个类别,因此它将是一个多类分类问题,可以通过使用NLP和机器学习算法来解决。

通过使用机器学习模型,可以轻松地对投诉进行分类,从而减少人工干预来分类投诉,减少投诉的响应时间。

注意:文本分类是监督机器学习的一个例子,因为正在使用标记过的数据进行训练和测试。

1. 加载和理解数据集

将使用金融消费者保护局提供的消费者金融投诉数据集。可以通过这个链接下载数据集,或者创建一个云笔记本并立即开始工作。

import pandas as pd import numpy as np df = pd.read_csv("../input/consumer-complaint-database/rows.csv", low_memory=False) df.head()

这个数据集包含许多列,但只需要关注两列[产品,消费者投诉叙述]。

df1 = df[['Product', 'Consumer complaint narrative']] df1.columns = ['Product', 'Consumer complaint']

已经将“消费者投诉叙述”重命名为“消费者投诉”,并保存在数据框df1中。

过滤掉没有文本内容的投诉(假投诉)。

df1 = df1[df1['Consumer complaint'].isna() != True]

2. 特征工程

在特征工程中,进行一些数据操作,以便更有效地训练模型,并深入理解数据。

pd.DataFrame(df1.Product.unique()).values

在数据集中,有18种不同的投诉类别,其中一些投诉类别是相互关联的。例如,“信用卡预付费卡”和“预付费卡”、“信用卡”是如此相关。

因此,需要重命名类别,以便合并相关类别。

重命名类别。

df1.replace({'Product': { 'Credit reporting': 'Repair or Credit reporting', 'Credit card': 'Credit card or prepaid card', 'Prepaid card': 'Credit card or prepaid card', 'credit repair services,Credit reporting , or other personal consumer reports': 'Repair or Credit reporting', 'Money transfer': 'Money transfer, virtual currency, or money service', 'Payday loan': 'title loan,Payday ,Personal loan', 'Virtual currency': 'Money transfer, virtual currency, or money service' }}, inplace=True)

重命名后,只有13个类别/产品需要分类。

注意:正在处理的数据集非常大,包含120万行数据,因此在大数据上训练将非常耗时,因此将只取10000行样本进行训练,以节省时间。

df2 = df1.sample(10000, random_state=1).copy()

df2是将进一步工作的数据处理后的数据集,包含10000行和2列。

到目前为止,已经将数据集转换为文本,需要将投诉文本和类别转换为一些数字。

将类别(产品)转换为数字。

df2['category_id'] = df2['Product'].factorize()[0]

已经添加了一个新的列“category_id”,它将包含类别编号。

如所见,已经将类别标签转换为category_id,还需要数据来将category_id转换回类别标签,以便在预测时使用。为此,将创建一个字典。

category_id = df2[['Product', 'category_id']].drop_duplicates() id_2_category = dict(category_id[['category_id', 'Product']].values)

将使用id_2_category字典将class_id转换为class_label。

3. 进行EDA

在EDA中,探索数据,绘制图表以理解数据之间的关系和各种洞察。

绘制产品/类别与投诉数量的对比图。

import matplotlib.pyplot as plt import seaborn as sns fig = plt.figure(figsize=(8,6)) colors = ['grey','grey','grey','grey','grey','grey','grey','grey','grey', 'grey','darkblue','darkblue','darkblue'] df2.groupby('Product')['Consumer complaint'].count().sort_values().plot.barh(ylim=0, color=colors, title='NUMBER OF COMPLAINTS IN EACH PRODUCT CATEGORY') plt.xlabel('Number of ocurrences', fontsize = 10)

可能会看到“信用报告、修理和其他”拥有最多的支持记录,而“其他金融服务”的记录非常少。这表明一些可能的数据不平衡,这可以通过从每个类别/产品中抽取相等的记录来解决。

4. 特征工程

现在需要将投诉文本转换为一些向量,因为机器无法理解文本数据。这个过程被称为特征提取

将使用TF-IDF向量化器(逆文档频率)进行特征提取。如果对特征工程不熟悉,请参考文章。

TF-IDF评估一个词在其文档集合或一组文档中的重要性。

注意:在去除标点符号、将单词转换为小写之后,可以进行特征提取步骤。TF-IDF向量化器可以自行处理停用词。

词频(Term Frequency):这告诉一个给定的词在文档中出现的次数。

逆文档频率(Inverse Document Frequency):它是词频的相反。如果一个给定的词在文档中出现很多次,它将有一个低IDF分数。

from sklearn.feature_extraction.text import TfidfVectorizer tfidf = TfidfVectorizer(sublinear_tf=True, min_df=5, ngram_range=(1, 2), stop_words='english') features = tfidf.fit_transform(df2['Consumer complaint']).toarray() labels = df2.category_id

min_df:它从词汇表中移除在“min_df”文件中出现次数少于“min_df”的单词。

sublinear_tf = True:在对数尺度上缩放词频。

stop_words:移除指定语言的停用词。

ngram_range = (1, 2):将考虑单字和双字。

max_df:它从词汇表中移除在“max_df”文件中出现次数超过“max_df”的单词。

分割数据集。将数据集分割为训练和测试分区。75%的记录将用于训练,其余将用于测试。

from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=0.25, random_state=0)

5. 模型训练

将使用LinearSVC,因为它表现良好,也可以尝试其他模型并检查它们的性能。

from sklearn.svm import LinearSVC model = LinearSVC() model.fit(X_train, y_train)

6. 评估和测试

为了查看模型表现如何,将使用sklearn的metrics类。将使用分类报告和混淆矩阵。

from sklearn import metrics from sklearn.metrics import classification_report y_pred = model.predict(X_test) print(metrics.classification_report(y_test, y_pred, target_names=df2['Product'].unique()))

正如所观察到的,拥有更多支持(数据行)的类别具有更好的f1分数。这是因为这些类别在更多数据上进行了训练。为了解决这个问题,应该平衡数据,正如已经讨论过的。

像“抵押贷款”、“学生贷款”、“信用报告、修理或其他”这样的类别可以更精确地分类。

绘制混淆矩阵。

import seaborn as sns sns.set() from sklearn.metrics import confusion_matrix conf_mat = confusion_matrix(y_test, y_pred) fig, ax = plt.subplots(figsize=(8,8)) sns.heatmap(conf_mat, annot=True, cmap="Blues", fmt='d', xticklabels=category_id.Product.values, yticklabels=category_id.Product.values) plt.ylabel('Actual') plt.xlabel('Predicted') plt.title("CONFUSION MATRIX - LinearSVC", size=16);

可以清楚地观察到,信用卡报告和数据收集类别比其他类别具有更高的精确度。

是时候尝试模型进行一些预测了。将传递一个投诉文本,模型将根据其投诉类别进行分类。

complain = """在2019年重新注册了印度大学。几天前,被Navient骚扰。已经传真了文件,提供了他们想要的一切。但仍然接到电话要求付款。此外,Navient现在向信用局报告说付款晚了。在这一点上,Navient需要采取行动,以避免采取进一步的措施""" complaint_id = (model.predict(tfidf.transform([complain]))) print("complain", id_2_category[complaint_id[0]])

输出:complain 学生贷款

可以清楚地看到,模型已经准确预测。

在这篇文章中,使用NLP解决了一个商业问题,使用了数据清洗、EDA、特征提取、特征工程等概念,并成功构建了模型,用于分类投诉类型。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485