Hướng dẫn joint probability python - trăn xác suất chung

Tôi sẽ xem xét

>>> cond_probs(['CAA'], reverse=True)
{('A', 'A'): 1.0}
8 ở đây. Bạn sẽ thấy rằng có rất nhiều chức năng này cho một câu trả lời.

1. Nhận xét về mã của bạn

  1. Dòng

    >>> cond_probs(['CAA'], reverse=True)
    {('A', 'A'): 1.0}
    
    9 có vết lõm sai. Lỗi sao chép/dán?

  2. Không có tài liệu. Các chức năng này làm gì và làm thế nào để tôi gọi chúng? (Văn bản từ câu hỏi của bạn sẽ là điểm khởi đầu tốt cho DocStrings.)

  3. Không có trường hợp kiểm tra. Đây là loại mã sẽ được hưởng lợi từ một số bài kiểm tra đơn vị và/hoặc tài liệu.

  4. Bạn viết, "

    counts = {}
    # ...
    counts[X] = counts.get(X, 0) + 1
    
    0 tạo ra một từ điển
    counts = {}
    # ...
    counts[X] = counts.get(X, 0) + 1
    
    1" Nhưng khi tôi chạy nó, từ điển có bộ đếm cho các khóa, không phải chuỗi:

    >>> cond_probs(['AAC'])
    {('A', 'C'): 0.5, ('A', 'A'): 0.5}
    
  5. Tôi không hiểu hành vi khi

    counts = {}
    # ...
    counts[X] = counts.get(X, 0) + 1
    
    2. Bạn viết, "ngược lại, các xác suất chuyển tiếp được tính toán với các chuỗi ngược lại" nhưng điều này dường như không phải là trường hợp:

    >>> cond_probs(['CAA'], reverse=True)
    {('A', 'A'): 1.0}
    

    Điều gì đã xảy ra với

    counts = {}
    # ...
    counts[X] = counts.get(X, 0) + 1
    
    3? Điều này có vẻ sai đối với tôi.

    Nếu tôi viết bài này, tôi sẽ thực hiện

    >>> cond_probs(['CAA'], reverse=True)
    {('A', 'A'): 1.0}
    
    8 để chỉ chạy theo hướng chuyển tiếp; Để thực hiện hướng ngược lại, tôi sẽ vượt qua các chuỗi đảo ngược.

  6. Thích sử dụng

    counts = {}
    # ...
    counts[X] = counts.get(X, 0) + 1
    
    5 và
    counts = {}
    # ...
    counts[X] = counts.get(X, 0) + 1
    
    6 cho Booleans, không phải
    counts = {}
    # ...
    counts[X] = counts.get(X, 0) + 1
    
    7 và
    counts = {}
    # ...
    counts[X] = counts.get(X, 0) + 1
    
    8. Vì vậy, tham số thứ hai đến
    >>> cond_probs(['CAA'], reverse=True)
    {('A', 'A'): 1.0}
    
    8 phải là
    counts = Counter()
    # ...
    counts[X] += 1
    
    0.

  7. Thay vì:

    counts = {}
    # ...
    counts[X] = counts.get(X, 0) + 1
    

    Sử dụng

    counts = Counter()
    # ...
    counts[X] += 1
    
    1 và viết:

    counts = Counter()
    # ...
    counts[X] += 1
    

    (Nhưng xem bên dưới để biết cách sử dụng

    counts = Counter()
    # ...
    counts[X] += 1
    
    2.)

  8. Thay vì:

    range(len(seq))[::-1][:-1]
    

    write:

    range(len(seq) - 1, 0, -1)
    

    Sử dụng

    counts = Counter()
    # ...
    counts[X] += 1
    
    1 và viết:

  9. (Nhưng xem bên dưới để biết cách sử dụng

    counts = Counter()
    # ...
    counts[X] += 1
    
    2.)

    (Nhưng xem bên dưới để biết cách tránh điều này.)

    Thích lặp hơn các phần tử của chuỗi thay vì lặp qua các chỉ mục của chúng. Vì vậy, thay vì:

    for t in zip(seq, seq[1:]):
        counts[t] += 1
    

    for i in range(len(seq) - 1):
        counts[seq[i],seq[i + 1]] = counts.get((seq[i], seq[i + 1]), 0) + 1
    

    counts.update(zip(seq, seq[1:]))
    

    Sử dụng

    counts = Counter()
    # ...
    counts[X] += 1
    
    3:

  10. Hoặc, thậm chí đơn giản hơn, sử dụng

    counts = Counter()
    # ...
    counts[X] += 1
    
    2:

    for s in states:
        sCounts = dict((k,v) for (k,v) in counts.items() if k[0] == s)
    

    .

Trong mã này:

>>> cond_probs(['CAA'], reverse=True)
{('A', 'A'): 1.0}
0

Bạn lặp lại toàn bộ

counts = Counter()
# ...
counts[X] += 1
8 cho mọi tiểu bang, thu thập những người bạn muốn. Nó sẽ hiệu quả hơn để lặp lại chỉ trong quá trình chuyển đổi từ
counts = Counter()
# ...
counts[X] += 1
9. Xem bên dưới để biết xem điều này sẽ trông như thế nào.

>>> cond_probs(['CAA'], reverse=True)
{('A', 'A'): 1.0}
1

2. Mã sửa đổi

Điều này nhanh hơn khoảng 30% so với mã của bạn:

>>> cond_probs(['CAA'], reverse=True)
{('A', 'A'): 1.0}
2

3. Viết lại trong Numpy

Đây là cách tôi đi về loại nhiệm vụ này trong Numpy. Numpy hoạt động tốt nhất với dữ liệu số có kích thước cố định, vì vậy tôi đã mã hóa đầu vào dưới dạng số nguyên nhỏ:

>>> cond_probs(['CAA'], reverse=True)
{('A', 'A'): 1.0}
3

.

>>> cond_probs(['CAA'], reverse=True)
{('A', 'A'): 1.0}
4

Sau đó, bạn có thể mã hóa các cặp số liền kề từ 0 Ném3 dưới dạng một số từ 0 Lỗi15, đếm số lần xuất hiện của mỗi cặp bằng cách sử dụng

range(len(seq))[::-1][:-1]
1 và giải mã kết quả bằng cách sử dụng
range(len(seq))[::-1][:-1]
2:

>>> cond_probs(['CAA'], reverse=True)
{('A', 'A'): 1.0}
5

Mảng này đại diện cho bảng chuyển tiếp:

>>> cond_probs(['CAA'], reverse=True)
{('A', 'A'): 1.0}
6

Sau đó, bạn có thể tính toán xác suất chuyển tiếp bằng cách chia từng phần tử cho tổng cột của nó:

>>> cond_probs(['CAA'], reverse=True)
{('A', 'A'): 1.0}
7