文本挖掘机器学习与数据挖掘NLP 自然语言处理

文本挖掘——实践总结(

2017-09-21  本文已影响168人  H2016

以下内容都是在工作中的一些小实践,代码部分是参考网上的已有的然后再自行根据情况修改过的。记载主要是想以后用的时候可以更方便的直接拿过来用。

注:工作所需,程序是在knime这个数据挖掘软件的python下运行的,结果是截图过来的,可能模糊,可以自己实践代码。


文章内容: jieba分词(包括分词、关键词提取、词性标记)、word2vec、LDA、Kmeans四大模块算法的理论归纳及简单实现代码与果。

完成时间:1个星期左右时间。 其中,python部分2天左右,knime部分花费时间较长。

所用软件:python,  Knime(python脚本完成)。

所用主要模块:NLTK、 Sklearn、pandas、Scipy、numpy、gensim(Word2vec部分),jieba。

遇到的主要问题:KNIME软件python脚本里中文编码问题、KNIME运行非常慢、KNIME的文件流入流出端还不是很熟练、KNIME其他数据预处理结点还不是很熟练。

后续计划:首先,因为之前时间并不多,所以还未实现其他文本挖掘算法,比如,SVM、 随机森林、kNN、CNN(类似其他神经网络算法)、 NLP其他功能、朴素贝叶斯等,这些算法在python里很好实现,在KNIME里需要改进运行效率。其次,希望可以对knime的python脚本运行效率作以改进,对KNIME数据流入流出数据库作以实践与熟练,还有就是对模型参数的多次训练,比如,本文实践的kmeans算法,参数K目前设置的是3,聚类预测准确率也就在60%左右,模型还不是很好,需要时间再调参训练。最后,希望对knime其他挖掘软件及结点作以实践,比如weka(这个软件比较熟悉,希望后面多了解)、R、matlab等。

jieba分词:

词性标记代码部分:

# Copy input to output

output_table_1 = input_table_1.copy()

output_table_2 = input_table_2.copy()

#!/usr/bin/python

import sys

#reload(sys)

#sys.setdefaultencoding('utf-8')

import jieba

import jieba.posseg as pseg #主要用jieba里的pseg做词性标记

import jieba.analyse

# 对句子进行分词

def seg_sentence(sentence):

sentence_seged = pseg.cut(sentence.strip())

stopwords = []

for line in output_table_2.values: #遍历停用词DataFrame

#print

line[0]

stopwords.append(line[0])

outstr = ''

for word in sentence_seged:

if word not in stopwords: #去除停用词

if word!='\t':

for word1, flag in

sentence_seged: #遍历分词及分词词性

#print'%s %s' % (word1,

flag)

outstr

+=word1+'\t'+flag+'\n'

else:

outstr += " "

return outstr

#out_table=DataFrame()

for line in output_table_1.values:

line_seg = seg_sentence(line[0]) # 这里的返回值是字符串

print line_seg

#output_table_1['fenci']=line_seg

词性标记脚本结果:

特征词提取代码部分(提取了权重top100的词):

# Copy input to output

output_table = input_table.copy()

#!/usr/bin/python

import sys

import pandas

from pandas import DataFrame

#reload(sys)

#sys.setdefaultencoding('utf-8')

import jieba

import jieba.posseg as pseg

import jieba.analyse #主要用到jieba里的analyse做特征词提取

#finename='C:\\Users\\AAS-1413\\Desktop\\r.txt'

words = ''

#f = open("goods11.txt",

"w")

#with open(finename,'r') as f1:

for line in input_table['Col0']:

#print

line

words+=line

#print

words

#f2=f1.readlines()

tags = jieba.analyse.extract_tags(words,

topK=100, withWeight=True, allowPOS=()) #特征词提取关键部分,该函数里的参数可以自行修改,allowPOS参数可以自行设置提取词的词性

for wd, weight in tags:

print

wd, weight

#output_table['fe']=wd

#output_table['f']=weight

#f.close()

特征词提取脚本结果:

jieba分词:

# Copy input to output

output_table_1 = input_table_1.copy()

output_table_2 = input_table_2.copy()

#!/usr/bin/python

import sys

#(sys)

#sys.setdefaultencoding('utf-8')

import jieba #该部分主要用jieba

import jieba.posseg as pseg

import jieba.analyse

# 对句子进行分词

