赞
踩
本文没有使用特别高端的挖掘算法,也没有使用专用的第三方分词工具,是基于统计的原理进行分词和文章句子的统计的。基本逻辑如下:
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以内。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。