Python 文本挖掘淘宝客服日志挖掘

本文没有使用特别高端的挖掘算法,也没有使用专用的第三方分词工具,是基于统计的原理进行分词和文章句子的统计的。基本逻辑如下:
1、导入文章,进行分句。
2、按照2个字一个词的规则,对统计的句子进行分词并统计。
3、对分得的词进行处理,去除词左右交接的组合,比如ABCD中,BC出现的频率高于AB、CD,则AB、CD在ABCD同时出现的句子中不应被视为词语,但如果在后续的句子中,存在BCDF,CD仍可以统计为词语。频数设一个阀值,小于该值的不视为词语。(本部分耗时较大,改进使用并行算法需要开销比较大的内存)
4、找出词语出现的句子。
5、找出词组出现的句子并统计。
经过以上的处理,基本能挖掘出淘宝客服日志中用户最关注的问题。本文使用的分词方法还可进一步用来建立词库,以供后续分词使用,因为很多分词系统都是收费的,本文的分词算法基本不会出现漏词的情况,即使是新词。下面是全部代码。

#0主目录
from time import time as time
import os

if __name__=='__main__':

    start=time();
    os.system('python '+ os.getcwd() + '\\1提取句子.py');
    os.system('python '+ os.getcwd() + '\\2分词-2字词1分词.py');
    os.system('python '+ os.getcwd() + '\\2分词-2字词2处理.py');
    os.system('python '+ os.getcwd() + '\\3词语匹配句子.py');
    os.system('python '+ os.getcwd() + '\\4词组匹配句子.py');
    print('Time used:',int((time()-start)/60*10)/10,'分钟')
#1提取句子
from time import time as time
import re
import xlrd
import threading
import pickle
from multiprocessing import Process
from multiprocessing import cpu_count
import os
import os.path
import xlwt
import sys
import operator

def func00():   #文件、文件夹操作

    try:
        kk=os.listdir(os.getcwd()+'\\数据输出');
        for j in kk:
            os.remove(os.getcwd()+'\\数据输出\\'+j)
        os.rmdir(os.getcwd()+'\\数据输出');  #删除 数据1 文件夹
    except:
        pass
    finally:
        print('程序开始运行,请勿删除文件!')
    cs=os.path.isdir(os.getcwd()+'\\数据输出'); #判断 数据输出 文件夹是否存在
    if cs==False:
        os.mkdir(os.getcwd()+'\\数据输出'); #新建 数据输出 文件夹

def func01():    #提取待处理文本

    try:
        fp=open(os.getcwd()+'\\十九大报告全文.txt','r',encoding='gb18030')
    except:
        print('本目录下未找到文件');sys.exit()
    wb1=[];
    for j in fp:
        line=''.join(j.split('\n'));
        if line != '':
            wb1.append(line);
    fp.close()
    wb2=func02(wb1)
    return wb2

def func02(wb1):    #按照特征符号分句子

    fh1=['。','!','?','.','!','?'];#分句特征
    for f in fh1:
        fh2=fh1.copy();fh2.remove(f);wb2=[];
        for j in wb1:
            line=j.split(f);
            for i in line:
                if i != '':
                    if i[len(i)-1:len(i)] not in fh2:
                        wb2.append(i+f);
                    else:
                        wb2.append(i);
        wb1=wb2.copy()
    func03(wb2)
    return wb2

def func03(wb2):    #文件输出
    #保存txt
    fp=open(os.getcwd()+'\\数据输出\\1 句子文件.txt','w',encoding='gb18030')
    for j in wb2:
        fp.write(j);fp.write('\n')
    fp.close()
    #保存dat
    fp=open(os.getcwd()+'\\数据输出\\1 句子文件.dat','wb');
    pickle.dump(wb2,fp);
    fp.close()

if __name__=='__main__':

    start=time();

    func00();
    func01();

    print('Time used:',int((time()-start)/60*10)/10,'分钟')
    #os.system("pause")
#2分词-2字词1分词
from time import time as time
import re
import xlrd
import threading
import pickle
from multiprocessing import Process
from multiprocessing import cpu_count
import os
import os.path
import xlwt
import sys
import operator

def func01():    #提取句子

    fp=open(os.getcwd()+'\\数据输出\\1 句子文件.dat','rb');
    wb1=pickle.load(fp);
    fp.close()
    return wb1

