<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【機(jī)器學(xué)習(xí)筆記】Python機(jī)器學(xué)習(xí)基本語法

        本來算法沒有那么復(fù)雜,但如果因?yàn)檎Z法而攻不下就很耽誤時(shí)間。于是就整理一下,搞python機(jī)器學(xué)習(xí)上都需要些什么基本語法,夠用就行,可能會(huì)持續(xù)更新。

       

      Python四大類型

      元組tuple,初始化之后不可元素值變更,其余還沒有感受到它和list什么差別,感覺也比較少用,聲明語法是()

      >>> tp = ()

      >>> type(tp)

      <class 'tuple'>

      字典dict,聲明語法{},對(duì)值 .items(),鍵值 .keys(),值 .values()

      >>> d = {'left': {0}, 'right' :1}

      >>> d

      {'left': {0}, 'right': 1}

      >>> d.keys()

      dict_keys(['left', 'right'])

      集合set,聲明語法set(),括號(hào)內(nèi)只能傳一個(gè)參數(shù),這個(gè)參數(shù)要可迭代。

      整這么多類型干什么呢,主要是每個(gè)類型具有的屬性不同。

      Python支持集合類型的交集(用&)、并集(用|)、差集(用-)、交叉補(bǔ)集(用^)等操作

      >>> setA = set(1,2)

      Traceback (most recent call last):

        File "<stdin>", line 1, in <module>

      TypeError: set expected at most 1 arguments, got 2

      >>> setA = set([1,'a',2.0])

      >>> setB = set(['a'])

      >>> setA | setB

      {1, 2.0, 'a'}

      列表list,聲明語法[],這個(gè)類型很常用,

      需要注意一點(diǎn)的是,在按列表索引查詢列表的數(shù)據(jù)時(shí),方括號(hào)里不能出現(xiàn)小寫逗號(hào)。這是目前我知道的,它與numpy.array類型的主要區(qū)別之一(前者用兩個(gè)方括號(hào))。

      >>> lst = [[0,1,2],[3,4,5],[6,7,8],[9,10,11]]

      >>> lst[1:3]

      [[3, 4, 5], [6, 7, 8]]

      >>> lst[1:5:2]

      [[3, 4, 5], [9, 10, 11]]

      [a:b:c]指從下標(biāo)a到下標(biāo)b(不包括下標(biāo)b)的以c行作為間隔取行,c默認(rèn)是1。例如1~10,如果取2:8:2就是2,4,6

      如果a(或b)為負(fù)數(shù),意思是取倒數(shù)的a行(或b行)

      數(shù)組 numpy.array,這個(gè),和list寫法差不多,但是它很多比較方便的屬性,

      比如獲取矩陣大小shape,改變矩陣大小reshape,矩陣轉(zhuǎn)置T,等等。還有一個(gè)mat類型(聲明為mat()),就是矩陣(matrix)類型,也差不多。

      array比list方便的一點(diǎn)還在于,按索引查詢當(dāng)中,array可以選擇查詢的列,其中對(duì)列的篩選,需要用小寫逗號(hào)隔開。

      (如果是list類型,取第一行第一列是testlist[0][0])

      >>> test = [[0,2],[1,3],[4,0],[2,1],[5,1]]

      >>> test

      [[0, 2], [1, 3], [4, 0], [2, 1], [5, 1]]

      >>> test[0]

      [0, 2]

      >>> test[0][0]

      0

      >>> testA = np.array(test)

      >>> testA[0, :]

      array([0, 2])

       

      循環(huán)

      for item in iterator

      常用for item in range(5)相當(dāng)于for (int i = 0; i < 5; i++)

      或者for item in listInstance就是foreach item in listInstance

      更多點(diǎn)擊這里 

       

      numpy函數(shù)介紹:

      關(guān)于這個(gè),其實(shí)百度一下啥都有,或者在編輯器里懸停鼠標(biāo),可見描述。此處記一下我遇到的,感覺比較特殊的:

      numpy.nonzero()  #求非0元素所在位置

      >>> import numpy as np

      >>> test = [[1,2,5,0],[0,0,1,0]]

      >>> np.nonzero(test)

      (array([0, 0, 0, 1], dtype=int64), array([0, 1, 2, 2], dtype=int64))

      dtype是dataType,指前面這個(gè)array里面數(shù)值的類型。

      求出來是兩行內(nèi)容,第一行是非0的所在行下標(biāo),這個(gè)行下標(biāo)出現(xiàn)多少次,就表示這個(gè)行有多少個(gè)非0元素;第二行是對(duì)應(yīng)第一行的列中,非0元素所在列位置。

      列下標(biāo)\行下標(biāo)

      0

      1

      2

      3

      0

      1

      2

      5

      0

      1

      0

      0

      1

      0

      出現(xiàn)0的位置:

      行下標(biāo)

      0

      0

      0

      1

      列下標(biāo)

      0

      1

      2

      2

       

      var()  #求方差

      看見這個(gè)第一印象真是variable,弱類型,然而,np.var()此var是variance,方差。

       

      關(guān)于查詢

      有3個(gè)強(qiáng)大的函數(shù)

      https://www.liaoxuefeng.com/wiki/1016959663602400/1017329367486080

      >>> def f(x):

      ...     return x * x

      ...

      >>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])

      >>> list(r)

      [1, 4, 9, 16, 25, 36, 49, 64, 81]

       

      reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

      >>> from functools import reduce

      >>> def add(x, y):

      ...     return x + y

      ...

      >>> reduce(add, [1, 3, 5, 7, 9])

      25

       

      排序sorted(list, key = function)

      最最重要的是這個(gè):filter()

      接受兩個(gè)參數(shù),一個(gè)是函數(shù)類型,一個(gè)是迭代器類型

      !! filter()這個(gè)函數(shù)非常重要,相當(dāng)于C#的linq to object

      filter()函數(shù)返回的是一個(gè)Iterator,需要再轉(zhuǎn)換類型,可用list(返回內(nèi)容)

       

      list類型處理下標(biāo)查詢,還能這樣:

      >>> test = [[1,2,5,0],[0,0,1,0]]

      >>> test = np.array(test)

      >>> test[0, :] >= 2

      array([False,  True,  True, False])

       

      >>> test[[0,0,0,1],:]

      array([[1, 2, 5, 0],

             [1, 2, 5, 0],

             [1, 2, 5, 0],

             [0, 0, 1, 0]])

       

      >>> test[:, np.nonzero((test[0, :] >= 2))[0]]

      array([[2, 5],

             [0, 1]])

       

      最后一例這個(gè)查詢,看起來好像很厲害,但是吧,這個(gè)可讀性讓人感到難受,真是不要也罷。

      而且,就此例而言,時(shí)間復(fù)雜度是多少,只是篩選≥2的數(shù)據(jù),列表遍歷了3次,這能忍嗎?

      用filter()不是簡單明了很多嗎?

      我這個(gè)寫法有點(diǎn)古怪,可能不太正確:

      >>> def TestFilter(x):

      ...     if x >= 2:

      ...         return x

      ...     else: return

      >>> test1 = [5,2,3,1,0,0]

      >>> list(filter(TestFilter, test1))

      [5, 2, 3]

      return就是默認(rèn)return None

      于是,這樣也是可行的:

      >>> def tt(x):

      ...     if(x >= 2):

      ...         return x

      再簡略一些:

      >>> list(filter(lambda x : x >=2, test1))

      [5, 4, 3, 2]

       

      然后問題又來了,不能處理二維的list,只能是原子型的list,這樣看來,《機(jī)器學(xué)習(xí)》那書上寫的辦法好像經(jīng)得起考驗(yàn)?

      不,不可能這么沙雕。

      對(duì)象化數(shù)據(jù)不就可以了么!真是多多感謝linq to object,有時(shí)候真覺得語言設(shè)計(jì)者太厲害了,方方面面想到了。

      >>> def testFilter(x):

      ...     if x.col1 > value:

      ...         return x

      ...     else: return

       

      練一練:

      搞明白上面的語法,基本就能直接看明白這個(gè)CART算法的決策樹(classification and regression tree)

      (代碼按閱讀順序排序的,如果要走,注意函數(shù)聲明順序)

       1 from numpy import *
       2 def createTree(dataSet, leafType=regLeaf, errType=regErr, ops=(1,4)): 
       3     feat, val = chooseBestSplit(dataSet, leafType, errType, ops)
       4     if feat == None: return val 
       5     retTree = {}
       6     retTree['spInd'] = feat
       7     retTree['spVal'] = val
       8     lSet, rSet = binSplitDataSet(dataSet, feat, val)
       9     retTree['left'] = createTree(lSet, leafType, errType, ops)
      10     retTree['right'] = createTree(rSet, leafType, errType, ops)
      11     return retTree  
      12 
      13 def chooseBestSplit(dataSet, leafType=regLeaf, errType=regErr, ops=(1,4)):
      14     tolS = ops[0]; tolN = ops[1]
      15     if len(set(dataSet[:, -1].T.tolist()[0])) == 1: #取最后一列,轉(zhuǎn)置為行,取第一行轉(zhuǎn)作集合類型,判斷集合元素個(gè)數(shù)
      16         return None, leafType(dataSet)
      17     m,n = shape(dataSet)                        #數(shù)據(jù)集大小
      18     S = errType(dataSet)                        #errType是個(gè)方法,默認(rèn)為方法regErr,計(jì)算數(shù)據(jù)集數(shù)據(jù)波動(dòng)情況
      19     bestS = inf; bestIndex = 0; bestValue = 0
      20     for featIndex in range(n-1):                  #每一列
      21         for splitVal in dataSet[:,featIndex]:       #每一行
      22             mat0, mat1 = binSplitDataSet(dataSet, featIndex, splitVal)      #按當(dāng)前單元格作為劃分列的閾值
      23             if (shape(mat0)[0] < tolN) or (shape(mat1)[0] < tolN): continue #劃分出來的兩塊,任一塊元素個(gè)數(shù)太小的話
      24             newS = errType(mat0) + errType(mat1)                         #劃分出來的兩塊大小比較合理,就分別計(jì)算誤差
      25             if newS < bestS: 
      26                 bestIndex = featIndex
      27                 bestValue = splitVal
      28                 bestS = newS
      29     if (S - bestS) < tolS: 
      30         return None, leafType(dataSet) 
      31     mat0, mat1 = binSplitDataSet(dataSet, bestIndex, bestValue)
      32     if (shape(mat0)[0] < tolN) or (shape(mat1)[0] < tolN): 
      33         return None, leafType(dataSet)
      34     return bestIndex,bestValue
      35 
      36 def regLeaf(dataSet):
      37     return mean(dataSet[:,-1])                   #我不僅知道m(xù)ean是吝嗇,我還知道m(xù)ean是平均值
      38 
      39 def regErr(dataSet):
      40     return var(dataSet[:,-1]) * shape(dataSet)[0]
      41 
      42 def binSplitDataSet(dataSet, feature, value):     
      43     a = dataSet[nonzero(dataSet[:,feature] > value)[0],:] #所有大于value的行
      44     b = dataSet[nonzero(dataSet[:,feature] <= value)[0],:]
      45     if (len(a) > 0):
      46         mat0 = a
      47     else: mat0 = []
      48     if (len(b) > 0):
      49         mat1 = b
      50     else: mat1 = []
      51     return mat0,mat1
      52 
      53 def loadDataSet(fileName):               #general function to parse tab -delimited floats
      54     dataMat = []                         #assume last column is target value
      55     fr = open(fileName)
      56     for line in fr.readlines():
      57         curLine = line.strip().split('\t')
      58         fltLine = list(map(float,curLine)) #此處的float是個(gè)函數(shù),float(),類型轉(zhuǎn)換為float
      59         dataMat.append(fltLine)
      60         #dataMat.append(curLine)
      61     return mat(dataMat)

       

       Q:代碼返回的是個(gè)什么樹?

      兩列兩百行的數(shù)據(jù)集,其中最后一列是標(biāo)簽,返回的是一個(gè)節(jié)點(diǎn)的樹。

      {'left': 1.0180967672413792, 'right': -0.04465028571428572, 'spInd': 0, 'spVal': matrix([[0.48813]])}

      這個(gè)節(jié)點(diǎn)意思是:列下標(biāo)為0作為判斷依據(jù),當(dāng)待歸類數(shù)值>spval閾值,就走左分支樹;待歸類≤spval,走右分支。

       

      樹剪枝

        這個(gè)算法走下來,對(duì)這個(gè)ops=(1,4)的依賴,就很大,人很難把握到這個(gè)默認(rèn)值是多少比較合適。

        樹的分支少了,很可能就意味著樹不準(zhǔn)確,擬合度不夠;樹的分支多了,就過擬合了,先不說計(jì)算成本可能增多,如果讓歸類范圍有太大偏差就不好了。  

        再,如何判斷這個(gè)樹擬合程度如何?——可以放一些新的帶已知結(jié)果的數(shù)據(jù)進(jìn)去,比較一下分類結(jié)果誤差情況。如果新數(shù)據(jù)在某個(gè)節(jié)點(diǎn)的分類誤差比較大,那倒不如不要這個(gè)節(jié)點(diǎn)了。當(dāng)然,這個(gè)過程要從葉節(jié)點(diǎn)開始計(jì)算。這就是樹剪枝。

       

        樹剪枝,有時(shí)候真覺得,算法怎么可以沒有動(dòng)畫,沒有圖呢,只有公式,勸退多少人啊。

         這個(gè)圖取自李航的《統(tǒng)計(jì)學(xué)習(xí)方法》,感覺一下子get到精髓——這個(gè)損失得怎么設(shè)置?

       1 def isTree(obj):
       2     return (type(obj).__name__=='dict')                 #此代碼樹的類型是dict
       3 
       4 def getMean(tree):
       5     if isTree(tree['right']): tree['right'] = getMean(tree['right'])
       6     if isTree(tree['left']): tree['left'] = getMean(tree['left'])
       7     return (tree['left']+tree['right'])/2.0
       8     
       9 def prune(tree, testData):                              #這個(gè)testData最后一列還是標(biāo)簽列,是個(gè)數(shù)值
      10     if shape(testData)[0] == 0: return getMean(tree)    #if we have no test data collapse the tree
      11     if (isTree(tree['right']) or isTree(tree['left'])): #if the branches are not trees try to prune them
      12         lSet, rSet = binSplitDataSet(testData, tree['spInd'], tree['spVal'])
      13     if isTree(tree['left']): tree['left'] = prune(tree['left'], lSet)
      14     if isTree(tree['right']): tree['right'] =  prune(tree['right'], rSet)
      15     #if they are now both leafs, see if we can merge them
      16     if not isTree(tree['left']) and not isTree(tree['right']):
      17         lSet, rSet = binSplitDataSet(testData, tree['spInd'], tree['spVal'])
      18         errorNoMerge = sum(power(lSet[:,-1] - tree['left'],2)) + sum(power(rSet[:,-1] - tree['right'],2))
      19         treeMean = (tree['left']+tree['right'])/2.0
      20         errorMerge = sum(power(testData[:,-1] - treeMean,2))
      21         if errorMerge < errorNoMerge: 
      22             print("merging")
      23             return treeMean
      24         else: return tree
      25     else: return tree

        原來按節(jié)點(diǎn)的閾值劃分testData的數(shù)據(jù)后,分別求兩個(gè)數(shù)據(jù)塊與左右子樹的距離總數(shù) errorNoMerge,如果這個(gè)距離比按另一個(gè)數(shù) errorMerge 大時(shí),就合并。這個(gè)損失函數(shù)的選定,看似有些拓展空間,但我更喜歡具體問題具體分析,所以此處不展開。

       

      隨機(jī)森林

        隨機(jī)森林(Random Forest)是一種集成學(xué)習(xí)方法。

        集成學(xué)習(xí),我的理解是,有幾種決策模型,可能大家意見不同,然后投票(取平均或設(shè)置決策模型權(quán)重)決出結(jié)果。

        集成學(xué)習(xí)是一種“投票法”,少數(shù)服從多數(shù)。因?yàn)榧蓪W(xué)習(xí)中每個(gè)個(gè)體學(xué)習(xí)器可能學(xué)到的是任務(wù)的不同方面,綜合不同方面的結(jié)果可以達(dá)到一定程度上的泛化作用。是由多個(gè)弱學(xué)習(xí)器組成一個(gè)強(qiáng)學(xué)習(xí)器。

       

        隨機(jī)森林里設(shè)置有多顆決策樹,任務(wù)結(jié)果由這些決策樹投票決出。

        設(shè)定現(xiàn)有M * N大小的DataSet,其中M為數(shù)據(jù)行數(shù),N為特征列數(shù)目。隨機(jī)森林算法步驟如下:

      1.有放回地(有放回抽樣Bootstrap Sample)x次取出y行n個(gè)(n應(yīng)遠(yuǎn)小于N)特征列,其中x * y = m,創(chuàng)建x個(gè)決策樹(每棵樹都不需要剪枝);

      2.由步驟1組成隨機(jī)森林,其中,對(duì)于分類問題:根據(jù)多棵樹分類器投票[0]決出分類結(jié)果;對(duì)于回歸問題,取多棵樹預(yù)測(cè)值的均值[0]作為預(yù)測(cè)結(jié)果。

      [0]對(duì)于步驟2,如何對(duì)子模型賦予“其結(jié)果重要性”還可以再玩些花樣。

      3.取未被步驟1選中過的數(shù)據(jù)集(OOB,out-of-bag[1])作為測(cè)試數(shù)據(jù),需要測(cè)試準(zhǔn)確率(袋外錯(cuò)誤率out-of-bag error),這個(gè)準(zhǔn)確率可以粗暴地這樣處理:比較經(jīng)過隨機(jī)森林得到的決策結(jié)果與真實(shí)結(jié)果,以求得準(zhǔn)確率。

      [1]關(guān)于有放回抽樣 Bootstrap Sample,

      設(shè)在袋中有x個(gè)不同的小球,有放回抽取x個(gè),那么抽到不同小球的個(gè)數(shù)大概是多少個(gè)?

      此時(shí),有一個(gè)小球在一次抽取中被抽中的概率是1/x,設(shè)小球不被抽中的概率是P,x次不被抽中的概率是:

       其中又: 

      所以,當(dāng)x取無窮大時(shí),有:

      所以,不會(huì)被抽中的球大概有:x·P個(gè)。

      假如設(shè)x取100,那么大概會(huì)取到不同的小球個(gè)數(shù)是100 – 36.79 ≈ 63

      參考自:https://blog.csdn.net/cholocatehe/article/details/42130341

       

      4.得到準(zhǔn)確率后給步驟2得到的眾決策樹添加決策權(quán)重,準(zhǔn)確率高的權(quán)重稍高一些,準(zhǔn)確率低的權(quán)重稍小一些。當(dāng)然,此步不走,那么步驟2每棵樹權(quán)重就取平均。

       

      隨機(jī)森林 缺點(diǎn)

      想要得出超過范圍的獨(dú)立變量或非獨(dú)立變量,可能不行;

      關(guān)于網(wǎng)上所說的一點(diǎn),“噪音較大的數(shù)據(jù),RF容易陷入過擬合”,這個(gè)說法的缺點(diǎn),不太贊成叭,如果噪音這么大,就應(yīng)該預(yù)處理,應(yīng)該很少有方法可以不需要預(yù)處理數(shù)據(jù)(神經(jīng)網(wǎng)絡(luò)好像可以);

      比較明顯的缺點(diǎn)還沒感受到,如果后面有實(shí)操,再來補(bǔ)充。

       

      其他:

      Python實(shí)現(xiàn):

      在scikit-learn類庫里面有很多現(xiàn)成的集成學(xué)習(xí)方法

      https://scikit-learn.org/stable/modules/classes.html#module-sklearn.ensemble

       更多文獻(xiàn) github 上也有人歸納了:

      https://github.com/kjw0612/awesome-random-forest

       

      posted @ 2019-09-09 23:48  Carcar019  閱讀(602)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 久热久精久品这里在线观看| 鲁丝片一区二区三区免费| 国产美女自卫慰黄网站| 铜梁县| 日韩av毛片福利国产福利| 波多野结系列18部无码观看AV| 芜湖市| 亚洲精品自拍在线视频| 亚洲成在人线av无码| 一本一道av中文字幕无码| 国产欧美在线手机视频| 欧美拍拍视频免费大全| 亚洲一久久久久久久久| 国产麻豆精品一区二区三区v视界| 精品日本免费一区二区三区| 百色市| 综合偷自拍亚洲乱中文字幕| 亚洲最大福利视频网| 91在线视频视频在线| 激情四射激情五月综合网| 日本牲交大片免费观看| 日韩人妖精品一区二区av| 无码囯产精品一区二区免费| 亚洲av无一区二区三区| 久久天天躁狠狠躁夜夜婷 | 久久99久国产麻精品66| 亚洲最大成人在线播放| 97国产成人无码精品久久久| 亚洲男人天堂2021| 激情综合网激情五月伊人| gogogo高清在线观看视频中文| 狠狠色丁香婷婷久久综合五月| 日本一本无道码日韩精品| 精品一区二区三区在线播放视频| 东京热人妻无码一区二区av| 在线观看人成视频免费| 日韩全网av在线| 国产精品人妻熟女男人的天堂| 亚洲夜色噜噜av在线观看| 国语精品一区二区三区| 国产精品日韩专区第一页|