首先我的原始數據是這樣的,關於爬蟲請看http://blog.csdn.net/jemila/article/details/61196863
我的數據鏈接:http://pan.baidu.com/s/1hskNlEO 密碼:dxv5
加載以下模塊
import os
import jieba
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
from langconv import *
from langconv import *加載這個模塊是爲了簡繁轉換
加載停止詞
f=open(r'C:/Users/user/Desktop/stopword.txt')
stopwords = f.readlines()
stopwords = [i.replace("\n","").decode("gbk") for i in stopwords]
定義一個分詞函數
def sent2word(sentence):
"""
Segment a sentence to words
Delete stopwords
"""
segList = jieba.cut(sentence)
segResult = []
for w in segList:
segResult.append(w)
newSent = []
for word in segResult:
if word in stopwords:
# print "stopword: %s" % word
continue
else:
newSent.append(Converter('zh-hans').convert(word.decode('utf-8')))
return newSent
定義一個新建文件夾函數
def mkdir(path):
# 引入模塊
import os
# 去除首位空格
path=path.strip()
# 去除尾部 \ 符號
path=path.rstrip("\\")
# 判斷路徑是否存在
# 存在 True
# 不存在 False
isExists=os.path.exists(path)
# 判斷結果
if not isExists:
# 如果不存在則創建目錄
print path+' 創建成功'
# 創建目錄操作函數
os.makedirs(path)
return True
else:
# 如果目錄存在則不創建,並提示目錄已存在
print path+' 目錄已存在'
return False
定義一個列表轉文字的函數,因爲每一句分詞之後返回的是一個列表,轉成文字才能保存到新的文件當中
def list_to_str(list):
new_str =''
for i in range(len(list)):
new_str = new_str+' '+list[i]
return new_str
加載文件夾,讀取並且分詞,注意如果文件中某一行包括分號的,就是作詞和作曲啦,這類信息不用。還有就是純音樂的也直接去掉。
test=r'C:/Users/user/Desktop/lyrics/'
p = unicode(test,'utf-8')
list_dir=os.listdir(p)
for i,j in enumerate(list_dir):
path_rude = u'C:/Users/yunfang/Desktop/lyrics/%s'%j
list_dir_dir=os.listdir(path_rude)
for x,y in enumerate(list_dir_dir):
path2_rude=r'C:/Users/yunfang/Desktop/lyrics/%s/%s'%(j,y)
f_test= open(path2_rude)
print "正在打開",j,"文件夾的",y,"文件"
word=''
for line in f_test.readlines():
if ":" in line or u"純音樂" in line :
continue
else:
result = sent2word(line)
if result ==[]:
continue
else:
list_str = list_to_str(result)
word=word+u'\n'+list_str
mkpath=r"C:/Users/yunfang/Desktop/lyrics_result/%s"%j
mkdir(mkpath)
f_result=open(u'C:/Users/yunfang/Desktop/lyrics_result/%s/%s'%(j,y),'w')
f_result.write(str(word))
f_result.close()
f_test.close()
print "正在關閉",j,"文件夾的",y,"文件"
f.close()
提取部分,想到TF-IDF和主題模型LDA。首先我做了TF-IDF發現不太合適用來分析,因爲TF-IDF=詞頻*逆文檔頻率。詞頻表示文章中某個詞出現的次數,逆文檔頻率表示如果某個詞比較少見,但是它在某篇文章中多次出現,那麼它很可能就反映了這篇文章的特性,它就更有可能揭示這篇文字的話題所在。於是當一個詞在某段歌詞中出現的頻率極高(跟分詞有關係),在其他歌詞中出現頻率極低,就會挖掘成關鍵詞,於是對於12個歌手,運用TF-IDF的結果如下。比如,一隻,在低苦艾的《不叫鳥》中出現了無數次,然而其他歌詞竟然頻率極地。再比如,ll,其實是在草東沒有排隊中的《等》,歌詞是說,you will wait you will wait you will keep on wait,you will wait you will wait you will wait for nothing ”。分詞結果變成,I ll wait I ll wait I ll keep on waiting, I ll wait I ll wait I ll wait for nothing。於是出現了ll這種尷尬分詞,
低苦艾 | 一隻 | 0.326554546 |
反光鏡 | 瞬間 | 0.230418286 |
周雲蓬 | 呼吸 | 0.406213645 |
好妹妹樂隊 | 再見 | 0.372984749 |
海龜先生 | the | 0.563802482 |
竇唯 | 結束 | 0.352856921 |
草東沒有派對 | ll | 0.508105904 |
趙雷 | 北京 | 0.335062454 |
逃跑計劃 | 再見 | 0.45489933 |
郝雲 | 生活 | 0.268754262 |
陳粒 | 一步 | 0.218289286 |
馬頔 | 親愛 | 0.28473938 |
算法部分寫下,免得以後忘了,不過文件夾也是夠多了,我是新手代碼用的也不是很簡潔。。。生成一個concat文件夾,放置分詞後的所有文件合併後的txt文件,並且命名爲歌手名字。
path = u"C:/Users/user/Desktop/lyrics_result/"
listdir = os.listdir(path)
for i in listdir:
path_way =u"C:/Users/user/Desktop/lyrics_result/%s/"%(i.split(".")[0])
listdir_dir = os.listdir(path_way)
text_list=""
for j in listdir_dir:
path_acc=u"C:/Users/user/Desktop/lyrics_result/%s/%s"%(i.split(".")[0],j)
file = open(path_acc)
text = list_to_str(file.readlines())
text_list=text_list+text
print "this is ",i
f_result=open(u'C:/Users/user/Desktop/lyrics_concat/%s.txt'%(i),'w')
f_result.write(text_list)
f_result.close()
讀取合併後的TXT文件,並生成向量path = u"C:/Users/user/Desktop/lyrics_concat/"
listdir = os.listdir(path)
arr=[]
for i in listdir:
data=[]
path_way =u"C:/Users/user/Desktop/lyrics_concat/%s"%(i)
text_list=""
print i
file = open(path_way)
text = list_to_str(file.readlines())
dataList = text.split('\n')
for oneline in dataList:
if oneline is not u" ":
data.append(unicode(oneline.strip(),'utf-8'))
data = [ x for x in data if x != '' ]
arr.append(data)
file.close()
#arr爲12個子列表的二層列表,將其重新生成一層列表12個元素
word_list = []
for i in arr:
text = ""
for j in i:
text = text+" "+j
word_list.append(text)
接下來用TF-IDF計算 ,name爲提取的詞頻>=3的單詞,weight爲其權重
from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer(min_df=3)#至少多少個詞能當詞庫
vectorizer.fit_transform(word_list)
name = vectorizer.get_feature_names()
weight = vectorizer.fit_transform(word_list).toarray()