A. 機器學習中,使用邏輯回歸(python)做二分類時,recall,f1_score,support的含義是
假設預測目標為0和1
數據中1的個數為a,預測1的次數為b,預測1命中的次數為c
准確率 precision = c / b
召回率 recall = c / a
f1_score = 2 * precision * recall / (precision + recall)
B. python演算法設計的步驟有三步分別是
1. 弄清楚題目的意思,列出題目的輸入、輸出、約束條件
其中又一道題目是這樣的:「有一個mxn的矩陣,每一行從左到右是升序的,每一列從上到下是升序的。請實現一個函數,在矩陣中查找元素elem,找到則返回elem的位置。」題設只說了行和列是升序的,我在草稿紙上畫了一個3x4的矩陣,裡面的元素是1~12,於是我就想當然的認為矩陣的左上角是最小的元素,右下角是最大的元素。於是整個題目的思考方向就錯了。
2. 思考怎樣讓演算法的時間復雜度盡可能的小
繼續以上面的題目為例子。可以有如下幾種演算法:
a. 遍歷整個矩陣進行查找,那麼復雜度為O(m*n);
b. 因為每一行是有序的,所以可以對每一行進行二分查找,復雜度為O(m*logn)。但是這樣只用到了行有序的性質。
c. 網上查了一下,最優的演算法是從矩陣的左下角開始,比較左下角的元素(假設為X)與elem的大小,如果elem比X大,那麼X所在的那一列元素就都被排除了,因為X是該列中最大的了,比X還大,那麼肯定比X上面的都大;如果elem比X小,那麼X所在的那一行就可以排除了,因為X是這一行里最小的了,比X還小那麼肯定比X右邊的都小。每迭代一次,矩陣的尺寸就縮小一行或一列。復雜度為O(max(m,n))。
可以先從復雜度較高的實現方法入手,然後再考慮如何利用題目的特定條件來降低復雜度。
3. 編寫偽代碼或代碼
C. python分治法求二維數組局部峰值方法
python分治法求二維數組局部峰值方法
下面小編就為大家分享一篇python分治法求二維數組局部峰值方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
題目的意思大致是在一個n*m的二維數組中,找到一個局部峰值。峰值要求大於相鄰的四個元素(數組邊界以外視為負無窮),比如最後我們找到峰值A[j][i],則有A[j][i] > A[j+1][i] && A[j][i] > A[j-1][i] && A[j][i] > A[j][i+1] && A[j][i] > A[j][i-1]。返回該峰值的坐標和值。
當然,最簡單直接的方法就是遍歷所有數組元素,判斷是否為峰值,時間復雜度為O(n^2)
再優化一點求每一行(列)的最大值,再通過二分法找最大值列的峰值(具體方法可見一維數組求峰值),這種演算法時間復雜度為O(logn)
這里討論的是一種復雜度為O(n)的演算法,演算法思路分為以下幾步:
1、找「田」字。包括外圍的四條邊和中間橫豎兩條邊(圖中綠色部分),比較其大小,找到最大值的位置。(圖中的7)
2、找到田字中最大值後,判斷它是不是局部峰值,如果是返回該坐標,如果不是,記錄找到相鄰四個點中最大值坐標。通過該坐標所在的象限縮小范圍,繼續比較下一個田字
3、當范圍縮小到3*3時必定會找到局部峰值(也可能之前就找到了)
關於為什麼我們選擇的范圍內一定存在峰值,大家可以這樣想,首先我們有一個圈,我們已知有圈內至少有一個元素大於這個圈所有的元素,那麼,是不是這個圈中一定有一個最大值?
可能說得有點繞,但是多想想應該能夠理解,也可以用數學的反證法來證明。
演算法我們理解後接下來就是代碼實現了,這里我用的語言是python(初學python,可能有些用法上不夠簡潔請見諒),先上代碼:
import numpy as np
def max_sit(*n): #返回最大元素的位置
temp = 0
sit = 0
for i in range(len(n)):
if(n[i]>temp):
temp = n[i]
sit = i
return sit
def dp(s1,s2,e1,e2):
m1 = int((e1-s1)/2)+s1 #row
m2 = int((e2-s1)/2)+s2 #col
nub = e1-s1
temp = 0
sit_row = 0
sit_col = 0
for i in range(nub):
t = max_sit(list[s1][s2+i], #第一排
list[m1][s2+i], #中間排
list[e1][s2+i], #最後排
list[s1+i][s2], #第一列
list[s1+i][m2], #中間列
list[s1+i][e2], #最後列
temp)
if(t==6):
pass
elif(t==0):
temp = list[s1][s2+i]
sit_row = s1
sit_col = s2+i
elif(t==1):
temp = list[m1][s2+i]
sit_row = m1
sit_col = s2+i
elif(t==2):
temp = list[e1][s2+i]
sit_row = e1
sit_col = s2+i
elif(t==3):
temp = list[s1+i][s2]
sit_row = s1+i
sit_row = s2
elif(t==4):
temp = list[s1+i][m2]
sit_row = s1+i
sit_col = m2
elif(t==5):
temp = list[s1+i][e2]
sit_row = s1+i
sit_col = m2
t = max_sit(list[sit_row][sit_col], #中
list[sit_row-1][sit_col], #上
list[sit_row+1][sit_col], #下
list[sit_row][sit_col-1], #左
list[sit_row][sit_col+1]) #右
if(t==0):
return [sit_row-1,sit_col-1]
elif(t==1):
sit_row-=1
elif(t==2):
sit_row+=1
elif(t==3):
sit_col-=1
elif(t==4):
sit_col+=1
if(sit_row<m1):
e1 = m1
else:
s1 = m1
if(sit_col<m2):
e2 = m2
else:
s2 = m2
return dp(s1,s2,e1,e2)
f = open("demo.txt","r")
list = f.read()
list = list.split("n") #對行進行切片
list = ["0 "*len(list)]+list+["0 "*len(list)] #加上下的圍牆
for i in range(len(list)): #對列進行切片
list[i] = list[i].split()
list[i] = ["0"]+list[i]+["0"] #加左右的圍牆
list = np.array(list).astype(np.int32)
row_n = len(list)
col_n = len(list[0])
ans_sit = dp(0,0,row_n-1,col_n-1)
print("找到峰值點位於:",ans_sit)
print("該峰值點大小為:",list[ans_sit[0]+1,ans_sit[1]+1])
f.close()
首先我的輸入寫在txt文本文件里,通過字元串轉換變為二維數組,具體轉換過程可以看我上一篇博客——python中字元串轉換為二維數組。(需要注意的是如果在windows環境中split後的列表沒有空尾巴,所以不用加list.pop()這句話)。有的變動是我在二維數組四周加了「0」的圍牆。加圍牆可以再我們判斷峰值的時候不用考慮邊界問題。
max_sit(*n)函數用於找到多個值中最大值的位置,返回其位置,python的內構的max函數只能返回最大值,所以還是需要自己寫,*n表示不定長參數,因為我需要在比較田和十(判斷峰值)都用到這個函數
def max_sit(*n): #返回最大元素的位置
temp = 0
sit = 0
for i in range(len(n)):
if(n[i]>temp):
temp = n[i]
sit = i
return sit
dp(s1,s2,e1,e2)函數中四個參數的分別可看為startx,starty,endx,endy。即我們查找范圍左上角和右下角的坐標值。
m1,m2分別是row 和col的中間值,也就是田字的中間。
def dp(s1,s2,e1,e2):
m1 = int((e1-s1)/2)+s1 #row
m2 = int((e2-s1)/2)+s2 #col
依次比較3行3列中的值找到最大值,注意這里要求二維數組為正方形,如果為矩形需要做調整
for i in range(nub):
t = max_sit(list[s1][s2+i], #第一排
list[m1][s2+i], #中間排
list[e1][s2+i], #最後排
list[s1+i][s2], #第一列
list[s1+i][m2], #中間列
list[s1+i][e2], #最後列
temp)
if(t==6):
pass
elif(t==0):
temp = list[s1][s2+i]
sit_row = s1
sit_col = s2+i
elif(t==1):
temp = list[m1][s2+i]
sit_row = m1
sit_col = s2+i
elif(t==2):
temp = list[e1][s2+i]
sit_row = e1
sit_col = s2+i
elif(t==3):
temp = list[s1+i][s2]
sit_row = s1+i
sit_row = s2
elif(t==4):
temp = list[s1+i][m2]
sit_row = s1+i
sit_row = m2
elif(t==5):
temp = list[s1+i][e2]
sit_row = s1+i
sit_row = m2
判斷田字中最大值是不是峰值,並找不出相鄰最大值
t = max_sit(list[sit_row][sit_col], #中
list[sit_row-1][sit_col], #上
list[sit_row+1][sit_col], #下
list[sit_row][sit_col-1], #左
list[sit_row][sit_col+1]) #右
if(t==0):
return [sit_row-1,sit_col-1]
elif(t==1):
sit_row-=1
elif(t==2):
sit_row+=1
elif(t==3):
sit_col-=1
elif(t==4):
sit_col+=1
縮小范圍,遞歸求解
if(sit_row<m1):
e1 = m1
else:
s1 = m1
if(sit_col<m2):
e2 = m2
else:
s2 = m2
return dp(s1,s2,e1,e2)
好了,到這里代碼基本分析完了。如果還有不清楚的地方歡迎下方留言。
除了這種演算法外,我也寫一種貪心演算法來求解這道題,只可惜最壞的情況下演算法復雜度還是O(n^2),QAQ。
大體的思路就是從中間位置起找相鄰4個點中最大的點,繼續把該點來找相鄰最大點,最後一定會找到一個峰值點,有興趣的可以看一下,上代碼:
#!/usr/bin/python3
def dp(n):
temp = (str[n],str[n-9],str[n-1],str[n+1],str[n+9]) #中 上 左 右 下
sit = temp.index(max(temp))
if(sit==0):
return str[n]
elif(sit==1):
return dp(n-9)
elif(sit==2):
return dp(n-1)
elif(sit==3):
return dp(n+1)
else:
return dp(n+9)
f = open("/home/nancy/桌面/demo.txt","r")
list = f.read()
list = list.replace(" ","").split() #轉換為列表
row = len(list)
col = len(list[0])
str="0"*(col+3)
for x in list: #加圍牆 二維變一維
str+=x+"00"
str+="0"*(col+1)
mid = int(len(str)/2)
print(str,mid)
p = dp(mid)
print (p)
f.close()
以上這篇python分治法求二維數組局部峰值方法就是小編分享給大家的全部內容了,希望能給大家一個參考
D. python 演算法有哪些比賽
演算法是指解題方案的准確而完整的描述,是一系列解決問題的清晰指令,演算法代表著用系統的方法描述解決問題的策略機制。簡單來講,能夠對一定規范的輸入,在有限時間內獲得所要求的輸出。如果一個演算法有缺陷,或不適合於某個問題,執行這個演算法將不會解決這個問題。不同的演算法可能用不同的時間、空間或效率來完成同樣的任務。一個演算法的優劣可以用空間復雜度與時間復雜度來衡量。包括這幾類:
1.
選擇排序演算法:選擇排序是一種簡單直觀的排序演算法。原理:首先在未排序序列中找到最小或最大元素,存放到排序序列的起始位置;然後,再從剩餘未排序元素中繼續尋找最大最小元素,然後放到已排序序列的後面,以此類推直到所有元素均排序完畢。
2.
快速排序演算法:快速排序的運行速度快於選擇排序。原理:設要排序的數組為N,首先任意選取一個數據作為關鍵數據,然後將所有比它小的數放到它前面,所有比它大的數都放到它後面,這個過程稱之為快速排序。
3. 二分查找演算法:二分查找的輸入是一個有序的列表,如果要查找的元素包含在一個有序列表中,二分查找可以返回其位置。
4.
廣度優先搜索演算法:屬於一種圖演算法,圖由節點和邊組成。一個節點可以與多個節點連接,這些節點稱為鄰居。它可以解決兩類問題:第一類是從節點A出發,在沒有前往節點B的路徑;第二類問題是從節點A出發,前往B節點的哪條路徑最短。使用廣度優先搜索演算法的前提是圖的邊沒有權值,即該演算法只用於非加權圖中,如果圖的邊有權值的話就應該使用狄克斯特拉演算法來查找最短路徑。
5.
貪婪演算法:又叫做貪心演算法,對於沒有快速演算法的問題,就只能選擇近似演算法,貪婪演算法尋找局部最優解,並企圖以這種方式獲得全局最優解,它易於實現、運行速度快,是一種不錯的近似演算法。
E. python 二分查找演算法函數bi_search(),該函數實現檢索任意一個整數在 prime() 函數生成的
defprime(n):
ifn<=2:
return[]
result=[False,False]+[True]*(n-2)
foriinrange(len(result)):
ifresult[i]==True:
forjinrange(2*i,len(result),i):
result[j]=False
return[iforiinrange(len(result))ifresult[i]==True]
defbi_search(prime,primelist,start,end):
ifstart>end:
return-1
mid=(start+end)//2
ifprimelist[mid]==prime:
returnmid
elifprimelist[mid]>prime:
end=mid-1
else:
start=mid+1
returnbi_search(prime,primelist,start,end)
if__name__=='__main__':
n=int(raw_input())
primelist=prime(n)
num=raw_input()
whilenum:
num=int(num)
index=bi_search(num,primelist,0,len(primelist)-1)
print(index)
num=raw_input()
F. 推薦系統召回演算法之——圖模型(Personal Rank)
目錄
1、Personal Rank 演算法背景
2、二分圖的概念
3、文件解析原理及其物理意義
4、PR公式推導
5、python實現
6、總結
Personal Rank演算法背景:
用戶行為很容易表示為圖
圖推薦在個性化推薦領域效果顯著,UI矩陣就是典型的二分圖。
二分圖: 又稱為二部圖,是圖論中的一種特殊模型。設G=(V,E)是一個無向圖,如果頂點V可分割為兩個互不相交的子集(A,B),並且圖中的每條邊(i,j)所關聯的兩個頂點i和j分別屬於這兩個不同的頂點集(i in A,i in B),則稱圖G為一個二分圖。
下面舉例並從物理意義角度解析,二分圖演算法是如何將UI矩陣表示為二分圖,計算出Item集合對固定user的重要程度排序?
1、兩個頂點之間連通的路徑數?
A到c:A->a->B->c;A->d->D->c兩條連通路徑;
A到e:A->b->C->e一條連通路徑
故,A對物品c的偏好程度大於對物品e的偏好。
2、兩個頂點之間的連通路徑長度?
A->c兩條路徑4個頂點,連通路徑長度都是3;A->e也為3
3、兩個頂點之間連通路徑經過頂點的初度?
A到c:A->a->B->c:3+2+2+2;A->d->D->c:3+2+2+2
A到e:A->b->C->e:3+2+2+1
演算法文字描述 :對用戶A進行個性化推薦,從用戶A結點開始在用戶物品二分圖random walk ,以alpha的概率從A的出邊中等概率選擇一條遊走過去,到達頂點後(例如a),有alpha的概率繼續從頂點a的出邊中等概率選擇一條繼續遊走到下一個結點,或者(1-alpha)的概率回到起點A,多次迭代。直到所有的頂點對於用戶A的重要度收斂。(二分圖有且只有一個頂點)
演算法公式推導 :
按照上面UI矩陣的二分圖表示法結合演算法文字描述,以節點A和a來舉例解釋公式。
:表示不同節點重要度。
以a為例,公式上部分表示節點a與之相連的節點A和B,分別從各自出邊等概率貢獻了1/3和1/2的重要度加和後乘以 , 取經值為0-1之間(經驗值0.6)。
以A為例,公式下部分表示與A相連的節點a,b,d,分別從各自的出邊等概率貢獻了1/2的重要度,同時它們又是直接與A相連的節點,從PR演算法文字描述可知,都可以以1- 的概率回到A節點。
公式(1)的矩陣表達方式為: (2)
其中 是n維向量,每一個元素代表一個節點的PR重要度; 也是n維向量,第i個位置為1,其餘位置為0,我們就是要為第i個節點進行推薦。其中 是n階轉移矩陣:
由(2)進行恆等變形可得
(3)
(4) ,其中 就是所有節點的推薦結果,乘以 就是取出矩陣的第i列。
Python實現: https://github.com/SolodanceMagicq/RecommendSys/tree/master/PersonalRank
總結:
1、personalrank二分圖演算法,是一種無向圖,有且只有一個root頂點。
2、演算法核心思想是將UI矩陣以二分圖存儲,通過頂點按等概率隨機遊走,迭代計算關聯節點pr值的過程。首次迭代只計算推薦用戶(root頂點)與其直接關聯的節點pr值,然後每次基於上次節點進一步迭代計算關聯節點,直至收斂。
3、PersonalRank演算法迭代的時間復雜度過高,須進一步優化,工業界一般會藉助spark離線計算或maprece將多節點並行計算提高計算性能。
G. python中有哪些簡單的演算法
你好:
跟你詳細說一下python的常用8大演算法:
1、插入排序
插入排序的基本操作就是將一個數據插入到已經排好序的有序數據中,從而得到一個新的、個數加一的有序數據,演算法適用於少量數據的排序,時間復雜度為O(n^2)。是穩定的排序方法。插入演算法把要排序的數組分成兩部分:第一部分包含了這個數組的所有元素,但將最後一個元素除外(讓數組多一個空間才有插入的位置),而第二部分就只包含這一個元素(即待插入元素)。在第一部分排序完成後,再將這個最後元素插入到已排好序的第一部分中。
2、希爾排序
希爾排序(Shell Sort)是插入排序的一種。也稱縮小增量排序,是直接插入排序演算法的一種更高效的改進版本。希爾排序是非穩定排序演算法。該方法因DL.Shell於1959年提出而得名。 希爾排序是把記錄按下標的一定增量分組,對每組使用直接插入排序演算法排序;隨著增量逐漸減少,每組包含的關鍵詞越來越多,當增量減至1時,整個文件恰被分成一組,演算法便終止。
3、冒泡排序
它重復地走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重復地進行直到沒有再需要交換,也就是說該數列已經排序完成。
4、快速排序
通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。
5、直接選擇排序
基本思想:第1趟,在待排序記錄r1 ~ r[n]中選出最小的記錄,將它與r1交換;第2趟,在待排序記錄r2 ~ r[n]中選出最小的記錄,將它與r2交換;以此類推,第i趟在待排序記錄r[i] ~ r[n]中選出最小的記錄,將它與r[i]交換,使有序序列不斷增長直到全部排序完畢。
6、堆排序
堆排序(Heapsort)是指利用堆積樹(堆)這種數據結構所設計的一種排序演算法,它是選擇排序的一種。可以利用數組的特點快速定位指定索引的元素。堆分為大根堆和小根堆,是完全二叉樹。大根堆的要求是每個節點的值都不大於其父節點的值,即A[PARENT[i]] >= A[i]。在數組的非降序排序中,需要使用的就是大根堆,因為根據大根堆的要求可知,最大的值一定在堆頂。
7、歸並排序
歸並排序是建立在歸並操作上的一種有效的排序演算法,該演算法是採用分治法(Divide and Conquer)的一個非常典型的應用。將已有序的子序列合並,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合並成一個有序表,稱為二路歸並。
歸並過程為:比較a[i]和a[j]的大小,若a[i]≤a[j],則將第一個有序表中的元素a[i]復制到r[k]中,並令i和k分別加上1;否則將第二個有序表中的元素a[j]復制到r[k]中,並令j和k分別加上1,如此循環下去,直到其中一個有序表取完,然後再將另一個有序表中剩餘的元素復制到r中從下標k到下標t的單元。歸並排序的演算法我們通常用遞歸實現,先把待排序區間[s,t]以中點二分,接著把左邊子區間排序,再把右邊子區間排序,最後把左區間和右區間用一次歸並操作合並成有序的區間[s,t]。
8、基數排序
基數排序(radix sort)屬於「分配式排序」(distribution sort),又稱「桶子法」(bucket sort)或bin sort,顧名思義,它是透過鍵值的部分資訊,將要排序的元素分配至某些「桶」中,藉以達到排序的作用,基數排序法是屬於穩定性的排序,其時間復雜度為O (nlog(r)m),其中r為所採取的基數,而m為堆數,在某些時候,基數排序法的效率高於其它的穩定性排序法。
H. python中list有沒有自帶二分查找函數
要判斷一個list中是否存在你要的東西,可以用 value in list 的方式或者 list.index(value), 具體python內部實現用的什麼演算法。。。自己研究吧。
I. python演算法有哪些
演算法(Algorithm)是指解題方案的准確而完整的描述,是一系列解決問題的清晰指令,演算法代表著用系統的方法描述解決問題的策略機制。也就是說,能夠對一定規范的輸入,在有限時間內獲得所要求的輸出。如果一個演算法有缺陷,或不適合於某個問題,執行這個演算法將不會解決這個問題。不同的演算法可能用不同的時間、空間或效率來完成同樣的任務。一個演算法的優劣可以用空間復雜度與時間復雜度來衡量。
一個演算法應該具有以下七個重要的特徵:
①有窮性(Finiteness):演算法的有窮性是指演算法必須能在執行有限個步驟之後終止;
②確切性(Definiteness):演算法的每一步驟必須有確切的定義;
③輸入項(Input):一個演算法有0個或多個輸入,以刻畫運算對象的初始情況,所謂0個輸 入是指演算法本身定出了初始條件;
④輸出項(Output):一個演算法有一個或多個輸出,以反映對輸入數據加工後的結果。沒 有輸出的演算法是毫無意義的;
⑤可行性(Effectiveness):演算法中執行的任何計算步驟都是可以被分解為基本的可執行 的操作步,即每個計算步都可以在有限時間內完成(也稱之為有效性);
⑥高效性(High efficiency):執行速度快,佔用資源少;
⑦健壯性(Robustness):對數據響應正確。
相關推薦:《Python基礎教程》
五種常見的Python演算法:
1、選擇排序
2、快速排序
3、二分查找
4、廣度優先搜索
5、貪婪演算法
J. python中有哪些簡單的演算法
Python中的基礎演算法有以下幾種:
基礎加減乘除演算法:
加法>>> 2 + 2;
減法>>> 2 - 2;
乘法>>> 2 * 2;
除法>>> 2 / 2。
整除運算:
第一種>>> 2 / 3 整型與整型相除,獲取整數,條件是除數被除數都是整數;
第二種>>> 2 // 3 雙斜杠整除演算法,只獲取小數點前的部分整數值。
冥運算:
例子1:>>> 2 ** 3;
例子2; >>> -2 ** 3;
例子3: >>> (-2) ** 3