Commits

wooparadog committed 37befa6

f

Comments (0)

Files changed (14)

tfidf/articles/用户研究思路概述-以淘宝网SNS分享为例.txt

-NS的网站上达成的第一笔交易,拿到钟爱的护肤品,突然发现:我居然没有在“我的淘宝”的“好友动态”里点击过别人分享的东西,更别提购买了。于是,有了这次的研究。
-
-一、立项:
-
-基于以上想法,本打算研究SNS用户习惯及动机(没有限定在淘宝网),希望能通过照片日志(Photo Dairy)的方法,从定性的角度研究活跃在各大SNS网站用户的特征,从而帮助淘宝网来定位自己的目标人群。但是,后来发现:在淘宝网购物的人群本身就是有自己特点的,而我的研究更多的价值点应该是放在【如何让这些网购用户成为淘宝网的SNS用户】。
-
-带着这个目标,了解了SNS下半年的业务规划,为了能够更好的让业务方得到启发和指导,更多的提升研究价值,将产品定位在【淘宝网分享】,研究使用淘宝分享的使用习惯及驱动因素。
-
-二、研究思路的确定:
-
- 
-
-一个严谨、完整的研究,我认为,定性与定量的结合是必不可少的。所以,这个项目采取了先定量、再定性、最后定量的研究过程。见图1。
-
-图1
-
-1、定量——确定目标用户:
-
-确定了要研究的产品,最重要的就是要确定目标用户了。
-
-为了让我的目标用户更“目标”,我选择了与BI(商业智能部门)同事的合作。希望BI的同事能将全网使用过SNS分享用户(当时是8月份,我们的‘分享’产品6月份上线)的特征数据进行提取、分析,帮助我们选择定性研究的样本。
-
-在这个过程中,我们发现,7月使用大分享1-2次的用户、8、9月份GMV­­­①>=3笔以上,但8、9月份没有再进行分享的用户占所有SNS大分享用户的76.2%,我们认为,这部分用户为什么不再使用SNS分享是一个很有价值的挖掘点。根据这一思路,我们将用户分为三层:见图2
-
-图2
-
-新用户:8月1日至8月17日之间,第一次进行过分享,且至少绑定了一个外网SNS网站的用户。
-
-活跃用户:6月份,7月份,8月份均进行过分享,且至少绑定了一个外网SNS网站的用户。
-
-流失用户:6月份分享过,但是7月,8月均未分享的用户,且至少绑定了一个外网SNS网站。(BI建议:调研时候可以选择分享天数>=2的用户,因为分享天数为1的用户大部分可能只是尝试下。) 注:这里并未用分享次数来定义流失。因为一个用户如果一天内分享了10次,第二天不再分享,也算作流失用户。
-
-但是,问题出来了。如果我们三个层面的用户都来做研究,可能会出现每类用户研究的都不透彻,所以,经过讨论,排出了优先级:流失用户>新用户>活跃用户。
-
- 
-
-所以,最后,目标用户确定为:使用淘宝网SNS分享的流失用户。
-
- 
-
-2、定性——以研究目的为导向,深入挖掘定性问题
-
-用户分层结束,确定了目标用户——流失用户。接下来,就是对用户的星级、在淘宝成交情况、人口特征等因素做出分析,然后进行定性研究前的抽样。具体的抽样方法不做赘述,这属于另外一个方面的问题。
-
-接下来,根据提纲,电话深访了16名买家,其中有10名流失用户和6名活跃用户,得到了诸多的定性问题,经过整理,要进行定量验证了。
-
-为什么要对活跃用户进行深访呢?在接下来的定量阶段,我会做出具体的解释。
-
- 
-
-3、定量——定性结果的量化
-
-从BI提取的数据中,流失用户最后的样本仅有3万多用户,据我们平时的问卷回收情况估算,样本量过低,这样得到的结果误差会比较大。为了保证最后实验结果的可靠性和丰富性,添加了【非流失用户】,即7、8、9月份GMV>=3笔以上的淘宝纯买家(除去流失用户)。因为这部分有效样本可以保证,而且涵盖了新用户和活跃用户,可以和流失用户在人口特征、习惯、动机、使用驱动因素上做以对比。
-
-也是因为这个原因,我们在电话调研的过程中,添加了6名活跃用户的电访。
-
-在问卷设计的过程中,面临最大的挑战就是关于驱动因素的题目。因为建立驱动因素的模型是需要很多传统的、经过诸多验证的题目来建立模型。但是SNS领域的驱动因素建模少之又少,为了保证模型的完整性和科学性,项目期间,还做了许多的桌面研究。
-
- 
-
-整个项目主要分为这三个阶段进行的。最后得到的非流失用户及流失用户的相关模型如下图:(结论仅供大家参考,由于实验设计和目标用户的不同,最后的结果可能是会有不同)
-
- 
-
-图3:有过分享经历的非流失用户做分享的原因模型
-
-圆圈越大,代表该指标用户打分越高(下同)。图中蓝色代表与购物相关的因素,红色代表用户心理层面的因素。
-
- 
-
- 图4:流失用户做分享的原因模型
-
- 
-
- 图5:有过分享经历的非流失用户不分享的因素模型
-
- 
-
- 图6:未分享过的非流失用户不分享的因素模型
-
- 
-
- 图7:非流失用户刺激因素的模型
-
- 
-
- 图8:流失用户刺激因素的模型
-
- 
-
-以上结论是我在专业同事的帮助下完成的,也是我们对SNS领域的初步探索。期待与大家更深入的探讨与交流。
-
-