def seg_sentence(sentence):

sentence_seged = jieba.cut(sentence.strip())

stopwords = []

for line in output_table_2.values:

#print

line[0]

stopwords.append(line[0])

outstr = ''

for word in sentence_seged:

if word not in stopwords:

if word != '\t':

outstr +='/'+word

else:

outstr += " "

return outstr

#out_table=DataFrame()

for line in output_table_1.values:

line_seg = seg_sentence(line[0])

print line_seg

分词脚本结果:

word2vec:

word2vev是一个浅层的神经网络算法。本文主要是利用python模块下gensim框架来调用word2vec实现先对文本分词,再对分词结果训练word2vec模型(word2vec模型训练过程中的参数可以修改),然后利用训练好的word2vec模型来做了简单的应用,比如,计算两个词的相似度,计算与一个词相关的所有其他词,寻找词语之间的对应关系,在一堆词语里寻找出不合群的词语。该模型目前大多用于对词语的分析挖掘中,所以对拿到的文本首先要做分词。

对文档分词脚本结果:

训练word2vec模型及简单应用代码:

import pandas

import numpy

# Copy input to output

output_table = input_table.copy()

from gensim.models import word2vec

sentences=word2vec.Text8Corpus(u'C:\\Python27\\fenci_result.txt')

model=word2vec.Word2Vec(sentences,

size=100) #训练模型,很多默认参数在此省略

#计算两个词的相似度/相关程度

y1=model.similarity(u"包装",

u"物流")

print "包装和物流的相似度为:", y1

print "-------------\n"

# 计算某个词的相关词列表

y2 = model.most_similar(u"不错",

topn=10) # 10个最相关的

#rint u"和【配置】最相关的词有:\n"

for item in y2:

print item[0], item[1]

print"--------------\n"

# 寻找对应关系

print u"包装-可以,物流-"

y3 =model.most_similar([u'包装', u'可以'], [u'物流'],

topn=10)

for item in y3:

print item[0], item[1]

print

"--------------------------\n"

# 寻找不合群的词

y4 =model.doesnt_match(u"包装 细心 可以 精美 不错 喜欢 很好".split())

print u"不合群的词:", y4

print"--------------------------------\n"

计算两个词的相似度/相关程度脚本结果:

计算某个词的相关词列表脚本结果:

寻找对应关系脚本结果:

寻找不合群的词脚本结果:

LDA模型部分:

LDA模型主要应用于对很多文档的主题分析上。关键部分是建立各个文档与词干的矩阵向量,该部分可以有很多方法,比如用tfidf或者本文用的doc2bow等。

本LDA模型建立步骤:导入文档——清洗文档——分词——去除停用词——词干提取——创建 document-term matrix矩阵(算法主旨部分)——训练LDA——应用LDA

LDA脚本代码:

import sys

# Copy input to output

output_table = input_table.copy()

#print input_table.values

#!/usr/bin/env python

import nltk

from nltk.tokenize import RegexpTokenizer

from stop_words import get_stop_words

from nltk.stem.porter import PorterStemmer

from gensim import corpora, models

import gensim

import jieba

# 创建词干

p_stemmer = PorterStemmer()

# 创建简单文档

doc_a = "活动非常不错,本来准备让美国同学带的,一合计还不如旗舰店买划算。我膝关节滑膜炎自己吃保健用的。"

doc_b = "价格钜惠,家人腰椎间盘滑脱随时脚麻,希望吃了有效果,有效果来追加评价通过扫码查了下,的确是美国进口,相信旗舰店的品质!"

doc_c = "前半小时包税,结果我过了3分钟,没包成税,多花了70多,老人家长期吃长期需要买,看来要收藏好随时关注活动!"

doc_d = "听别人说这种保健品很有效,老人膝盖很疼,希望吃了会有效果。货物发自保税仓,验证码很麻烦,就没有试。吃过再追评。"

doc_e = "有时会觉得膝盖活动不那么灵活,关键才三十多岁,在网上看到大家评价不错,先买两瓶试试。"

#简单文档列表

doc_set = [doc_a, doc_b, doc_c, doc_d,

doc_e]

# 对文档列表作循环

texts=[]

for i in doc_set:

#

clean and tokenize document string

tokens = jieba.cut(i)

stopped_tokens = [i for i in tokens if not i in input_table.values]

