构建决策树对于流失用户进行分类

    最近被分配到商业分析组配合商业分析师对流失掉的客户进行研究。我最先接到的任务是根据客服部门记录的客户的流失原因,对于这些客户的流失原因做分类。商业分析师给我提供了23个类别,要求我把客户都分到这些类中。最开始我企图通过建立关键词规则,比如包含某些单词或者不包含某些单词,但是实际上发现分类的结果很差,规则首先不完备,并且彼此还可能冲突,分类的结果当然就很差。于是我就想到可以利用文本挖掘的方法,对于客户流失的原因进行分类。之前对于机器学习的理论学了不少,但是真正拿实际的数据出来构建一个机器学习模型还是第一次,所以想记录一下这整个过程。

    首先,尽管我没做过文本挖掘,但是我大致知道这其中的原理。要做机器学习,必须有输入,输入就是通过将文本进行分词,然后构建词典。本来我是想用朴素贝叶斯的,但是发现效果很差。首先通过jieba分词将每个用户流失原因进行分词,然后将所有词语加在一起,去重,去掉电话号码,还有符号,保存起来,作为我的词典。

    有了词典,就需要对于每个用户的流失原因文本进行分词,并且按照词典转化成向量。在最开始摸索的时候,我还是用一个超大的for循环进行的。后来发现sklearn自带转化向量的工具。但是它的分词并不符合中文的逻辑,所以我用了一个我觉得依照我现有知识能做的最机智的事儿。我将每个文本利用jieba分词,然后词语之间用','隔开。这样sklearn就会按照中文的逻辑进行分词,于是我的输入就秒有了。

    接下来,我对于数据集进行人工或者简单的标注,然后通过决策树学习,并且预测一部分,人工的将分类错误的进行修改,再利用数据集进行学习,再分类再人工纠错,这样,进行几次之后我就拥有一个基本完全标注正确的50000行的数据。我太机智了,我估计别人可能也是在这么做,但是我之前并不知道,我只能说,在现有条件下,我做了我最多能做的了。最后发现在测试集上有97%左右的正确率。哈哈哈哈哈哈哈哈哈

import pandas as pd
import numpy as np
import jieba
import sklearn.cross_validation as skc
from sklearn import tree
import jieba
from sklearn.feature_extraction.text import CountVectorizer

class creatdic:
    def __init__(self,data):
        assert 'reason' in data.columns,print('Enter the right data')
        self._df = data.copy()
        self._df.loc[self._df[pd.isnull(self._df['reason'])].index,'reason'] = 'None'
    def _creatdic(self,sentence):
        sents = jieba.cut(sentence)
        sent = np.array([x for x in sents])
        return np.unique(sent)
    def creat_dic(self):
        temp = self._df.reason.apply(self._creatdic)
        dic = list()
        for word in temp:
            for j in word:
                if j not in dic:
                    dic.append(j)
                else:
                    continue
        for i in range(len(dic)):
            try:
                float(dic[i])
                dic.pop(i)
            except:
                continue
        dictionary = pd.DataFrame(pd.Series(dic),columns=['word'])
        return dictionary
class creatX:
    def __init__(self,data):
        self._df = data
    def _creatdic(self,name):
        words = jieba.cut(name)
        word = np.array([x for x in words if len(x) > 1])
        return np.unique(word)
    def _concat(self,lis_words):
        temp = str()
        for i in range(len(lis_words)):
            if i == 0:
                temp = lis_words[i]
            else:
                temp = temp + ',' + lis_words[i]
        return temp
    def creatX(self):
        X = self._df.reason
        X1 = self._df.reason.apply(self._creatdic)
        X2 = X1.apply(self._concat)
        return X2
class TreeClassifier:
    def __init__(self,data):
        assert 'reason' in data.columns and 'Label' in data.columns,print('The data is not vailid')
        self._df = data
        
    def _creat_trainX(self,df):
        t_set = df
        dlabel = t_set[pd.isnull(t_set['reason'])].index
        t_set = t_set.drop(dlabel,axis = 0)
        cx = creatX(t_set)
        tX = cx.creatX()
        df = pd.DataFrame(tX,columns=['reason'])
        df['Label'] = t_set['Label']
        return df
    def predict(self,pre_data):
        train = self._creat_trainX(self._df)
        dic = pd.read_excel('words.xlsx')
        dic2 = dic.word
        trainX,testX,trainy,testy = skc.train_test_split(train['reason'],train['Label'])
        vect = CountVectorizer(vocabulary = dic2).fit(trainX)
        trainX,testX,trainy,testy = skc.train_test_split(train['reason'],train['Label'])
        vect = CountVectorizer(vocabulary = dic2).fit(trainX)
        X_train_vectorized = vect.transform(trainX)
        X_train_vectorized
        t2 = tree.DecisionTreeClassifier()
        t2.fit(X_train_vectorized,trainy)
        predata1 = pre_data.copy()
        predf = self._creat_trainX(predata1)
        predf['Label'] = t2.predict(vect.transform(predf.reason))
        predata1['label'] = predf['Label']
        return predata1

    

    决策树本身没什么太多调试,基本用默认的参数分类的结果就很好,主要困难集中在数据集的标注和反复学习,这是特别费工夫的。并且自己构建的字典对于准确率的影响也比较大。

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值