tfidf/data/tag2id

Binary file modified.

tfidf/data/word2id

Binary file modified.

tfidf/data/word_id2tag_id

Binary file modified.

tfidf/find_parent_tag.py

             if i in self.word_to_id:
                 set_list.append(i)
 
-        #out = []
-        #for i in  set_list:
-        #    out.append(i)
-
         return list(set(set_list))
 
     def get_parent_tag_list_by_list(self,tag_list):
         for tag in tag_list:
             parent_tag_list = self.get_parent_tag(tag)
             out.extend(parent_tag_list)
-        #print out
         return out
     
 if __name__ == '__main__':

tfidf/misc/.ropeproject/config.py

+# The default ``config.py``
+
+
+def set_prefs(prefs):
+    """This function is called before opening the project"""
+
+    # Specify which files and folders to ignore in the project.
+    # Changes to ignored resources are not added to the history and
+    # VCSs.  Also they are not returned in `Project.get_files()`.
+    # Note that ``?`` and ``*`` match all characters but slashes.
+    # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc'
+    # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc'
+    # '.svn': matches 'pkg/.svn' and all of its children
+    # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o'
+    # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o'
+    prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject',
+                                  '.hg', '.svn', '_svn', '.git']
+
+    # Specifies which files should be considered python files.  It is
+    # useful when you have scripts inside your project.  Only files
+    # ending with ``.py`` are considered to be python files by
+    # default.
+    #prefs['python_files'] = ['*.py']
+
+    # Custom source folders:  By default rope searches the project
+    # for finding source folders (folders that should be searched
+    # for finding modules).  You can add paths to that list.  Note
+    # that rope guesses project source folders correctly most of the
+    # time; use this if you have any problems.
+    # The folders should be relative to project root and use '/' for
+    # separating folders regardless of the platform rope is running on.
+    # 'src/my_source_folder' for instance.
+    #prefs.add('source_folders', 'src')
+
+    # You can extend python path for looking up modules
+    #prefs.add('python_path', '~/python/')
+
+    # Should rope save object information or not.
+    prefs['save_objectdb'] = True
+    prefs['compress_objectdb'] = False
+
+    # If `True`, rope analyzes each module when it is being saved.
+    prefs['automatic_soa'] = True
+    # The depth of calls to follow in static object analysis
+    prefs['soa_followed_calls'] = 0
+
+    # If `False` when running modules or unit tests "dynamic object
+    # analysis" is turned off.  This makes them much faster.
+    prefs['perform_doa'] = True
+
+    # Rope can check the validity of its object DB when running.
+    prefs['validate_objectdb'] = True
+
+    # How many undos to hold?
+    prefs['max_history_items'] = 32
+
+    # Shows whether to save history across sessions.
+    prefs['save_history'] = True
+    prefs['compress_history'] = False
+
+    # Set the number spaces used for indenting.  According to
+    # :PEP:`8`, it is best to use 4 spaces.  Since most of rope's
+    # unit-tests use 4 spaces it is more reliable, too.
+    prefs['indent_size'] = 4
+
+    # Builtin and c-extension modules that are allowed to be imported
+    # and inspected by rope.
+    prefs['extension_modules'] = []
+
+    # Add all standard c-extensions to extension_modules list.
+    prefs['import_dynload_stdmods'] = True
+
+    # If `True` modules with syntax errors are considered to be empty.
+    # The default value is `False`; When `False` syntax errors raise
+    # `rope.base.exceptions.ModuleSyntaxError` exception.
+    prefs['ignore_syntax_errors'] = False
+
+    # If `True`, rope ignores unresolvable imports.  Otherwise, they
+    # appear in the importing namespace.
+    prefs['ignore_bad_imports'] = False
+
+
+def project_opened(project):
+    """This function is called after opening the project"""
+    # Do whatever you like here!