stemmed_tokens = [p_stemmer.stem(i) for i in stopped_tokens]

texts.append(stemmed_tokens)

#print texts

#print stemmed_tokens

# 创建字典

dictionary = corpora.Dictionary(texts)

#print dictionary

#print dictionary.token2id#不重复的词的ID

# 创建 词-文档 矩阵

corpus = [dictionary.doc2bow(text) for text

in texts]

print corpus[0]#词向量

# 应用LDA模型

ldamodel =

gensim.models.ldamodel.LdaModel(corpus, num_topics=2, id2word = dictionary,

passes=20) #训练模型,该部分参数可自行修改

print ldamodel.print_topics(num_topics=2,

num_words=8)#应用LDA模型,该处自行设置2个主题,8个分词

t=''

for i in

ldamodel.print_topics(num_topics=2, num_words=8): #2个主题,8个分词

for

w in i:

t+=str(w)+'\n'

print t

主题生成脚本结果:

应用模型结果解释:打印出的corpus[0]([0]表示第一文档)就是截图结果里的第一行的向量部分,该部分的每个向量第一个数字表示词干ID,第二个数字表示该词干在第一个文档里出现的次数。打印出的 ldamodel.print_topics(num_topics=2, num_words=8),就是最下面的8个随机词干组成的两个主题,每个词干前对应该词干的权重。打印出的中间部分编码暂时有点问题。

Kmeans:

聚类算法

from __future__ import print_function

from sklearn.feature_extraction.text import

TfidfVectorizer

from sklearn.feature_extraction.text import

HashingVectorizer

import matplotlib.pyplot as plt

from sklearn.cluster import KMeans,

MiniBatchKMeans

import os

# Copy input to output

output_table = input_table.copy()

def loadDataset():

'''导入文本数据集'''

#FindPath = 'C:\\Users\\AAS-1413\\Desktop\\tokens\\pos\\'

#

FileNames = os.listdir(FindPath)

dataset=[]

for line in input_table['Col0']:

#print (line)

dataset.append(line)

return dataset

def transform(dataset,n_features=1000):

vectorizer = TfidfVectorizer(max_df=0.5, max_features=n_features,

min_df=2,use_idf=True)

X

= vectorizer.fit_transform(dataset)

return X,vectorizer

def train(X,vectorizer,true_k=3,minibatch =

False,showLable = False):

#使用采样数据还是原始数据训练k-means,

if minibatch:

km = MiniBatchKMeans(n_clusters=true_k, init='k-means++', n_init=1,

init_size=1000,

batch_size=1000, verbose=False)

else:

km = KMeans(n_clusters=true_k, init='k-means++', max_iter=300, n_init=1,

verbose=False)

km.fit(X)

if showLable:

print (u"聚类结果主要词条:")#

top terms per cluster

order_centroids = km.cluster_centers_.argsort()[:, ::-1]

terms = vectorizer.get_feature_names()

#print (vectorizer.get_stop_words())

for i in range(true_k):

print("\n Cluster %d:\n" % i, end='')

for ind in order_centroids[i, :10]:

print(' %s' % terms[ind], end='')

#print

result = list(km.predict(X))

#print('\n----------------------------------------------------------')

print (u'\n\n类分配:')#Cluster distribution

print (dict([(i, result.count(i)) for i in result]))

return -km.score(X)

def test():

'''测试选择最优参数'''

dataset = loadDataset()

print("%d documents" % len(dataset))

X,vectorizer = transform(dataset,n_features=500)

true_ks = []

scores = []

for i in xrange(3,80,1):

score = train(X,vectorizer,true_k=i)/len(dataset)

print (i,score)

true_ks.append(i)

scores.append(score)

plt.figure(figsize=(8,4))

plt.plot(true_ks,scores,label="error",color="red",linewidth=1)

plt.xlabel("n_features")

plt.ylabel("error")

plt.legend()

plt.show()

def out():

'''在最优参数下输出聚类结果'''

dataset = loadDataset()

X,vectorizer = transform(dataset,n_features=500)

score = train(X,vectorizer,true_k=3,showLable=True)/len(dataset)

#print('\n----------------------------------------------------------')

print (u'\n聚类预测准确率:')

print (score)

#test()

out()

聚类结果:

结果解释: 本模型设置k参数为3,聚成3类。

上一篇下一篇

猜你喜欢

热点阅读