2014-11-11 3 views
0

나는 작업을위한 추천 엔진을 만들고 8,000 x 8,000 아이템 아이템 유사성 매트릭스로 끝나게되었다. 매트릭스가 꽤 희소하기 때문에 각 키가 제품 권장 사항의 정렬 된 배열 (튜플의 형태로) 인 목록을 가리키는 많은 키가있는 사전을 만들기로했습니다. 나는 이것이 작동하도록했습니다, 아래를보십시오. 했던 이유는 (각각 하나 32 또는 64 비트로 표현되는 한) 제로의 톤을 제거하더라도누구든지이 사전과 매트릭스 크기 차이를 설명 할 수 있습니까?

In [204]: sys.getsizeof(dictionary) 
Out[204]: 786712 

In [205]: sys.getsizeof(similarity_matrix) 
Out[205]: 69168 

:

In [191]: dictionary["15454-M6-ECU2="] 
Out[191]: 
[('15454-M-TSCE-K9=', 0.8), 
('15454-M2-AC=', 0.52), 
('15454-M6-DC-RF', 0.45), 
('15454-M6-ECU2=', 0.63)] 

단, I는 현재 결과의 해석에 문제가 있다면 행렬에서 희소성을 제거하더라도 객체 크기가 증가합니까?

+0

사전 키는 많은 공간을 차지할 수 있습니다. 숫자 키가 문제가되는 경우 – Joni

+0

'getsizeof'는 지정된 객체의 크기 만 반환하며 참조하는 객체는 반환하지 않습니다. 즉. 'getsizeof ([1,2])> getsizeof ([[1,2,3,4,5]])'는 첫 번째리스트가 두 개의 원소를 포함하고있는 반면 두 번째 (루트)리스트는 하나의 원소만을 포함하고 있기 때문에 참이다. – Dunes

답변

1

sys.getsizeof은 컨테이너의 크기와 내부 항목의 크기를 반환하지 않습니다. dict은 포함 된 값의 크기와 키/값 쌍당 여전히 98 바이트 만 같은 크기를 반환합니다. 키에 대한 참조 및 값에 대한 참조와 해시/버킷에 대한 다른 오버 헤드를 저장합니다.

>>> sys.getsizeof(dict((i,'a'*10000) for i in range(8000))) 
786712 
>>> sys.getsizeof(dict((i,'a'*1) for i in range(8000))) 
786712 
>>> 786712/8000 
98 

튜플은 훨씬 더 작아서 참조 자체 만 저장합니다.

>>> sys.getsizeof(tuple((i,'a'*10000) for i in range(8000))) 
64056 
>>> sys.getsizeof(tuple((i,'a'*1) for i in range(8000))) 
64056 
>>> 64056/8000 
8 
0

는 사전의 크기에 따라 당신이 (해당 키와 유사하다 다른 키가 없을 수도도) 가능한 각 키에 대한 하나의 키/값 쌍을 가질 것으로 보인다. 당신도 드문 드문 사전

# initialise empty mapping -- literally an empty dict 
very_sparse_dict = {} 
very_sparse_dict[0] = [(2, 0.5)] # 0 is similar to 2 by 50% 

def get_similarity2(d, x, y): 
    for key, value in d.get(x,()): 
     if key == y: 
      return value 
    return 0 

# 0 not linked to 1, so 0% similarity 
assert get_similarity2(very_sparse_dict, 0, 1) == 0 
# 0 and 2 are similar 
assert get_similarity2(very_sparse_dict, 0, 2) == 0.5 
# 1 not similar to anything as it is not even present in the dict 
assert get_similarity2(very_sparse_dict, 1, 2) == 0 

을 구현할 수 있습니다 그리고 각 딕셔너리의 크기 인 dictget 방법을 사용하여, 그러나

# initialise sparse dict with one empty list of similar nodes for each node 
sparse_dict = dict((key, []) for key in range(1000)) 
sparse_dict[0].append((2, 0.5)) # 0 is similar to 2 by 50% 

def get_similarity(d, x, y): 
    for key, value in d[x]: 
     if key == y: 
      return value 
    return 0 

assert get_similarity(sparse_dict, 0, 1) == 0 
assert get_similarity(sparse_dict, 0, 2) == 0.5 

:

난 당신의 코드는 다음과 같이 보입니다 상상 :

>>>> print("sparse_dict:", sys.getsizeof(sparse_dict)) 
sparse_dict: 49248 
>>> print("very_sparse_dict", sys.getsizeof(very_sparse_dict)) 
very_sparse_dict: 288 
+0

당신이 보여준 것 모두는 유사성 사전을 실제로 채우지 않으면 훨씬 작다고 생각합니다. 모든 제품에 적어도 하나의 유사성이 있다고 가정하면 전체 크기의 사전으로 돌아갑니다. – tdelaney

관련 문제