tfidf/misc/_env.py

+import sys
+reload(sys)
+sys.setdefaultencoding('utf-8')
+from os.path import dirname, abspath, join
+PWD = dirname(dirname(abspath(__file__)))
+sys.path.append(dirname(PWD))

tfidf/misc/rmse.py

+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import _env
+from tfidf.train.topic_bayes import TAG2ID, WORD2ID, BAYES_RANK
+
+def rmse(num_list):
+    if num_list:
+        length = float(len(num_list))
+        E = sum(num_list)/length
+        total = 0
+        li = map(lambda x: (x-E)**2,num_list)
+        return sum(li)/length
+
+def main():
+    topic_count = TAG2ID.get_max_id()
+    for word_id,topic_list in BAYES_RANK.iteritems():
+        print WORD2ID.get_word_by_id(word_id),rmse(map(lambda x:x[1],topic_list))
+    
+
+if __name__ == '__main__':
+    main()

tfidf/test/articles/用户研究思路概述-以淘宝网SNS分享为例.txt

+NS的网站上达成的第一笔交易,拿到钟爱的护肤品,突然发现:我居然没有在“我的淘宝”的“好友动态”里点击过别人分享的东西,更别提购买了。于是,有了这次的研究。
+
+一、立项:
+
+基于以上想法,本打算研究SNS用户习惯及动机(没有限定在淘宝网),希望能通过照片日志(Photo Dairy)的方法,从定性的角度研究活跃在各大SNS网站用户的特征,从而帮助淘宝网来定位自己的目标人群。但是,后来发现:在淘宝网购物的人群本身就是有自己特点的,而我的研究更多的价值点应该是放在【如何让这些网购用户成为淘宝网的SNS用户】。
+
+带着这个目标,了解了SNS下半年的业务规划,为了能够更好的让业务方得到启发和指导,更多的提升研究价值,将产品定位在【淘宝网分享】,研究使用淘宝分享的使用习惯及驱动因素。
+
+二、研究思路的确定:
+
+ 
+
+一个严谨、完整的研究,我认为,定性与定量的结合是必不可少的。所以,这个项目采取了先定量、再定性、最后定量的研究过程。见图1。
+
+图1
+
+1、定量——确定目标用户:
+
+确定了要研究的产品,最重要的就是要确定目标用户了。
+
+为了让我的目标用户更“目标”,我选择了与BI(商业智能部门)同事的合作。希望BI的同事能将全网使用过SNS分享用户(当时是8月份,我们的‘分享’产品6月份上线)的特征数据进行提取、分析,帮助我们选择定性研究的样本。
+
+在这个过程中,我们发现,7月使用大分享1-2次的用户、8、9月份GMV­­­①>=3笔以上,但8、9月份没有再进行分享的用户占所有SNS大分享用户的76.2%,我们认为,这部分用户为什么不再使用SNS分享是一个很有价值的挖掘点。根据这一思路,我们将用户分为三层:见图2
+
+图2
+
+新用户:8月1日至8月17日之间,第一次进行过分享,且至少绑定了一个外网SNS网站的用户。
+
+活跃用户:6月份,7月份,8月份均进行过分享,且至少绑定了一个外网SNS网站的用户。
+
+流失用户:6月份分享过,但是7月,8月均未分享的用户,且至少绑定了一个外网SNS网站。(BI建议:调研时候可以选择分享天数>=2的用户,因为分享天数为1的用户大部分可能只是尝试下。) 注:这里并未用分享次数来定义流失。因为一个用户如果一天内分享了10次,第二天不再分享,也算作流失用户。
+
+但是,问题出来了。如果我们三个层面的用户都来做研究,可能会出现每类用户研究的都不透彻,所以,经过讨论,排出了优先级:流失用户>新用户>活跃用户。
+
+ 
+
+所以,最后,目标用户确定为:使用淘宝网SNS分享的流失用户。
+
+ 
+
+2、定性——以研究目的为导向,深入挖掘定性问题
+
+用户分层结束,确定了目标用户——流失用户。接下来,就是对用户的星级、在淘宝成交情况、人口特征等因素做出分析,然后进行定性研究前的抽样。具体的抽样方法不做赘述,这属于另外一个方面的问题。
+
+接下来,根据提纲,电话深访了16名买家,其中有10名流失用户和6名活跃用户,得到了诸多的定性问题,经过整理,要进行定量验证了。
+
+为什么要对活跃用户进行深访呢?在接下来的定量阶段,我会做出具体的解释。
+
+ 
+
+3、定量——定性结果的量化
+
+从BI提取的数据中,流失用户最后的样本仅有3万多用户,据我们平时的问卷回收情况估算,样本量过低,这样得到的结果误差会比较大。为了保证最后实验结果的可靠性和丰富性,添加了【非流失用户】,即7、8、9月份GMV>=3笔以上的淘宝纯买家(除去流失用户)。因为这部分有效样本可以保证,而且涵盖了新用户和活跃用户,可以和流失用户在人口特征、习惯、动机、使用驱动因素上做以对比。
+
+也是因为这个原因,我们在电话调研的过程中,添加了6名活跃用户的电访。
+
+在问卷设计的过程中,面临最大的挑战就是关于驱动因素的题目。因为建立驱动因素的模型是需要很多传统的、经过诸多验证的题目来建立模型。但是SNS领域的驱动因素建模少之又少,为了保证模型的完整性和科学性,项目期间,还做了许多的桌面研究。
+
+ 
+
+整个项目主要分为这三个阶段进行的。最后得到的非流失用户及流失用户的相关模型如下图:(结论仅供大家参考,由于实验设计和目标用户的不同,最后的结果可能是会有不同)
+
+ 
+
+图3:有过分享经历的非流失用户做分享的原因模型
+
+圆圈越大,代表该指标用户打分越高(下同)。图中蓝色代表与购物相关的因素,红色代表用户心理层面的因素。
+
+ 
+
+ 图4:流失用户做分享的原因模型
+
+ 
+
+ 图5:有过分享经历的非流失用户不分享的因素模型
+
+ 
+
+ 图6:未分享过的非流失用户不分享的因素模型
+
+ 
+
+ 图7:非流失用户刺激因素的模型
+
+ 
+
+ 图8:流失用户刺激因素的模型
+
+ 
+
+以上结论是我在专业同事的帮助下完成的,也是我们对SNS领域的初步探索。期待与大家更深入的探讨与交流。
+
+

