赞
踩
常言道:"不以提升业务价值为目的的搞技术都是耍流氓。"那么,下面咱们就来用机器学习中NLP(自然语言处理)的中文文本分类技术来进行一个客户问题智能分拣方面的实战项目。
先来简单描述下所应用的业务场景:当今大型的IT产品多采用分布式开发模式,分为多个不同的子系统,由多个不同的团队(可能在不同的地域)共同开发。一旦用户在使用过程中出现问题,首先会由客服人员进行识别是哪个子系统的问题,然后再将问题转给相应的技术团队进行解决。
这种传统的服务模式下就会存在这样的问题:
1.客服人员需要进行业务培训,然后具有根据客户问题描述识别问题的技术业务能力,这就存在不小的培训成本。
2.由于客服人员能力水平不同、客户问题描述不清晰等原因,问题很容易被错误的识别,造成派发错误,带来极大的沟通成本。
3.当客户问题较多时,经常会出现客户问题的处理不及时,引起客户极大的抱怨和不满。
4.大量的客服人员对企业来说也是很大的人工成本。
那么,为了解决这样的问题,有没有低成本又高效的解决方案呢?
答案是肯定的,机器学习就特别适合解决这样的问题。咱们可以引入机器学习,用机器自动对客户问题进行分拣和派发。
痛点识别了,解决方案也找到了,那咱们下面就撸起袖子,正式开始。
一、数据准备和预处理
做机器学习,首先要有数据。那么咱们就将客户问题历史数据以csv文件格式导出,然后用pandas进行数据集的分析和预处理。代码片段如下:
import pandas as pd
//读取文本数据文件
df_question=pd.read_csv('CustomerQuestion.csv',encoding='gb18030')
df_question.shape
(4238,5)
df_question.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4238 entries, 0 to 4237
Data columns (total 5 columns):
title 4238 non-null object
content 163 non-null object
questionfrom 4238 non-null object
customer 4238 non-null object
product 4238 non-null object
dtypes: object(5)
memory usage: 165.6+ KB
从数据描述中可以看出,数据集中共有4238个实例。我们注意到content只有163个非空值,这意味着4075个实例缺少这个值。 由于缺失的值较多,所以对content进行移除。OMG!关键的问题内容数据缺失,这可怎么办?先别慌,咱们再来看看剩下的数据都是哪些。经过查看,问题标题、问题提出人、客户机构的数据是比较全,那咱们就只有先用这些数据来试试看啦!
1.对数据列进行处理
删除信息严重丢失的问题详情列,将问题标题、问题提出人、客户机构等列进行合并。
df_question_dc=df_question.drop(['content'],axis=1)
df_question_dc['questiontext']=df_question_dc['title']+', '+df_question_dc['questionfrom']+','+df_question_dc['customer']
2.将目标分类映射为数字
df_question_dc['product_mapping']=df_mail_dc['product'].map(product_mapping)
统计各类别的数量如下:
df_question_dc['product_mapping'].value_counts()
二、对中文文本进行分词
由于中文的句子不像英文的句子是由一个一个的单词构成,所以对中文文本数据进行分词处理,拆分成一个个的词语。代码片段如下:
import jieba
def question_cut(questiontext):
return " ".join(jieba.cut(questiontext,cut_all=True))
df_question_dc['questionltext_cut']=df_question_dc['questiontext'].apply(question_cut)
三、区分训练集和测试集
接下来我们需要把数据分成训练集和测试集。
为什么要拆分数据集合呢?举个简单的例子:如果期末考试之前,老师给你一套试题和答案,你把它背了下来。然后考试的时候,只是从那套试题里面抽取一部分考。你凭借超人的记忆力获得了100分。请问你学会了这门课的知识了吗?不知道如果给你新的题目,你会不会做呢?答案还是不知道。所以考试题目需要和复习题目有区别。
同样的道理,假设咱们的模型只在某个数据集上训练,准确度非常高,但是从来没有见过其他新数据,那么它面对新数据表现如何呢?你心里估计也没底吧?
所以我们需要把数据集拆开,只在训练集上训练。保留测试集先不用,作为考试题,看模型经过训练后的分类效果。代码片段如下:
四、文本向量化
对自然语言文本做向量化(vectorization)的主要原因,是计算机看不懂自然语言,它只能处理数字。所以,我们需要将中文文本数据转换为数字格式,以便在机器学习算法中使用。
在这里,介绍下词袋模型(bag-of-words-model),它将文本以数值特征向量的形式来表示。词袋模型的理念很简单,可描述如下:
1)在整个文档集上为每个词汇创建了唯一的标记,例如英文的单词、中文的词语。
2)为每个文档出现的单词数量构建一个特征向量,其中包含每个单词/词语在次文档中出现的次数。
由于每个文档中出现的单词数量只是整个词袋中单词总量很小的一个子集,因此特征向量中的大多数元素为零,这也是我们称之为稀疏(sparse)的原因。这些内容听起来是不是过于抽象了呢!不过不用担心,下面我们就举个例子来详细讲解下。
加入这里有三句话:
1.The sun is shining.
2.The weather is sweet.
3.The sun is shining and the weather is sweet.
那么我们就可以抽取以下特征(即把所有的单子都罗列一遍)
The sun is shining weather sweet and
然后对每一句话,都分别计算特征出现个数。于是上面三句话就转换为以下表格:
The | sun | is | shining | weather | sweet | and |
1 | 1 | 1 | 1 | 0 | 0 | 0 |
1 | 0 | 1 | 0 | 1 | 1 | 0 |
2 | 1 | 2 | 1 | 1 | 1 | 1 |
按照句子为单位,从左到右读数字,就是下面转化后的三个特征向量,这就叫向量化。
[1 1 1 1 0 0 0]
[1 0 1 0 1 1 0]
[2 1 2 1 1 1 1]
1.将分词后的文本向量化
代码片段如下:
from sklearn.feature_extraction.text import CountVectorizer
vect=CountVectorizer(ngram_range=(1, 2))
term_matrix=pd.DataFrame(vect.fit_transform(X_train.questiontext_cut).toarray(),columns=vect.get_feature_names())
term_matrix.shape
(3390, 14919)
2.向量化调优
经过查看发现特征中存在较多数字,另外,排除一些比较独特和比较平凡的不具有特征代表意义的词语,对向量化参数进行设置。代码片段如下:
max_df = 0.8 # 在超过这一比例的文档中出现的关键词(过于平凡),去除掉。
min_df = 2 # 在低于这一数量的文档中出现的关键词(过于独特),去除掉。
vect_pat=CountVectorizer(ngram_range=(1,2),
max_df=max_df,
min_df=min_df,
token_pattern=u'(?u)\\b[^\\d\\W]\\w+\\b',
stop_words=frozenset(stopwords))
X_train_matrix=pd.DataFrame(vect_pat.fit_transform(X_train.questiontext_cut).toarray(),columns=vect_pat.get_feature_names())
X_train_matrix.shape
(3390, 4679)
可以看到,特征数量大幅减少。
3.通过词频-逆文档频率(TF-IDF)进一步特征调优
由于上面向量化是用的词语出现的绝对次数,为了避免特征之间数值差别太大带来的影响,需要对进行TF处理,这个就类似于对词数进行归一化处理。计算公示为:
而IDF是衡量这个词语提供了多少信息,即它在所有文档中都是常见的或罕见的。它是包含该词的文档的对数比例反分数(通过将文档总数除以包含该词的文档数量,然后对该商取对数得到):
一般情况下,会在分母加上常数1,这样可以保证对于没有出现在任何训练样本中的词汇,分母不为零;而取对数是为了保证文档中出现频率较低的词汇不会被赋予过大的权重。
然后再计算TF与IDF的乘积,这就是TF-IDF。这就可以解决以下类似的问题:
假如一个词语出现在多种类型的多个文档中,这种频繁出现的词语通常不包含有用或者具备辨识度的信息。进一步识别和过滤掉常见但是不重要的词语,保留具有重要新的词语。
代码片段如下:
from sklearn.feature_extraction.text import TfidfTransformer
tfidf = TfidfTransformer(use_idf=False)
X_train_tfidf=tfidf.fit_transform(X_train_matrix)
五、模型选择
本文重点在于描述机器学习在实际项目中的应用步骤。另外,机器学习的每个算法模型如果展开讲的话都是一个很大的主题,需要很长的篇幅才能讲述透彻,所以下面只展示每个算法的训练和测试结果。以下就是适合做文本多分类的一些模型的学习效果。
1.Multinomial Naive Bayes
训练得分:
测试得分:
准确率、召回率和F1得分:
2.Logistic Regression
训练得分:
测试得分:
准确率、召回率和F1得分:
3.Random Forest
训练得分:
测试得分:
准确率、召回率和F1得分:
4.Gradient Boosting Decision Tree
训练得分:
测试得分:
准确率、召回率和F1得分:
5.XGBoost(Kaggle大赛利器)
训练得分:
测试得分:
准确率、召回率和F1得分:
经过比较,Logistic Regression表现最好,训练得分和测试得分都是最高而且比较接近,说明无论对现有的数据还是新的数据,预测效果都是比较好的。
另外,由于机器学习大都是对于特定的业务数据集合的,所以学习模型一般也不会通用。所以按照机器学习较为普遍的评价方法,咱们只需要和该数据集下随机预测的最好结果做比较即可。由于前面对数据集进行分析时看以看到,有一类的占比有60%,假如都预测为该类时,该类的准确率可以达到0.6,目前咱们的测试分数总得准确率已经达到0.87,预测效果还是相当的好的,在关键信息缺失的情况下还能有这么高的准确率、召回率、F1得分,结果还是相当令人满意的。
说到这里,咱们就再说说机器学习中数据集和学习模型的关系,孰轻孰重。打个比方,数据集就像一间屋子的天花板,学习模型就是梯子,而机器学习的效果就像一个人在这间屋子可以摸到的高度。假如数据集质量很差,就相当于屋子的天花板很低,无论梯子有多么高,也只能摸到天花板的高度;加入数据级质量很高,代表屋子的天花板很高,如果学习模型不合适或者超参数没调好,那梯子就很短,无论那个人多么努力,还是摸不到天花板,高度被梯子所限。所以,数据集和学习模型都是非常的重要,缺一不可。这就要求我们在积累数据、处理数据的特征工程和对学习模型算法的理解和超参数调优方面都需要尽量做到极致,才能得到较好的学习效果。
好了,话不多说了,下面咱们就对选择好的模型进行超参数调优吧。
六、超参数调优
对于超参数调优,咱们使用快捷方便的网格搜索,代码片段如下:
哈哈!最佳超参数找到了。
下面咱们接着绘制学习曲线,评估下数据多少对学习效果的影响。
七、绘制学习曲线
学习曲线显示了一个估计器对不同数量的训练样本的验证和训练得分。它是一个工具,以找出我们从添加更多的训练数据中获益多少,以及估计值是否遭受较大的方差误差或偏差误差。如果随着训练集的增大,验证分数和训练分数都收敛到一个过低的值,那么我们将不会从更多的训练数据中获益太多。
以下分别是MultinomialNB和LogisticRegression的学习曲线,根据比较,可以看出LogisticRegression表现较好,同时也会随着训练数据的增加获得较多的收益。后续咱们就可以随着数据的积累增多,来取得更好的学习效果。
八、模型持久化
由于该机器学习线上应用的平台是基于Python的,所以选用pickle进行模型的持久化即可。
九、词嵌入模型和深度学习
可能你会有这样的疑问:前面为什么没有选择目前很热的深度学习模型呢?这是因为根据前面咱们对业务场景的分析和数据的特征分析,复杂的深度学习模型可能效果不是太好。为了证明这个推断,咱们还是实际来检验一下,因为实践是检验真理的唯一标准。
那么咱们就选用RNN和词嵌入模型来进行训练和测试下。由于篇幅优先,这里就不详细描述每一步,重点展示学习结果如下:
可以看出,在十次循环之后,训练分数达到了0.9563,而测试分数却只有0.8396,模型过于复杂导致出现了严重的过拟合。由此也可以看出,模型没有好坏之分,只有适用的才是最好的。
后记:机器学习应用不同于传统的IT软件研发,评估价值的方式也不同(千万不要说你这个机器学习模型怎么就只有这么简单的功能,这会被鄙视的),其主要价值是选择合适的机器学习模型,基于特定领域的数据进行特征工程和模型训练,以更加智能和高效准确的机器人来替代一些传统的人工劳动,以此带来丰厚的经济或者业务价值。所以,对于想要尝试机器学习的爱好者,一定要避免陷入传统软件功能价值的固有思维,而是要仔细挖掘业务领域的应用场景,同时静下心来修炼数学理论内功,否则你将茫然不知所措。
如果您喜欢这篇文章的话,请识别下面的二维码关注我的微信订阅号。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。