在GAE上使用Jieba分词遇到的问题和处理

last modified : 2017-03-25 | published: 2017-03-19 | category:

TemporaryFile 的问题处理

GAE对屏蔽了tempfile库的使用,Jieba分词使用tempfile库处理缓存问题,使用时会报错:

NotImplementedError: Only tempfile.TemporaryFile is available for use

解决办法:

  1. 修改GAE使用的tempfile.py。 替换

     gettempdir = PlaceHolder
    

     def gettempdir(*args, **kwargs):
         return os.path.dirname(os.path.abspath(__file__)) + '/../tmp'
    
  2. 命名为gae_tempfile.py,并放置于lib目录并使用官方的方法加载
  3. 修改jieba/analyse/tfidf.pylib/jieba/__init__.py,替换import tempfileimport tempfile_gae as tempfile
  4. 在本地新建tmp目录。
  5. 在本地环境生成dict.cache后,再上传至GAE。

至此,基本的分词功能正常了

使用 TF-IDF 关键词抽取时因内存不足无法完成请求

在本地测试环境无法发现此问题,上传后无法使用,因为GAE的免费配额下,单个实例仅有128M内存。

经过分析,发现提取关键词的过程中,读取jieba/analyse/idf.txt并生成索引对象的过程使用了大量内存。相关对象为jieba.analyse.tfidf.IDFLoader

解决办法:使用处理词库dict.txt的方法处理文本语料库,本地利用marshal库生成二进制对象后,上传到GAE。

  1. 修改jieba.analyse.tfidf.IDFLoaderset_new_path(self, new_idf_path)函数
     def set_new_path(self, new_idf_path):
         if self.path != new_idf_path:
             self.path = new_idf_path
             cache_file = "idf.cache"
             cache_file = os.path.join(tempfile.gettempdir(), cache_file)
             try:
                 with open(cache_file, 'rb') as cf:
                     self.idf_freq, self.median_idf = marshal.load(cf)
                 # print("Loading model from cache %s" % cache_file)
             except Exception:
                 content = open(new_idf_path, 'rb').read().decode('utf-8')
                 self.idf_freq = {}
                 for line in content.splitlines():
                     word, freq = line.strip().split(' ')
                     self.idf_freq[word] = float(freq)
                 self.median_idf = sorted(
                     self.idf_freq.values())[len(self.idf_freq) // 2]
                 with open(cache_file, 'wb') as cf:
                     marshal.dump((self.idf_freq, self.median_idf), cf)
    
  2. 在本地环境生成dict.cache后,再上传至GAE。

至此已完全可用

参考Demo: https://jieba.liantian.me

源文件:https://github.com/liantian-cn/jieba-gae

实例响应时间,免费配额的cpu,可以处理相当数量的请求。

snipaste_20170319_172602.png

实例内存占用,刚好落在免费配额限制内。

snipaste_20170319_172713.png