Sau đây là cách cơ bản nhất mà tôi biết để đếm chuyển tiếp trong một chuỗi Markov và sử dụng nó để cư một ma trận chuyển tiếp:Làm cách nào để tăng tốc độ tạo ma trận chuyển tiếp trong Numpy?
def increment_counts_in_matrix_from_chain(markov_chain, transition_counts_matrix):
for i in xrange(1, len(markov_chain)):
old_state = markov_chain[i - 1]
new_state = markov_chain[i]
transition_counts_matrix[old_state, new_state] += 1
Tôi đã cố gắng tăng tốc nó lên trong 3 cách khác nhau:
1) Sử dụng một ma trận thưa thớt một lót dựa trên mã này Matlab:
transition_matrix = full(sparse(markov_chain(1:end-1), markov_chain(2:end), 1))
nào trong numPy/scipy, trông như thế này:
def get_sparse_counts_matrix(markov_chain, number_of_states):
return coo_matrix(([1]*(len(markov_chain) - 1), (markov_chain[0:-1], markov_chain[1:])), shape=(number_of_states, number_of_states))
Và tôi đã cố gắng nhiều hơn một vài tinh chỉnh Python, như sử dụng zip():
for old_state, new_state in zip(markov_chain[0:-1], markov_chain[1:]):
transition_counts_matrix[old_state, new_state] += 1
Và Queues:
old_and_new_states_holder = Queue(maxsize=2)
old_and_new_states_holder.put(markov_chain[0])
for new_state in markov_chain[1:]:
old_and_new_states_holder.put(new_state)
old_state = old_and_new_states_holder.get()
transition_counts_matrix[old_state, new_state] += 1
Nhưng không ai trong số những 3 phương pháp tăng tốc mọi thứ lên. Trong thực tế, tất cả mọi thứ nhưng giải pháp zip() là ít nhất 10X chậm hơn so với giải pháp ban đầu của tôi.
Có giải pháp nào khác đáng xem xét không?
giải pháp thay đổi để xây dựng một ma trận chuyển đổi từ nhiều chuỗi
Câu trả lời tốt nhất cho câu hỏi trên đặc biệt là của DSM. Tuy nhiên, đối với bất kỳ ai muốn điền ma trận chuyển đổi dựa trên danh sách hàng triệu chuỗi markov, cách nhanh nhất là:
def fast_increment_transition_counts_from_chain(markov_chain, transition_counts_matrix):
flat_coords = numpy.ravel_multi_index((markov_chain[:-1], markov_chain[1:]), transition_counts_matrix.shape)
transition_counts_matrix.flat += numpy.bincount(flat_coords, minlength=transition_counts_matrix.size)
def get_fake_transitions(markov_chains):
fake_transitions = []
for i in xrange(1,len(markov_chains)):
old_chain = markov_chains[i - 1]
new_chain = markov_chains[i]
end_of_old = old_chain[-1]
beginning_of_new = new_chain[0]
fake_transitions.append((end_of_old, beginning_of_new))
return fake_transitions
def decrement_fake_transitions(fake_transitions, counts_matrix):
for old_state, new_state in fake_transitions:
counts_matrix[old_state, new_state] -= 1
def fast_get_transition_counts_matrix(markov_chains, number_of_states):
"""50% faster than original, but must store 2 additional slice copies of all markov chains in memory at once.
You might need to break up the chains into manageable chunks that don't exceed your memory.
"""
transition_counts_matrix = numpy.zeros([number_of_states, number_of_states])
fake_transitions = get_fake_transitions(markov_chains)
markov_chains = list(itertools.chain(*markov_chains))
fast_increment_transition_counts_from_chain(markov_chains, transition_counts_matrix)
decrement_fake_transitions(fake_transitions, transition_counts_matrix)
return transition_counts_matrix
Tôi sẽ chấp nhận câu trả lời này, nhưng tôi muốn theo dõi thêm câu hỏi. Khi tôi sử dụng bincount nhiều lần để điền ma trận đếm ma trận chuyển đổi dựa trên hàng nghìn chuỗi markov, mã ban đầu của tôi vẫn nhanh hơn. Tôi cho rằng điều này là do count_matrix.flat + = numpy.bincount (flat_coords, minlength = count_matrix.size) chậm hơn khi cập nhật count_matrix so với mã ban đầu của tôi. Suy nghĩ về điều đó? –
Cập nhật về điều này: giải pháp nhanh nhất mà tôi tìm thấy để điền ma trận chuyển đổi dựa trên tấn chuỗi markov là hợp nhất các chuỗi với nhau, sử dụng số lượng tài khoản, sau đó chuyển đổi giả (từ cuối chuỗi này sang đầu tiếp theo), sau đó giảm số lượng cho mỗi lần chuyển đổi giả. Giải pháp đó nhanh hơn khoảng 25% so với bản gốc của tôi. –
@ some-guy: cảm thấy tự do tận dụng giải pháp tốt nhất mà bạn tìm được cho trường hợp sử dụng của mình, đăng câu trả lời đó và chấp nhận nó. – DSM