2016-08-09 4 views
0

임 확신 메신저 :파이썬 - 수익률 부적절하게 사용 부적절 수율을 사용하여

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

import logging 
from gensim import corpora, models, similarities 
from collections import defaultdict 
from pprint import pprint # pretty-printer 
from six import iteritems 
import openpyxl 
import string 
from operator import itemgetter 

logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO) 

#Creating a stoplist from file 
with open('stop-word-list.txt') as f: 
    stoplist = [x.strip('\n') for x in f.readlines()] 

corpusFileName = 'content_sample_en.xlsx' 
corpusSheetName = 'content_sample_en' 

class MyCorpus(object): 
    def __iter__(self): 
     wb = openpyxl.load_workbook(corpusFileName) 
     sheet = wb.get_sheet_by_name(corpusSheetName) 
     for i in range(1, (sheet.max_row+1)/2): 
      title = str(sheet.cell(row = i, column = 4).value.encode('utf-8')) 
      summary = str(sheet.cell(row = i, column = 5).value.encode('utf-8')) 
      content = str(sheet.cell(row = i, column = 10).value.encode('utf-8')) 
      yield reBuildDoc("{} {} {}".format(title, summary, content)) 


def removeUnwantedPunctuations(doc): 
    "change all (/, \, <, >) into ' ' " 
    newDoc = "" 
    for l in doc: 
     if l == "<" or l == ">" or l == "/" or l == "\\": 
      newDoc += " " 
     else: 
      newDoc += l 
    return newDoc 

def reBuildDoc(doc): 
    """ 
    :param doc: 
    :return: document after being dissected to our needs. 
    """ 
    doc = removeUnwantedPunctuations(doc).lower().translate(None, string.punctuation) 
    newDoc = [word for word in doc.split() if word not in stoplist] 
    return newDoc 

corpus = MyCorpus() 

tfidf = models.TfidfModel(corpus, normalize=True) 

다음 예제에서 당신은 내게는 XLSX 파일에서 신체를 만들려고 볼 수 있습니다. Im은 xlsx 파일에서 제목 요약과 내용 인 3 줄을 읽고 큰 줄에 추가합니다. 내 reBuildDoc()removeUnwantedPunctuations() 함수는 텍스트를 내 필요에 맞게 조정하고 결국에는 큰 단어 목록을 반환합니다. (예를 들어 [hello, piano, computer, etc... ]) 결국 나는 결과를 얻을 수 있지만 다음과 같은 오류 얻을 : 내가 일을 다른 수율 라인을했기 때문에 오류가 수율 라인에서 알고

Traceback (most recent call last): 
    File "C:/Users/Eran/PycharmProjects/tfidf/docproc.py", line 101, in <module> 
    tfidf = models.TfidfModel(corpus, normalize=True) 
    File "C:\Anaconda2\lib\site-packages\gensim-0.13.1-py2.7-win-amd64.egg\gensim\models\tfidfmodel.py", line 96, in __init__ 
    self.initialize(corpus) 
    File "C:\Anaconda2\lib\site-packages\gensim-0.13.1-py2.7-win-amd64.egg\gensim\models\tfidfmodel.py", line 119, in initialize 
    for termid, _ in bow: 
ValueError: too many values to unpack 

합니다. 그것은이처럼 보였다 :

yield [word for word in dictionary.doc2bow("{} {} {}".format(title, summary, content).lower().translate(None, string.punctuation).split()) if word not in stoplist] 

가 IT에 functionallity을 넣어 ABIT 지저분하고 힘들었다 첫 번째 예에서 볼 수 있듯이 그래서 그것을 변경했습니다.

+0

사이드 노트 :'removeUnwantedPunctuations'는 엄청나게 비효율적으로 구현됩니다. 특히 어쨌든 결과에 대해'translate' 호출을 수행하고 있기 때문입니다. 코드'unwanted_to_space, deletepunc = string.maketrans (r '\/<>', ''), string.punctuation.translate (None, r '\/<>')'의 최상위 레벨에서 다음을 실행하십시오. 'doc = doc.translate (unwanted_to_space, deletepunc) .lower()'에'doc = removeUnwantedPunctuations (doc) .lower(). translate (None, string.punctuation)'를 변경하십시오. 간단한 테스트에서 실행 시간을 ~ 10-15 배 단축합니다 (더 짧게/짧게 구두점을 사용하는 경우). – ShadowRanger

+0

그리고'unwanted_to_space'를'string.maketrans (r '\/<>'+ string.ascii_uppercase, '+ string.ascii_lowercase)'로 만들면 더 많은 것을 절약 할 수 있습니다 (보이지 않으면 네 개의 공백이 있어야합니다). 두 번째 인수를 이끄는 문자열),'lower'에 대한 호출을 생략 할 수 있습니다 (입력이 ASCII가 아닌 경우 true 'lower'를 원하지만 ASCII의 경우'str'). 'translate' 호출은 동등하고 무료입니다), 런타임에 20 배 이상 절약됩니다. 분명히 입력 값이 작 으면 절약은 중요하지 않지만 큰 데이터의 경우 입력을 파싱하는 것은 큰 비용이 될 수 있습니다. – ShadowRanger

답변

1

는 문제가되지 않습니다 yield 자체, 굴복 어떤 오류가이 라인은 당신이 bow은 튜플의 목록 또는 정확히 2 요소 (1,2),[1,2],"12",...처럼하지만로를 포함하는 다른 객체를 포함 할 것으로 예상했다 for termid, _ in bow 인 것을 특징으로한다 분명 2 개 이상의 요소, 따라서 오류가있는 문자열입니다 MyCorpus의 결과가 그것을 포기 끝이 그래서 당신이이 검사를 설명하기 위해이 객체의 튜플

를 얻을 중 하나 for termid in bow 또는 MyCorpus에서이 yield reBuildDoc("{} {} {}".format(title, summary, content)), None을 할 고치는 이 예

>>> def fun(obj): 
     for _ in range(2): 
      yield obj 


>>> for a,b in fun("xyz"): 
     print(a,b) 


Traceback (most recent call last): 
    File "<pyshell#11>", line 1, in <module> 
    for a,b in fun("xyz"): 
ValueError: too many values to unpack (expected 2) 
>>> for a,b in fun("xy"): 
     print(a,b) 


x y 
x y 
>>> for a,b in fun(("xy",None)): 
     print(a,b) 


xy None 
xy None 
>>> 
문제가 TfidfModellist doc2bow의 출력 (2 ~ tuple의의 자체 list들)입니다 corpus을 기대하는처럼 16,
+0

맞습니다. 문제는 다른 기능과 관련이 있습니다. 문서를 작성하기 전에 dictionary.doc2bow를 문서에 적용해야했습니다. 그리고 작성한 것처럼 튜플을 허용합니다. 감사! –

+1

이 답변은 최종 증상의 즉각적인 원인을 설명하고 있지만 실제 해결책은 "가짜 두 번째 요소 추가"가 아니라 실제 원인이 훨씬 높은 수준입니다. 'TfidfModel'은 특정 형식의 입력을 필요로하며, 위조 된 두 번째 요소를 추가해도 코드가 작동하지 않습니다. – ShadowRanger

1

는 것 같습니다. 원래의 작업 코드는 doc2bow을 사용하여 일반 문자열을 코퍼스 형식으로 변환했지만 새 코드는 원시 문자열로 전달됩니다. TfidfModel은 "벡터"가 아닙니다.

doc2bowread the tutorial on converting string to vectors을 사용하면 원시 문자열이 입력 값으로 무의미하다는 것을 알 수 있습니다.