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)
  1. 在本地环境生成dict.cache后,再上传至GAE。

效果

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

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

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

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

snipaste_20170319_172713.png