2021年4月15日,京東算法面試題4道

#這是我參與8月更文挑戰的第3天,活動詳情查看:8月更文挑戰算法

1.介紹邏輯迴歸,邏輯迴歸是一個分類算法,那麼它是在迴歸什麼呢?

邏輯迴歸是在數據服從伯努利分佈的假設下,經過極大似然的方法,運用梯度降低法來求解參數,從而達到將數據二分類的目的。編程

邏輯迴歸就是一種減少預測範圍,將預測值限定爲[0,1]間的一種廣義線性迴歸模型,解決的是分類問題。數組

2.編程題:顏色分類(leetcode 75)

思路一:單指針markdown

對數組進行兩次遍歷,考慮使用單指針 ptr 進行遍歷,第一次遍歷中須要把全部的 0 交換到數組的頭部,每交換一次,ptr 向右移動一位,直到遍歷結束,此時 ptr 以前的元素都爲 0;第二次遍歷從 ptr 開始遍歷,將全部的 1 交換到中間位置,每交換一次,ptr 向後移動一位,直到遍歷結束,此時 ptr 以後(包括ptr)的元素都爲2,排序完成。多線程

代碼:函數

class Solution:
    def sortColors(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        ptr = 0
        for i in range(len(nums)):
            if nums[i] == 0:
                nums[i],nums[ptr] = nums[ptr],nums[i]
                ptr +=1
        for i in range(ptr,len(nums)):
            if nums[i] == 1:
                nums[i],nums[ptr] = nums[ptr],nums[i]
                ptr +=1
        return nums
複製代碼

時間複雜度:O(n),其中 nn 是數組 nums 的長度。工具

空間複雜度:O(1)。oop

思路二:雙指針post

相比單指針只須要一次遍歷便可完成。須要指針 p0 來交換等於 0 的元素,指針 p1 來交換等於 1 的元素,須要特別注意的以下:學習

先判斷元素是否等於 1,知足等於1 就進行交換,並將 p1 + 1,再判斷是否等於0 ,若是等於 0 也相應進行交換,另外須要判斷 p0 和 p1 的關係,若是知足 p0 < p1,還須要再次進行交換,完成後將 p0 和 p1 同時 +1。

代碼以下:

class Solution:
    def sortColors(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        p0 = p1 = 0
        for i in range(len(nums)):
            if nums[i] == 1:
                nums[i],nums[p1] = nums[p1],nums[i]
                p1 +=1
            elif nums[i] == 0:
                nums[i],nums[p0] = nums[p0],nums[i]
                if p0 < p1:
                    nums[i],nums[p1] = nums[p1],nums[i]
                p0 += 1
                p1 += 1
        return nums
複製代碼

時間複雜度:O(n),其中 nn 是數組 nums 的長度。

空間複雜度:O(1)。

3.GBDT瞭解嗎?基分類器用的什麼?分類時也是用的那個嗎?

GBDT是梯度提高決策樹,是一種基於Boosting的算法,採用以決策樹爲基學習器的加法模型,經過不斷擬合上一個弱學習器的殘差,最終實現分類或迴歸的模型。關鍵在於利用損失函數的負梯度在當前模型的值做爲殘差的近似值,從而擬合一個迴歸樹。

GBDT的基分類器用的是決策樹,分類時也是用的決策樹。

對於分類問題:常使用指數損失函數;對於迴歸問題:常使用平方偏差損失函數(此時,其負梯度就是一般意義的殘差),對於通常損失函數來講就是殘差的近似。

更多請看七月在線題庫裏的這題:www.julyedu.com/questions/w…

4.XGBoost相對GBDT原理上有哪些改進。

改進主要爲如下方面:

  • 傳統的GBDT以CART樹做爲基學習器,XGBoost還支持線性分類器,這個時候XGBoost至關於L1和L2正則化的邏輯斯蒂迴歸(分類)或者線性迴歸(迴歸);
  • 傳統的GBDT在優化的時候只用到一階導數信息,XGBoost則對代價函數進行了二階泰勒展開,獲得一階和二階導數;
  • XGBoost在代價函數中加入了正則項,用於控制模型的複雜度。從權衡方差誤差來看,它下降了模型的方差,使學習出來的模型更加簡單,放置過擬合,這也是XGBoost優於傳統GBDT的一個特性;
  • shrinkage(縮減),至關於學習速率(XGBoost中的eta)。XGBoost在進行完一次迭代時,會將葉子節點的權值乘上該係數,主要是爲了削弱每棵樹的影響,讓後面有更大的學習空間。(GBDT也有學習速率);
  • 列抽樣:XGBoost借鑑了隨機森林的作法, 支持列抽樣, 不只防止過 擬合,還能減小計算;
  • 對缺失值的處理: 對於特徵的值有缺失的樣本,XGBoost還能夠自動 學習出它的分裂方向;
  • XGBoost工具支持並行。Boosting不是一種串行的結構嗎?怎麼並行 的?注意XGBoost的並行不是tree粒度的並行,XGBoost也是一次迭代完才能進行下一次迭代的(第t次迭代的代價函數裏包含了前面t-1次迭代的預測值)。XGBoost的並行是在特徵粒度上的。咱們知道,決策樹的學習最耗時的一個步驟就是對特徵的值進行排序(由於要肯定最佳分割點),XGBoost在訓練以前,預先對數據進行了排序,而後保存爲block結構,後面的迭代 中重複地使用這個結構,大大減少計算量。這個block結構也使得並行成爲了可能,在進行節點的分裂時,須要計算每一個特徵的增益,最終選增益最大的那個特徵去作分裂,那麼各個特徵的增益計算就能夠開多線程進行。

更多請看七月在線題庫裏的這題:www.julyedu.com/questions/w…

相關文章
相關標籤/搜索