def func02(wb1,zs):    #提取词语

    wb2=[];wb3=[];
    for j in wb1:
        if len(j)>=zs:
            for i in range(0,len(j)-zs+1):
                wb2.append(j[i:i+zs])
    #保存原始词语,用于后续筛选
    fp=open(os.getcwd()+'\\数据输出\\2 2字词语-1原始.dat','wb');
    pickle.dump(wb2,fp);
    fp.close();
    #筛选汉字词语
    wb3=[];pattern=re.compile(r'[\u4e00-\u9fa5]');
    for j in wb2:
        if len(pattern.findall(j))==len(j):
            wb3.append(j)
    #筛选唯一,并统计频数
    wb3.sort();k=0;wb4=[];
    for j in range(0,len(wb3)-1):
        k=k+1;
        if wb3[j]!=wb3[j+1]:
            wb4.append([wb3[j],k]);k=0;
    wb4.append([wb3[len(wb3)-1],k+1])

    #列表排序,降序
    wb4.sort(reverse=True,key=operator.itemgetter(1))
    print(len(wb4))
    return wb4

def func03(wb4):    #输出词语

    #保存词语
    fp=open(os.getcwd()+'\\数据输出\\2 2字词语-2汉字.dat','wb');
    pickle.dump(wb4,fp);
    fp.close()
    #输出词语
    fp=open(os.getcwd()+'\\数据输出\\2 2字词语-2汉字.txt','w',encoding='gb18030')
    for j in wb4:
        fp.write(j[0]);fp.write('\t');
        i=str(j[1]);fp.write(i);fp.write('\n')
    fp.close()

if __name__=='__main__':

    start=time();

    wb1=func01();
    n=2     #字数2
    wb4=func02(wb1,n);
    func03(wb4);

    print('Time used:',int((time()-start)/60*10)/10,'分钟')
    #os.system("pause")

#2分词-2字词2处理
from time import time as time
import re
import xlrd
import threading
import pickle
from multiprocessing import Process
from multiprocessing import cpu_count
import os
import os.path
import xlwt
import sys
import operator

def func01():   #找出词语句中的左右词语

    #提取句子
    with open(os.getcwd()+'\\数据输出\\2 2字词语-1原始.dat','rb') as fp:
        wb1=pickle.load(fp)
    with open(os.getcwd()+'\\数据输出\\2 2字词语-2汉字.dat','rb') as fp:
        wb2=pickle.load(fp)

    wb3=[];
    for j in wb2:
        wb3.append(j[0])

    for j in wb3:
        for i in range(0,len(wb1)):
            if j==wb1[i]:
                if 0<i and i<len(wb1)-1:
                    if j[0:1]==wb1[i-1][1:2]:
                        wb1[i-1]='*'
                    if j[1:2]==wb1[i+1][0:1]:
                        wb1[i+1]='*'
                    continue
                elif i==0:
                    if j[1:2]==wb1[i+1][0:1]:
                        wb1[i+1]='*'
                    continue
                elif i==len(wb1)-1:
                    if j[0:1]==wb1[i-1][1:2]:
                        wb1[i-1]='*'
    #筛选汉字词语
    wb4=[];pattern=re.compile(r'[\u4e00-\u9fa5]')
    for j in wb1:
        if len(pattern.findall(j))==len(j):
            wb4.append(j)

    #筛选唯一,并统计频数
    wb4.sort();k=0;wb5=[];
    for j in range(0,len(wb4)-1):
        k=k+1;
        if wb4[j]!=wb4[j+1]:
            wb5.append([wb4[j],k]);k=0;
    wb5.append([wb4[len(wb4)-1],k+1])
    #列表排序,降序
    wb5.sort(reverse=True,key=operator.itemgetter(1))
    return wb5

def func02(wb5):    #输出词语

    #保存词语
    fp=open(os.getcwd()+'\\数据输出\\2 2字词语-3汉字.dat','wb');
    pickle.dump(wb5,fp);
    fp.close()
    #输出词语
    fp=open(os.getcwd()+'\\数据输出\\2 2字词语-3汉字.txt','w',encoding='gb18030')
    for j in wb5:
        fp.write(j[0]);fp.write('\t');
        i=str(j[1]);fp.write(i);fp.write('\n')
    fp.close()

if __name__=='__main__':

    start=time();

    wb5=func01();
    func02(wb5);    #输出

    print('Time used:',int((time()-start)/60*10)/10,'分钟')
    #os.system("pause")
#3词语匹配句子
from time import time as time
import re
import xlrd
import threading
import pickle
from multiprocessing import Process
from multiprocessing import cpu_count
import os
import os.path
import xlwt
import sys
import operator

def func01(): #提取文件

    with open(os.getcwd()+'\\数据输出\\1 句子文件.dat','rb') as fp:
        wb1=pickle.load(fp)
    with open(os.getcwd()+'\\数据输出\\2 2字词语-3汉字.dat','rb') as fp:
        cy1=pickle.load(fp)
    return wb1,cy1

def func02(cy2,wb1,xhlb,j): #词语匹配句子

    wb2=[];kk=None;
    for j in xhlb:
        wb2.append([cy2[j]])
        for i in wb1:
            if cy2[j] in i:
                wb2[len(wb2)-1].append(i);
        if len(wb2[len(wb2)-1])<2: #句子数小于1的一律不要(第1个是词语,后面是句子)######################################
            wb2.pop();
    if len(wb2)==0:
        wb2=[['***','***']];
    fp=open(os.getcwd()+'\\数据1\\shuju'+ str(j+1) +'.dat','wb');
    pickle.dump(wb2,fp); #保存数据
    fp.close()

def func03(wb1,cy1): #并行进程,句子,词语

    k=int(cpu_count());    #CPU核心数
    print('CPU核心数:',k)
    cs=os.path.isdir(os.getcwd()+'\\数据1'); #判断 数据1 文件夹是否存在
    if cs==False:
        os.mkdir(os.getcwd()+'\\数据1');
    cy2=[];
    for j in cy1:
        if j[1]>10:             #筛选词语频数大于10##############################################################
            cy2.append(j[0])
    print('词语总数:',len(cy2));
    nrows=list(range(0,len(cy2)));  #生成序号列表
    xhlb=[];
    for j in range(k):              #CPU核心数k
        xhlb.append([])
    xh=True
    while xh:
        for j in range(k):
            xhlb[j].append(nrows.pop()) #按组分配序号
            if nrows==[]:
                xh=False;break
    p=[];
    for j in range(0,k):
        t=Process(target=func02,args=(cy2,wb1,xhlb[j],j));  #开启多进程,导入func03方法
        p.append(t);
    for j in p:
        j.start();
    print('启动并行进程数:',k);print('正在计算,请稍等...');
    for j in p:
        j.join();
    print('全部进程已结束');
    return k;

def func04(k): #reduce部分

    wb3=[];
    for j in range(0,k):    #读取数据
        try:
            fp=open(os.getcwd()+'\\数据1\\shuju'+ str(j+1) +'.dat','rb');
            wb3.extend(pickle.load(fp));
            fp.close()
        except:
            print(os.getcwd()+'\\数据1\\shuju'+ str(j+1) +'.dat','  文件读取异常')
    func05(); #删除过程文件
    func06(wb3); #输出文件
    return wb3

def func05(): #删除过程文件

    kk=os.listdir(os.getcwd()+'\\数据1');
    for j in kk:
        os.remove(os.getcwd()+'\\数据1\\'+j)
    os.rmdir(os.getcwd()+'\\数据1');  #删除 数据1 文件夹

def func06(wb3): #输出文件

    #输出 客户发言文本
    fp=open(os.getcwd()+'\\数据输出\\3 词语匹配句子.txt','w',encoding='gb18030')
    for j in wb3:
        for i in j:
            fp.write(i);fp.write('\n');
        fp.write('\n\n')
    fp.close()
    #保存数据
    fp=open(os.getcwd()+'\\数据输出\\3 词语匹配句子.dat','wb');
    pickle.dump(wb3,fp);
    fp.close()

if __name__=='__main__':

    start=time();

    wb1,cy1=func01();
    k=func03(wb1,cy1);      #进程数=CPU核心数
    wb3=func04(k);

    print('Time used:',int((time()-start)/60*10)/10,'分钟')
    #os.system("pause")
#4词组匹配句子
from time import time as time
import re
import xlrd
import threading
import pickle
from multiprocessing import Process
from multiprocessing import cpu_count
import os
import os.path
import xlwt
import sys
import operator

def func01():    #读取数据

    fp=open(os.getcwd()+'\\数据输出\\3 词语匹配句子.dat','rb');
    wb1=pickle.load(fp);
    fp.close()
    return wb1

def func02(wb1,xhlb,ji): #词组匹配句子

    wb2=[];bj=None;
    for j in xhlb:
        for i in range(j+1,len(wb1)):
            if len(set(wb1[j][0]+wb1[i][0]))==len(wb1[j][0]+wb1[i][0]):
                wb2.append([wb1[j][0]+'+'+wb1[i][0]]);
                for k in wb1[i]: #提取句子
                    if wb1[j][0] in k:
                        wb2[len(wb2)-1].append(k);
                if len(wb2[len(wb2)-1])<2: #句子数小于1的一律不要(第1个是词语,后面是句子)######################################
                    wb2.pop();
    if len(wb2)==0:
        wb2=[['***','***']];
    fp=open(os.getcwd()+'\\数据2\\shuju'+ str(ji+1) +'.dat','wb');
    pickle.dump(wb2,fp); #保存数据
    fp.close()

def func03(wb1): #并行进程

    k=int(cpu_count()); #CPU核心数
    print('CPU核心数:',k)
    cs=os.path.isdir(os.getcwd()+'\\数据2'); #判断 数据2 文件夹是否存在
    if cs==False:
        os.mkdir(os.getcwd()+'\\数据2');
    nrows=list(range(0,len(wb1)));
    xhlb=[];
    for j in range(k):
        xhlb.append([])
    xh=True
    while xh:
        for j in range(k):
            xhlb[j].append(nrows.pop())
            if nrows==[]:
                xh=False;break
    p=[];
    for j in range(0,k):
        t=Process(target=func02,args=(wb1,xhlb[j],j)); #开启多进程,导入func02方法
        p.append(t);
    for j in p:
        j.start();
    print('启动并行进程数:',k);print('正在计算,请等待...');
    for j in p:
        j.join();
    print('全部进程已结束');
    return k;

def func04(k):  #reduce部分

    wb3=[];aa=[];
    for j in range(0,k):    #读取数据
        try:
            fp=open(os.getcwd()+'\\数据2\\shuju'+ str(j+1) +'.dat','rb');
            wb3.extend(pickle.load(fp));
            fp.close()
        except:
            print(os.getcwd()+'\\数据2\\shuju'+ str(j+1) +'.dat','  文件读取异常')
    #排序
    for j in range(0,len(wb3)):
        wb3[j].insert(0,len(wb3[j])-1);
    wb3.sort(reverse=True,key=operator.itemgetter(0));
    func05(); #删除过程文件
    func06(wb3); #输出文件
    return wb3

def func05(): #删除过程文件

    kk=os.listdir(os.getcwd()+'\\数据2');
    for j in kk:
        os.remove(os.getcwd()+'\\数据2\\'+j)
    os.rmdir(os.getcwd()+'\\数据2');  #删除 数据2 文件夹

def func06(wb3): #输出文件

    #保存词语
    fp=open(os.getcwd()+'\\数据输出\\4 词组匹配句子.dat','wb');
    pickle.dump(wb3,fp);
    fp.close()
    #输出词语
    fp=open(os.getcwd()+'\\数据输出\\4 词组匹配句子.txt','w',encoding='gb18030')
    for j in wb3:
        for i in j:
            fp.write(str(i));fp.write('\n')
        fp.write('\n\n')
    fp.close()

def func07(wb3):   #统计频数

    #新建xlsx文件
    w = xlwt.Workbook()
    ws = w.add_sheet('词组匹配句子统计表')
    ws.write(0,0,'词组');ws.write(0,1,'频数');
    x=1;y=0;
    for j in wb3:
        ws.write(x,0,j[1]);ws.write(x,1,str(j[0]));x=x+1;
    w.save(os.getcwd()+'\\数据输出\\4 词组匹配句子统计表.xls')
    return wb3

if __name__=='__main__':

    start=time();

    wb1=func01();
    k=func03(wb1);
    wb3=func04(k);
    func07(wb3);

    print('Time used:',int((time()-start)/60*10)/10,'分钟')
    #os.system("pause")

需要把文本文件保存为txt格式。请忽略import部分,不想核对了。文件不要太大了,分词后处理的时候有点耗时,10M以内。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值