论文首次处理流程及代码
原始文件格式说明:
新浪微博sina_weibo.data:
關鍵詞 微博id 用户id 微博url 創建時間 内容 頭像url 視頻url 音樂url 發博來源 轉發數 評論數 贊數 所轉發微博id 所評論微博id(目前都是0) 抓取時間
微博大V新浪微博: 微博id 用户id 微博url 創建時間 内容 頭像url 視頻url 音樂url 發博來源 轉發數 評論數 贊數 所轉發微博id 所評論微博id(目前都是0) 抓取時間 新浪用户信息: 用户id 昵稱 property domainname 性别 描述 用户類型 認證原因 location 省份/城市 null 圖片url 博客url 微號 生日 星座 關注數 粉絲數 微博數 qq msn mail 性取向 情感狀况 血型 關注列表 粉絲列表 標簽列表 創建時間 更新時間
<program>.tilte(也经过通过grep ‘节目名称’)
微博内容 创建时间 用户id
<program>.uniq (对微博内容进行去重)
微博内容 创建时间 用户id
1,将原始文件sina.data首先使用文件进行过滤
(1)按照节目名称过滤出各个节目对应的子文件,并提取出对应字段,对于一个节目名称有多种叫法的,使用多种叫法,最终再进行合并
1 #!/bin/bash 2 root_dir=/home/bobo/paperFormal 3 conf_dir="$root_dir"/conf 4 raw_data_dir="$root_dir"/raw_data 5 source_file=$raw_data_dir/sina_weibo.data 6 7 echo "read file_name_list and filter by title.." 8 while read line 9 do 10 rm -rf $raw_data_dir/$line 11 mkdir $raw_data_dir/$line 12 cat $source_file | grep $line | awk -F'\t' '{print $6"\t"$5"\t"$3}'>$raw_dat a_dir/$line/$line.title 13 done<$conf_dir/program_name.list
将一个名称有集中叫法的文件合并,包括“扰民了你”、“绕民了您”;“想你的365天”,“想你365天”;“群发的我不回”、“群发短信我不回”;“英雄组歌”、“英雄赞歌”,“盛世欢歌”,“欢歌”;,其中英雄赞歌可能有点问题,不建议使用
(这个数据实在自己老式的笔记本上paperFormal目录下)
(2)去除微博中的短链接,之后再对内容进行去重处理,
14 15 echo "uniq the weibo content" 16 program_list=`ls $raw_data_dir` 17 for program_name in $program_list 18 do 19 echo $program_name >> $root_dir/data.statics 20 wc -l $raw_data_dir/$program_name/$program_name.title >> data.statc is 21 cat $raw_data_dir/$program_name/$program_name.title | sort -t ' ' -k 1 | awk -F'\t' '{print $2"\t"$3"\t"$1}' | uniq -f 2 | awk -F'\t' '{print $3 "\t"$1"\t"$2}' > $raw_data_dir/$program_name/$program_name.uniq 22 wc -l $raw_data_dir/$program_name/$program_name.uniq >> data.statci s 23 echo "$program_name" is done! 24 done
sed -i '1,$s/http:\/\/t\.cn\/[a-zA-Z0-9]\{7\}//g' *.sample cat *.sample | awk -F'\t' '{print $1"\t"$3"\t"$4"\t"$2}' | uniq -f 3 | awk -F'\t' '{print $1"\t"$4"\t"$2"\t"$3}'
以上步骤其实可以合并和改进,而且可以看出,将内容放在一行的最后一列字段便于进行去重
最后一团圆饭.sample为例,所有微博都包含“团圆饭”这个词。实验目的,去除“团圆饭”这个词的歧义性。
经过通过标题筛选,去除链接,文本去重之后。剩余样本1184条,其中正样本为569,负样本为615
方法一、利用TF-IDF加权,
接下来,对单个词进行tf-idf加权,其中出现了一个bug,文件输出的时候,记住及时flush的重要性!(在老式笔记本paperProgram的工程目录下)
其中出现了一个bug,文件输出的时候,记住及时flush的重要性!
tf-idf的输出文件为团圆饭.tfidf;word_id.map
使用航总的深度学习进行分类。
利用tf-idf进行加权,将标注数据分为三类。
训练集:data.train(369条负样本,342条正样本)
测试集:data.test(123条负样本,123条正样本)
验证集:data.verfied(123条负样本,123条正样本)
利用svm进行分类:
最终结果的准确率为:
方法二,抽取属性进行加权
1.Features Based On Show Titles:节目名称集(某个特定节目,可能有多种叫法,如欢歌这个节目,有的网站又叫做盛世欢歌,对于一个节目,用其的名称搜索得到备选微博<难道使用>)(0,1加权) 2.General Features based on Terms which is related to TV watching: 该特征集包括tv_terms(0.5): 观看、收看、演出、播出、表演、节目、电视; Network_terms: 央视、中央电视台(0.25); Context_genres:春晚、春节联欢晚会(0.25)<.这两个实际中还是pass吧,因为采用的貌似是组合搜索> (这个对于每一个节目都适应,使用祝博的同义词拓展可以拓展一下) 3.Features Based on Show genres:(或者叫做show profile) 包括actors_genres: 节目对应的演员名称(1), Category_genres(1):节目对应的类型特征,如歌曲、小品、相声、舞蹈、歌舞等 对于节目类别可以进行近义词拓展 3) Features based on rules (on negative rules) 3.1)词频规则:寻找出现共同出现次数高的词: 和正样本同时出现次数多的词:统计正样本中和title同时出现次数高的词频,选择top20 和负样本同时出现次数多的词:统计负样本中和title同时出现次数高的词频,选择top20 以上按照词出现的次数进行归一化:word_time/max_word_time。这个维度为20+20=40 搭配规则:寻找常见搭配: 以节目名称,向前找一位,向后找一位,去常见搭配的top10(这个维度为20) 正样本中的常见搭配: 负样本中的常见搭配: 如果微博中出现常见搭配:(+-)
自己分别使用了自己的加权方法,word-bag的加权方法,tf-idf的加权方法,并检验了相应的分类指标:precision,recall,accuracy,f,roc
代码如下:
#!/usr/python #!-*-coding=utf8-*- import numpy as np import random from sklearn import cross_validation from sklearn import svm from sklearn import metrics from sklearn.feature_extraction.text import CountVectorizer from sklearn.feature_extraction.text import TfidfVectorizer import pylab as pl root_dir='/home/bobo/paperProgram' def preDataByWordBag(): print "start to preDataBywordBag..." in_file_name=root_dir+'/raw_data/tuanyuanfan.fenci' v=CountVectorizer(min_df=1) corpus=list() label_list=list() with open(in_file_name) as in_file: for line in in_file: label_list.append(int(line.strip().split('\t')[0])) corpus.append(line.strip().split('\t')[1]) data_list=v.fit_transform(corpus) label_list=np.array(label_list) return (data_list,label_list) def preDataByTfidf(): print "start to preDataByTfIdf..." in_file_name=root_dir+'/raw_data/tuanyuanfan.fenci' v=TfidfVectorizer(min_df=1) corpus=list() label_list=list() with open(in_file_name) as in_file: for line in in_file: label_list.append(int(line.strip().split('\t')[0])) corpus.append(line.strip().split('\t')[1]) data_list=v.fit_transform(corpus) label_list=np.array(label_list) return (data_list,label_list) def preData(): print "start to preDataByMyOwn..." in_file_name=root_dir+'/raw_data/tuyuanfan.weight1' label_list=list() data_list=list() with open(in_file_name) as in_file: for line in in_file: line_list=list() label_list.append(int(line.strip().split('\t')[0])) all_features=line.strip().split('\t')[1:] for feature in all_features: line_list.append(float(feature)) data_list.append(line_list) data_list=np.array(data_list) # print data_list label_list=np.array(label_list) # print label_list print "datePre is done..." return (data_list,label_list) def trainModel(data,classifier,n_folds=5): print "start to trainModel..." x=data[0] y=data[1] #shupple samples n_samples,n_features=x.shape print "n_samples:"+str(n_samples)+";n_features"+str(n_features) p=range(n_samples) random.seed(0) random.shuffle(p) x,y=x[p],y[p] #cross_validation cv=cross_validation.KFold(len(y),n_folds=5) mean_tpr=0.0 mean_fpr=np.linspace(0,1,100) mean_recall=0.0 mean_accuracy=0.0 mean_f=0.0 mean_precision=0.0 for i,(train,test) in enumerate(cv): print "the "+str(i)+"times validation..." classifier.fit(x[train],y[train]) y_true,y_pred=y[test],classifier.predict(x[test]) mean_precision+=metrics.precision_score(y_true,y_pred) mean_recall+=metrics.recall_score(y_true,y_pred) # mean_accuracy+=metrics.accuracy_score(y_true,y_pred) mean_accuracy+=classifier.score(x[test],y_true) mean_f+=metrics.fbeta_score(y_true,y_pred,beta=1) probas_=classifier.predict_proba(x[test]) fpr,tpr,thresholds=metrics.roc_curve(y[test],probas_[:,1]) mean_tpr+=np.interp(mean_fpr,fpr,tpr) mean_tpr[0]=0.0 roc_auc=metrics.auc(fpr,tpr) pl.plot(fpr,tpr,lw=1,label='ROC fold %d (area=%0.2f)'%(i,roc_auc)) pl.plot([0,1],[0,1],'--',color=(0.6,0.6,0.6),label='luck') mean_precision/=len(cv) mean_recall/=len(cv) mean_f/=len(cv) mean_accuracy/=len(cv) print("mean_precision:%0.2f,mean_recall:%0.2f,mean_f:%0.2f,mean_accuracy:%0.2f " % (mean_precision,mean_recall,mean_f,mean_accuracy)) mean_tpr/=len(cv) mean_tpr[-1]=1.0 mean_auc=metrics.auc(mean_fpr,mean_tpr) pl.plot(mean_fpr,mean_tpr,'k--',label='Mean ROC (area=%0.2f)'% mean_auc,lw=2) pl.xlim([-0.05,1.05]) pl.ylim([-0.05,1.05]) pl.xlabel('False Positive Rate') pl.ylabel('True Positive Rate') pl.title('ROC') pl.legend(loc="lower right") pl.show() def removeOneFeatureThenTrain(data,clf): x=data[0] y=data[1] n_samples,n_features=x.shape for i in range(n_features): print 'remove ' + str(i+1) + ' feture...' data_one=x[:,0:i] data_two=x[:,(i+1):n_features] data_leave=np.column_stack((data_one,data_two)) trainModel((data_leave,y),clf) def chooseSomeFeaturesThenTrain(data,clf,choose_index): x=data[0] y=data[1] (n_samples,n_features)=x.shape result_data=np.zeros(n_samples).reshape(n_samples,1) for i in choose_index: if i<1 or i > n_features: print 'error feature_index' return choose_column=x[:,(i-1)].reshape(n_samples,1) result_data=np.column_stack((result_data,choose_column)) result_data=(result_data[:,1:],y) trainModel(result_data,clf) def main(): #采用svm进行分类 clf=svm.SVC(kernel='linear',C=1,probability=True,random_state=0) #采用自己提取的属性赋权重 # print "using my own weight strategory..." # data=preData() # trainModel(data,clf) # #采用word-bag赋权重 # print "using wordBag strategory..." # data=preDataByWordBag() # trainModel(data,clf) #采用tf-idf赋权重 # print "using tfidf strategory..." # data=preDataByTfidf() # trainModel(data,clf) #利用系统的10倍交叉验证功能 #data_list=data[0] #label_list=data[1] #scores=cross_validation.cross_val_score(clf,data_list,label_list,cv=5) #print scores #print("Accuracy:%0.2f(+/-%0.2f)"%(scores.mean(),scores.std()**2)) #每次去除一个属性进行判断 print "begin to remove one feature at one time..." #data=preData() #removeOneFeatureThenTrain(data,clf) #每次选择若干属性组合进行判断 print "begin to choose some features.." data=preData() n_samples,n_features=data[0].shape for i in range(1,n_features+1): chooseSomeFeaturesThenTrain(data,clf,[i]) if __name__=='__main__': main()
结果如下:
自己的加权方法:
mean_precision:0.98,mean_recall:0.96,mean_f:0.97,mean_accuracy:0.97
wrod_bag的加权方法:
mean_precision:0.97,mean_recall:0.97,mean_f:0.97,mean_accuracy:0.97
tf-idf的加权方法:
mean_precision:1.00,mean_recall:0.95,mean_f:0.97,mean_accuracy:0.98
相关讨论:每次去除一个属性,差别不大,都在97%左右
每次仅仅使用一个属性(依次是演员名称,类别名称,正频词,负频词,正频搭配,负频搭配),结果是:
使用演员名称:
mean_precision:1.00,mean_recall:0.74,mean_f:0.85,mean_accuracy:0.87
使用节目类别:
mean_precision:0.98,mean_recall:0.90,mean_f:0.94,mean_accuracy:0.94
使用正频词汇:
mean_precision:0.96,mean_recall:0.94,mean_f:0.95,mean_accuracy:0.95
使用负频词汇:
mean_precision:0.79,mean_recall:0.93,mean_f:0.85,mean_accuracy:0.85
使用正向表达:
mean_precision:1.00,mean_recall:0.58,mean_f:0.73,mean_accuracy:0.80
使用负向表达:
mean_precision:0.96,mean_recall:0.94,mean_f:0.95,mean_accuracy:0.95
经过测试,还是使用sina.data的输出效果最好。