文本挖掘——實踐總結(一)

以下內容都是在工作中的一些小實踐,代碼部分是參考網上的已有的然后再自行根據情況修改過的。記載主要是想以后用的時候可以更方便的直接拿過來用。

注:工作所需,程序是在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類。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容