2013-05-23 1 views
1

깨끗한 원 - 라이너에서 히스토그램을 만드는 데 많은 질문을했지만 가능한 한 효율적으로 만들려는 사람을 아직 찾지 못했습니다. 저는 현재 검색 알고리즘을위한 많은 tfidf 벡터를 만들고 있습니다. 그리고 이것은 매우 짧고 읽기 쉽지만 원하는만큼 빠르지는 않지만 많은 히스토그램과 현재 코드를 만드는 것을 포함합니다. 슬프게도, 저는 훨씬 느린 것으로 판명 된 다른 많은 방법을 시도했습니다. 빨리 할 수 ​​있니? cleanStringVector는 문자열 목록 (모두 소문자, 구두점 없음)이며 masterWordList는 cleanStringVector 내의 모든 단어를 포함해야하는 단어 목록입니다. 카운터 개체 대신 KeyError를 제기의 존재하지 않는 키에 0을 반환하는 사실은 심각한 플러스와 다른 질문에 히스토그램 방법의 대부분이 테스트에 실패 협조 할파이썬에서 가장 효율적인 히스토그램 코드

from collections import Counter 
def tfidfVector(cleanStringVector, masterWordList): 
    frequencyHistogram = Counter(cleanStringVector) 
    featureVector = [frequencyHistogram[word] for word in masterWordList] 
    return featureVector 

.

예 :

["apple", "orange", "tomato", "apple", "apple"] 
["tomato", "tomato", "orange"] 
["apple", "apple", "apple", "cucumber"] 
["tomato", "orange", "apple", "apple", "tomato", "orange"] 
["orange", "cucumber", "orange", "cucumber", "tomato"] 

과의 마스터 단어 목록 : 나는 다음과 같은 데이터가있는 경우

:

["apple", "orange", "tomato", "cucumber"] 

을 나는 각각 각 테스트 케이스에서 다음의 반환을 부탁합니다

[3, 1, 1, 0] 
[0, 1, 2, 0] 
[3, 0, 0, 1] 
[2, 2, 2, 0] 
[0, 2, 1, 2] 

도움이 되었기를 바랍니다.

대략적인 최종 결과 : 이것은 파이썬 3 크기 (1 개) 명령에 의해 내 대표성 마이크로 벤치 마크에서 런타임을 향상

Original Method: 3.213 
OrderedDict: 5.529 
UnorderedDict: 0.190 
+0

을만큼 안정해야합니까 'cleanStringVector'는 어떻게 보이나요? – chenaren

+0

오, 단지 문자열 목록 일뿐입니다. 지금 당장은 직선적 인 파이썬리스트이지만, 원하면 숫자가 적은 배열이라고 가정합니다. –

+0

[여기] (http://stackoverflow.com/questions/2870466/python-histogram-one-liner) 방법을 벤치마킹 해 보셨습니까? –

답변

2

: 나는 인 마스터 단어 목록을 통해 반복 생각

mapping = dict((w, i) for i, w in enumerate(masterWordList)) 

def tfidfVector(cleanStringVector, masterWordList):  
    featureVector = [0] * len(masterWordList) 
    for w in cleanStringVector: 
     featureVector[mapping[w]] += 1 
    return featureVector 
+0

같은 생각 나는 나의 대답에서 성취하려고 노력하고 있었다.. 그러나 훨씬 더 우아하고 (아마 더 빠르다), 멋지다. – qwwqwwq

+0

아, 환상적. 그것을 호출하는 코드에서 지역을 캐싱하기위한 몇 가지 작은 개조 작업을 수행하고이를 20 배 빠른 속도로 개선했습니다. –

0

문제. 히스토그램을 만들 때마다 마스터 단어 목록의 모든 단어를 해시해야합니다 (대부분의 해시가 누락되어 계산 비용이 많이 드는 방식으로 0을 반환합니다).

먼저 마스터 단어 목록을 해시 한 다음 해시를 사용하여 각 막대 그래프를 만듭니다.이 방법은 stringvector의 모든 단어를 해시 할 필요가 있습니다 (두 번, 한 번 계산하려면 한 번, 한 번 마스터 단어 목록 해시를 다시 설정하십시오).).

from itertools import repeat 

stringvecs=[["apple", "orange", "tomato", "apple", "apple"], 
["tomato", "tomato", "orange"], 
["apple", "apple", "apple", "cucumber"], 
["tomato", "orange", "apple", "apple", "tomato", "orange"], 
["orange", "cucumber", "orange", "cucumber", "tomato"]] 

m=["apple", "orange", "tomato", "cucumber"] 

md = dict(zip(m, repeat(0))) 

def tfidfVector(stringvec, md): 
    for item in stringvec: 
     md[item]+=1 
    out=md.values() 
    for item in stringvec: 
     md[item]=0 
    return out 

for stringvec in stringvecs: 
    print tfidfVector(stringvec, md) 

참고 : 다음 stringvectors 마스터 단어 목록보다 작은 경우,이 결과 많은 적은 해시 작업입니다 md.values ​​() 우리는 키를 추가하지 않는 한 ..

+0

나는 그 생각이 마음에 들지만 현재 구현보다 훨씬 느리다. (약 2 배 길어짐) –

+0

그래, 그냥'OrderedDict'를 사용하여'dict'을 사용하는 것보다 10 배 느리고 필요하지는 않습니다.'OrderedDict'없이 테스트합니다. 이것은 가까운 토마스 정의 대답이지만 여전히 조금 느립니다. – qwwqwwq

관련 문제