论文首次处理流程及代码

原始文件格式说明:

新浪微博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进行加权

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()    
tf-idf,自己加权,word-bag提取特征的方法以及分类的常见验证和属性贡献度衡量

 

结果如下:

自己的加权方法:

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/经过关键词加权过滤的/处理后的,实验室台式机上的sina60.text文件作为祝博同义词拓展的训练输入(共1555171条)
执行语句为./distance sina60.bin
如果采用sina.unfiltered/没有经过关键词加权过滤的/作为同义词拓展库的训练数据(共9375516条) 作为祝博同义词拓展的训练输入(共)
该拓展库是利用从除夕、初一和初二这三天,所有关键词下的数据。经过文本去重、去除链接、表情、@、去除停用词之后,一共有

 经过测试,还是使用sina.data的输出效果最好。

posted @ 2014-02-21 09:29  bobo的学习笔记  阅读(329)  评论(0编辑  收藏  举报