tfidf/test/run_test.py

 
 import _env
 from collections import defaultdict
-from tfidf.train.topic_bayes import TAG2ID, WORD2ID, BAYES_RANK
+from tfidf.train.topic_bayes import TAG2ID, WORD2ID#, BAYES_RANK
+from tfidf.train.convert2array import DB_Kyoto
 from tfidf.idf import idf_zhihu
 from mmseg import seg_txt
 from yajl import loads
 sys.setdefaultencoding('utf-8')
 
 ID2TAG = TAG2ID.id2word()
+TAG2ID = dict((k,v) for v,k in ID2TAG.iteritems())
 
 CURRENT_PATH = path.dirname(path.abspath(__file__))
 
 class GetTag(object):
+
     def __init__(self, folder):
         self.idf = idf_zhihu()
         file_list = glob(path.join(CURRENT_PATH, folder)+'/*')
         self.file_list = file_list
+        self.db = DB_Kyoto('test.kch')
 
     def run_test(self):
         for i in self.file_list:
         topic_rank = defaultdict(float)
         tfidf_list = sorted(self.idf.tf_idf(txt), key=lambda x:x[1], reverse=True)
 
-        highest_word_list = []
-        for word, tfidf in tfidf_list[:10]:
-            if word in ID2TAG.values():
-                highest_word_list.append(TAG2ID.id_by_tag(word))
 
-        for word_tfidf, word_id in zip(
-            [i[1] for i in tfidf_list],
+        for (word, word_tfidf), word_id in zip(
+            tfidf_list,
             WORD2ID.id_list_by_word_list(i[0] for i in tfidf_list)
         ):
-            if word_id in BAYES_RANK:
-                for topic_id, bayes in BAYES_RANK[word_id]:
+            topic_items_dict  = self.db.get(word_id)
+            if topic_items_dict:
+                for topic_id, bayes in topic_items_dict:
                     topic_rank[topic_id] += (word_tfidf*bayes)
 
         topic_rank = sorted(topic_rank.iteritems(), key=lambda x:x[1], reverse=True)
+        txt = txt.lower()
+        if topic_rank:
+            rank_avg = float(sum(i[1] for i in topic_rank))/len(topic_rank)
+            for topic_id, rank in topic_rank[:50]:
+                '''
+                推荐主题做二元分词, 如果文章中没有, 则去掉. 
+                '''
+                rank_t = rank/rank_avg
+                if rank_t<6:
+                    break
 
-        for topic_id, rank in topic_rank[:10]:
-            '''
-            推荐主题做二元分词, 如果文章中没有, 则去掉. 
-            '''
-            for seg in sp_txt(ID2TAG[topic_id]):
-                if seg in txt:
-                    print ID2TAG[topic_id], rank
-                    break
-                
+                topic = ID2TAG[topic_id]
+                if topic.replace(" ","").isalnum():
+                    if topic.lower() in txt:
+                        print topic, rank_t
+                else: 
+                    for seg in sp_txt(topic):
+                        if seg in txt:
+                            print topic, rank_t
+                            break
 
-        for k in highest_word_list:
-            print ID2TAG[k]
+
+        print ""
+        if tfidf_list:
+            idf_avg = float(sum(i[1] for i in tfidf_list))/len(tfidf_list)
+            for word, tfidf in tfidf_list:
+                if word in TAG2ID:
+                    rank = tfidf/ idf_avg
+                    if rank<6:
+                        break
+                    #print word, rank
+
+#            print ID2TAG[k]
 
 def sp_txt(txt):
     txt = unicode(txt)
 
 
 if __name__ == '__main__':
+    #import cProfile
+    #cProfile.run('main()')
     main()
+

tfidf/train/convert2array.py

+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from itertools import tee, izip
+from array import array
+import sys
+import os.path as path
+from kyotocabinet import *
+
+MAX_INT = (1<<32)-1
+CURRENT_PATH = path.dirname(path.abspath(__file__))
+
+class DB_Kyoto(object):
+    """docstring for DB_Kyoto"""
+    def __init__(self, db_file):
+        from topic_bayes import TAG2ID, WORD2ID#, BAYES_RANK
+        self.ider = WORD2ID
+        super(DB_Kyoto, self).__init__()
+        self.db = DB()
+        self.db_file = db_file
+        if not self.db.open(path.join(CURRENT_PATH,self.db_file), DB.OWRITER | DB.OCREATE):
+            print >>sys.stderr, "open error: " + str(self.db.error())
+
+
+    def set(self,entry):
+        key = entry[0]
+        result_array = convert2array(entry[1]).tostring()
+        if not self.db.set(key,result_array):
+            print key
+            print result_array
+            print >>sys.stderr, "open error: " + str(self.db.error())
+
+    def get(self,key):
+        value = self.db.get(key)
+        if value:
+            result = array('L')
+            result.fromstring(value)
+            return convert2dict(result)
+        else:
+            #print >>sys.stderr, self.ider.get_word_by_id(key)
+            #print key
+            print >>sys.stderr, "%s error: "%key + str(self.db.error())
+
+
+def pairwise(iterable):
+    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
+    a, b = tee(iterable)
+    next(b, None)
+    return izip(a, b)
+
+#for k,v in pairwise(range(10)):
+#    print k,v
+
+
+def convert2array(dict_value):
+    ''' 
+    >>> convert2array({1:0.1,2:0.3})
+    array('L', [1L, 429496729L, 2L, 1288490188L])
+    '''
+    result_list =  []  
+    for k,v in dict_value:
+        result_list.extend([k,int(v*MAX_INT)])
+    result = array('L',result_list)
+    return result
+
+def convert2dict(array_l):
+    ''' 
+    >>> convert2dict([1L, 429496729L, 2L, 1288490188L])
+    {1:0.1,2:0.3}
+    '''
+    return [ (array_l[i],array_l[i+1]) for i in range(len(array_l)) if i%2==0]
+
+if __name__=='__main__':
+    import doctest
+    doctest.testmod()
+

tfidf/train/topic_bayes.py

 from zkit.tofromfile import tofile, fromfile
 from tfidf.find_parent_tag import ParentTagger
 from tfidf.config import DATA_DIR
+from convert2array import DB_Kyoto
 
 current_path = os.path.dirname(os.path.abspath(__file__))
+banned_tag_list=['开放课程']
 
 class WordId(object):
     def __init__(self):
         return None
 
     def id_by_tag(self, tag):
+        if u'(' in tag:
+            tag = tag[:tag.find(u'(')]
+        if u'(' in tag:
+            tag = tag[:tag.find(u'(')]
+        tag = tag.lower()
         tag = str(tag)
         _dict = self._dict
         if tag in _dict:
             return self._id2word_dict[id]
         return None
 
+    def get_max_id(self):
+        self._reverse_dict()
+        return max(self._id2word_dict.keys())
+
+
 #def word2id(self):
 #    return self._dict
 
 class TagWord(object):
     def __init__(self, path):
+        print "Loding"
         self.tag2id = WordId()
         self.word2id = WordId()
         self.path = path
         self.parent_tag_finder = ParentTagger()
+        print "Loading done"
 
     def _txt_tag_generator(self):
         path = self.path
         zhihu_data.extend(data_files)
 
 
+        print 'Processing...'
         g = open(join(path, 'topic_dict'))
         topic_dict = loads(g.read())
 
+        #count = 0
         for data_src in zhihu_data:
             print 'Processing...', data_src
             with open(data_src) as f:
                 for line in f:
+                    #if count>1000:
+                    #    break
+                    #count+=1
                     data = loads(line)
-                    tags = data['tags']
+                    if 'tags' in data:
+                        tags = data['tags']
+                    else:
+                        continue
 
 
                     tags_processed = []
                     if 'zhihu' not in data_src:
                         for tag in tags:
-                            if tag in topic_dict:
+                            if tag in topic_dict and tag not in banned_tag_list:
                                 tags_processed.append(tag)
 
                         if not tags_processed:
         word_topic_count = self.word_topic_count = defaultdict(lambda:defaultdict(int))
         self.tag2id = WordId().fromfile(join(DATA_DIR, 'tag2id'))
         self.word2id = WordId().fromfile(join(DATA_DIR, 'word2id'))
+        self.db = DB_Kyoto('test.kch')
 
         for word_id_list, tag_id_list in word_id2tag_id:
             for tag_id in tag_id_list:
         topic_id_title_count = self.topic_id_title_count
         word_topic_count = self.word_topic_count
 
-        word_topic_bayes = {}
+
+        #word_topic_bayes = {}
         for word, topic_count in word_topic_count.iteritems():
             word_topic_freq = {}
             for topic_id, count in topic_count.iteritems():
                     word_topic_freq[topic_id] = 1
 
             count = sum(word_topic_freq.itervalues())
-            wb = word_topic_bayes[word] = []
-            for k, v in word_topic_freq.iteritems():
-                wb.append((k, v/count))
+            self.db.set((word,[(k,v/count) for k,v in word_topic_freq.iteritems()]))
+            #wb = word_topic_bayes[word] = []
+            #for k, v in word_topic_freq.iteritems():
+            #    wb.append((k, v/count))
 
-        return word_topic_bayes
+        #return word_topic_bayes
 
 def main():
     tagword = TagWord(join(current_path, 'train_data/'))
     tagword.tofile()
     WORD_ID2TAG_ID = fromfile(join(DATA_DIR, 'word_id2tag_id'))
     bayes_rank = BayesRank(WORD_ID2TAG_ID)
-    tofile(join(DATA_DIR, 'bayes_rank') , bayes_rank.rank())
+    bayes_rank.rank()
+    #tofile(join(DATA_DIR, 'bayes_rank') , bayes_rank.rank())
 
 if __name__ == '__main__':
     #TAG2ID = WordId().fromfile(join(DATA_DIR, 'tag2id'))

wanfang/convert_wanfang.py

+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+
+import _env
+from yajl import loads,dumps
+from zkit.htm2txt import htm2txt
+from glob import glob
+
+def main():
+    out = []
+    file_list = glob('article/*')
+    for fi in file_list:
+        with open(fi) as f:
+            for line in f:
+                data = loads(line)
+                entry = {}
+                if data[1]:
+                    entry['txt'] = str(''.join(data[:2]))
+                    entry['tags'] = [str(i) for i in data[2]]
+                print dumps(entry)
+
+if __name__ == '__main__':
+    main()

wanfang/wanfang_arti.py

 # -*- coding: utf-8 -*-
 
 import _env
-from tfidf.tofromfile import tofile
+from zkit.tofromfile import tofile
 from gcrawler import GCrawler, Downloader
 from zkit.bot_txt import txt_wrap_by_all, txt_wrap_by
 import os.path as path
 from os import mkdir
 from yajl import dumps
-import fileinput
 import re
 from zkit.lock_file import LockFile
 
                 yield url
 
 spider = MassDown(get_file_list())
-crawler = GCrawler(spider, workers_count=100)
+crawler = GCrawler(spider, workers_count=10)
 crawler.start()