簡體   English   中英

我需要一些幫助來優化python代碼

[英]I need some help to optimize a python code

我正在使用Python開發KNN分類器,但遇到了一些問題。 以下代碼需要7.5s-9.0s才能完成,我將不得不運行60.000次。

        for fold in folds:  
            for dot2 in fold:
                """
                distances[x][0] = Class of the dot2
                distances[x][1] = distance between dot1 and dot2
                """
                distances.append([dot2[0], calc_distance(dot1[1:], dot2[1:], method)])

“ folds”變量是一個包含10折的列表,這些列表的總和包含60.000個.csv格式的圖像輸入。 每個點的第一個值是它所屬的類。 所有值都是整數。 有沒有辦法使這條線的運行更快?

這是calc_distance函數

def calc_distancia(dot1, dot2, distance):

if distance == "manhanttan":
    total = 0
    #for each coord, take the absolute difference
    for x in range(0, len(dot1)):
        total = total + abs(dot1[x] - dot2[x])
    return total

elif distance == "euclidiana":
    total = 0
    for x in range(0, len(dot1)):
        total = total + (dot1[x] - dot2[x])**2
    return math.sqrt(total)

elif distance == "supremum":
    total = 0
    for x in range(0, len(dot1)):
        if abs(dot1[x] - dot2[x]) > total:
            total = abs(dot1[x] - dot2[x])
    return total

elif distance == "cosseno":
    dist = 0
    p1_p2_mul = 0
    p1_sum = 0
    p2_sum = 0
    for x in range(0, len(dot1)):
        p1_p2_mul = p1_p2_mul + dot1[x]*dot2[x]
        p1_sum = p1_sum + dot1[x]**2
        p2_sum = p2_sum + dot2[x]**2
    p1_sum = math.sqrt(p1_sum)
    p2_sum = math.sqrt(p2_sum)
    quociente = p1_sum*p2_sum
    dist = p1_p2_mul/quociente

    return dist

編輯:找到了一種方法,至少對於“ manhanttan”方法,它使其更快。 代替:

    if distance == "manhanttan":
    total = 0
    #for each coord, take the absolute difference
    for x in range(0, len(dot1)):
        total = total + abs(dot1[x] - dot2[x])
    return total

我放

    if distance == "manhanttan":
    totalp1 = 0
    totalp2 = 0
    #for each coord, take the absolute difference
    for x in range(0, len(dot1)):
        totalp1 += dot1[x]
        totalp2 += dot2[x]

    return abs(totalp1-totalp2)

abs()調用非常繁重

有很多關於“分析python”的指南。 您應該搜索一些內容,閱讀它們,然后逐步完成配置過程,以確保您知道工作中的哪些部分花費最多的時間。

但是,如果這真的是您工作的核心,可以肯定地說, calc_distance是消耗大部分運行時間的地方。

進行深度優化可能需要使用NumPy加速數學或類似的低級方法。

作為一種需要較少侵入性分析和重寫的快速而骯臟的方法,請嘗試安裝Python的PyPy實現並在其下運行。 與標准(CPython)實現相比,我看到了輕松的2倍或更多加速。

我糊塗了。 您是否嘗試了探查器?

 python -m cProfile myscript.py

它會向您顯示大部分時間都花在了哪里,並提供了可使用的硬數據。 例如。 進行重構以減少調用次數,重構輸入數據,用此函數代替,等等。

https://docs.python.org/3/library/profile.html

首先,您應該避免使用單個calc_distance函數,該函數在每次調用時都在字符串列表中執行線性搜索。 定義獨立的距離函數並調用正確的距離函數。 正如Lee Daniel Crocker所建議的那樣,不要使用切片,只需將循環范圍從1開始即可。

對於余弦距離,我建議一次將所有點向量歸一化。 這樣,距離計算減少為點積。

這些微優化可以使您加速。 但是,通過切換到更好的算法,應該可以獲得更好的收益:kNN分類器要求使用kD-tree ,這將使您能夠快速從考慮中刪除大部分點。

這很難實現(您必須略微適應不同的距離;余弦距離會使其變得棘手。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM