分類
發燒車訊

RabbitMQ入門,我是動了心的

人一輩子最值得炫耀的不應該是你的財富有多少(雖然這話說得有點違心,呵呵),而是你的學習能力。技術更新迭代的速度非常快,那作為程序員,我們就應該擁有一顆擁抱變化的心,积極地跟進。

在 RabbitMQ 入門之前,我已經入門了 Redis、Elasticsearch 和 MongoDB,這讓我感覺自己富有極客精神,非常良好。

小夥伴們在繼續閱讀之前,我必須要聲明一點,我對 RabbitMQ 並沒有進行很深入的研究,僅僅是因為要用,就學一下。但作為一名負責任的技術博主,我是動了心的,這篇入門教程,小夥伴們讀完后絕對會感到滿意,忍不住無情地點贊,以及赤裸裸地轉發。

當然了,小夥伴們遇到文章中有錯誤的地方,不要手下留情,可以組團過來捶我,但要保證一點,不要打臉,我怕毀容。

01、RabbitMQ 是什麼

首先,我知道,Rabbit 是一隻兔子(哎呀媽呀,忍不住秀了一波自己的英語功底),可愛的形象已經躍然於我的腦海中了。那 MQ 又是什麼呢?是 Message Queue 的首字母縮寫,也就是說 RabbitMQ 是一款開源的消息隊列系統。

RabbitMQ 的主要特點在於健壯性好、易於使用、高性能、高併發、集群易擴展,以及強大的開源社區支持。反正就是很牛逼的樣子。

九年前我做大宗期貨交易的時候,也需要消息推送,那時候還不知道去找這種現成的中間件,就用自定義的隊列實現,結果搞了不少 bug,有些到現在還沒有解決,真的是不堪回首的往事啊。

下圖是 RabbitMQ 的消息模型圖(來源於網絡,侵刪),小夥伴們來感受下。

1)P 是 Producer,代表生產者,也就是消息的發送者,可以將消息發送到 X

2)X 是 Exchange(為啥不是 E,我也很好奇),代表交換機,可以接受生產者發送的消息,並根據路由將消息發送給指定的隊列

3)Q 是 Queue,也就是隊列,存放交換機發送來的消息

4)C 是 Consumer,代表消費者,也就是消息的接受者,從隊列中獲取消息

聽我這樣一解釋,是不是對 RabbitMQ 的印象就很具象化了?小夥伴們,學起來吧!

02、安裝 Erlang

咦,怎麼不是安裝 RabbitMQ 啊?先來看看官方的解釋。

英文看不太懂,沒關係,我來補充兩人話。RabbitMQ 服務器是用 Erlang 語言編寫的,它的安裝包里並沒有集成 Erlang 的環境,因此需要先安裝 Erlang。小夥伴們不要擔心,Erlang 安裝起來沒有任何難度。

Erlang 下載地址如下:

https://erlang.org/download/otp_versions_tree.html

最新的版本是 23.0.1,我選擇的是 64 位的版本,104M 左右。下載完就可以雙擊運行安裝,傻瓜式的。

需要注意的是,我安裝的過程中,電腦重啟了一次,好像要安裝一個什麼庫,重啟之前忘記保存圖片了(sorry)。重啟后,重新雙擊運行 otp_win64_23.0.1.exe 文件完成 Erlang 安裝。

03、安裝 RabbitMQ

Erlang 安裝成功后,就可以安裝 RabbitMQ 了。下載地址如下所示:

https://www.rabbitmq.com/install-windows.html

找到下圖中的位置,選擇紅色框中的文件進行下載。

安裝包只有 16.5M 大小,還是非常輕量級的。下載完后直接雙擊運行 exe 文件就可以傻瓜式地安裝了。

安裝成功后,就可以將 RabbitMQ 作為 Windows 服務啟動,可以從“開始”菜單管理 RabbitMQ Windows 服務。

點擊「RabbitMQ Command Prompt (sbin dir)」,進入命令行,輸入 rabbitmqctl.bat status 可確認 RabbitMQ 的啟動狀態。

可以看到 RabbitMQ 一些狀態信息:

  • 進程 ID,也就是 PID 為 2816
  • 操作系統為 Windows
  • 當前的版本號為 3.8.4
  • Erlang 的配置信息

命令行界面看起來不夠優雅,因此我們可以輸入以下命令來啟用客戶端管理 UI 插件:

rabbitmq-plugins enable rabbitmq_management

看到以下信息就可以確認插件啟用成功了。

在瀏覽器地址欄輸入 http://localhost:15672/ 可以進入管理端界面,如下圖所示:

04、在 Java 中使用 RabbitMQ

有些小夥伴可能會問,“二哥,我是一名 Java 程序員,我該如何在 Java 中使用 RabbitMQ 呢?”這個問題問得好,這就來,這就來。

第一步,在項目中添加 RabbitMQ 客戶端依賴:

<dependency>
    <groupId>com.rabbitmq</groupId>
    <artifactId>amqp-client</artifactId>
    <version>5.9.0</version>
</dependency>

第二步,我們來模擬一個最簡單的場景,一個生產者發送消息到隊列中,一個消費者從隊列中讀取消息並打印。

官方對 RabbitMQ 有一個很好的解釋,我就“拿來主義”的用一下。在我上高中的年代,同學們之間最流行的交流方式不是 QQ、微信,甚至短信這些,而是書信。因為那時候還沒有智能手機,況且上學期間學校也是命令禁用手機的,所以書信是情感表達的最好方式。好懷念啊。

假如我向女朋友小巷寫了一封情書,內容如下所示:

致小巷
你好呀,小巷。
你走了以後我每天都感到很悶,就像堂吉訶德一樣,每天想念托波索的達辛妮亞。我現在已經養成了一種習慣,就是每兩三天就要找你說幾句不想對別人說的話。
。。。。。。
王二,5月20日

那這封情書要寄給小巷,我就需要跑到郵局,買上郵票,投遞到郵箱當中。女朋友要收到這封情書,就需要郵遞員盡心儘力,不要弄丟了。

RabbitMQ 就像郵局一樣,只不過處理的不是郵件,而是消息。之前解釋過了,P 就是生產者,C 就是消費者。

新建生產者類 Wanger :

public class Wanger {
    private final static String QUEUE_NAME = "love";
    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory factory = new ConnectionFactory();

        try (Connection connection = factory.newConnection();
             Channel channel = connection.createChannel()) {
            channel.queueDeclare(QUEUE_NAME, falsefalsefalsenull);
            String message = "小巷,我喜歡你。";
            channel.basicPublish("", QUEUE_NAME, null, message.getBytes(StandardCharsets.UTF_8));
            System.out.println(" [王二] 發送 '" + message + "'");
        }
    }
}

1)QUEUE_NAME 為隊列名,也就是說,生產者發送的消息會放到 love 隊列中。

2)通過以下方式創建服務器連接:

ConnectionFactory factory = new ConnectionFactory();
try (Connection connection = factory.newConnection();
             Channel channel = connection.createChannel()) {

ConnectionFactory 是一個非常方便的工廠類,可用來創建到 RabbitMQ 的默認連接(主機名為“localhost”)。然後,創建一個通道( Channel)來發送消息。

Connection 和 Channel 類都實現了 Closeable 接口,所以可以使用 try-with-resource 語句,如果有小夥伴對 try-with-resource 語句不太熟悉,可以查看我之前寫的我去文章。

3)在發送消息的時候,必須設置隊列名稱,通過 queueDeclare() 方法設置。

4)basicPublish() 方法用於發布消息:

  • 第一個參數為交換機(exchange),當前場景不需要,因此設置為空字符串;
  • 第二個參數為路由關鍵字(routingKey),暫時使用隊列名填充;
  • 第三個參數為消息的其他參數(BasicProperties),暫時不配置;
  • 第四個參數為消息的主體,這裏為 UTF-8 格式的字節數組,可以有效地杜絕中文亂碼。

生產者類有了,接下來新建消費者類 XiaoXiang:

public class XiaoXiang {
    private final static String QUEUE_NAME = "love";
    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory factory = new ConnectionFactory();
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        channel.queueDeclare(QUEUE_NAME, falsefalsefalsenull);
        System.out.println("等待接收消息");

        DeliverCallback deliverCallback = (consumerTag, delivery) -> {
            String message = new String(delivery.getBody(), "UTF-8");
            System.out.println(" [小巷] 接收到的消息 '" + message + "'");
        };
        channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });
    }
}

1)創建通道的代碼和生產者差不多,只不過沒有使用 try-with-resource 語句來自動關閉連接和通道,因為我們希望消費者能夠一直保持連接,直到我們強制關閉它。

2)在接收消息的時候,必須設置隊列名稱,通過 queueDeclare() 方法設置。

3)由於 RabbitMQ 將會通過異步的方式向我們推送消息,因此我們需要提供了一個回調,該回調將對消息進行緩衝,直到我們做好準備接收它們為止。

DeliverCallback deliverCallback = (consumerTag, delivery) -> {
    String message = new String(delivery.getBody(), "UTF-8");
    System.out.println(" [小巷] 接收到的消息 '" + message + "'");
};

basicConsume() 方法用於接收消息:

  • 第一個參數為隊列名(queue),和生產者相匹配(love)。

  • 第二個參數為 autoAck,如果為 true 的話,表明服務器要一次性交付消息。怎麼理解這個概念呢?小夥伴們可以在運行消費者類 XiaoXiang 類之前,先多次運行生產者類 Wanger,向隊列中發送多個消息,等到消費者類啟動后,你就會看到多條消息一次性接收到了,就像下面這樣。

等待接收消息
 [小巷] 接收到的消息 '小巷,我喜歡你。'
 [小巷] 接收到的消息 '小巷,我喜歡你。'
 [小巷] 接收到的消息 '小巷,我喜歡你。'
  • 第三個參數為 DeliverCallback,也就是消息的回調函數。

  • 第四個參數為 CancelCallback,我暫時沒搞清楚是幹嘛的。

在消息發送的過程中,也可以使用 RabbitMQ 的管理面板查看到消息的走勢圖,如下所示。

05、鳴謝

好了,我親愛的小夥伴們,以上就是本文的全部內容了,是不是看完后很想實操一把 RabbitMQ,趕快行動吧!如果你在學習的過程中遇到了問題,歡迎隨時和我交流,雖然我也是個菜鳥,但我有熱情啊。

另外,如果你想寫入門級別的文章,這篇就是最好的範例。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

新北清潔公司,居家、辦公、裝潢細清專業服務

※教你寫出一流的銷售文案?

分類
發燒車訊

為什麼用抓包工具看HTTPS包是明文的

測試或者開發調試的過程中,經常會進行抓包分析,並且裝上抓包工具的證書就能抓取 HTTPS 的數據包並显示。由此就產生了一個疑問,為什麼抓包工具裝上證書後就能抓到 HTTPS 的包並显示呢?不是說 HTTPS 是加密傳輸的嗎?

今天這篇文章就來探究下上面這個問題,要解釋清楚這個問題,我會通過解答以下兩個問題來講述:

  1. HTTPS 到底是什麼?
  2. 抓包工具抓包的原理?

HTTPS 到底是什麼

HTTP 作為一種被廣泛使用的傳輸協議,也存在一些的缺點:

  1. 無狀態(可以通過 Cookie 或 Session 解決);
  2. 明文傳輸;
  3. 不安全;

為了解決 “明文” 和 “不安全” 兩個問題,就產生了 HTTPSHTTPS 不是一種單獨的協議,它是由 HTTP + SSL/TLS 組成。

HTTP與HTTPS

所以要理解 HTTPS 就只需在 HTTP 的基礎上理解 SSL/TLS (TLS 是 SSL 的後續版本,現在一般使用 TLS),下面就來了解下 TLS 是什麼。

TLS

傳輸層安全性協議(英語:Transport Layer Security,縮寫:TLS)及其前身安全套接層(英語:Secure Sockets Layer,縮寫:SSL)是一種安全協議,目的是為互聯網通信提供安全及數據完整性保障。

TLS 由記錄協議、握手協議、警報協議、變更密碼規範協議、擴展協議等幾個子協議組成,綜合使用了對稱加密、非對稱加密、身份認證等許多密碼學前沿技術。

  • 記錄協議 規定
    TLS 收發數據的基本單位為:記錄。類似
    TCP 里的
    segment,所有其它子協議都需要通過記錄協議發出。
  • 警報協議 的職責是向對方發出警報信息,類似於
    HTTP 里的狀態碼。
  • 握手協議
    TLS 里最複雜的子協議,瀏覽器和服務器在握手過程中會協商
    TLS 版本號、隨機數、密碼套件等信息,然後交換證書和密鑰參數,最終雙方協商得到會話密鑰,用於後續的混合加密系統。
  • 變更密碼規範協議 用於告知對方,後續的數據都將使用加密傳輸。

TLS 的握手過程:

TLS握手過程

握手過程抓包显示:

TLS抓包
TLS所傳輸的數據

交換密鑰的過程為:

  1. 客戶端發起一個請求給服務器;
  2. 服務器生成一對非對稱的公鑰(
    pubkey)和私鑰(
    privatekey),然後把公鑰附加到一個
    CA数字證書 上返回給客戶端;
  3. 客戶端校驗該證書是否合法(通過瀏覽器內置的廠商根證書等手段校驗),然後從證書中提取出公鑰(
    pubkey);
  4. 客戶端生成一個隨機數(
    key),然後使用公鑰(
    pubkey)對這個隨機數進行加密后發送給服務器;
  5. 服務器利用私鑰(
    privatekey)對收到的隨機數密文進行解密得到
    key ;
  6. 後續客戶端和服務器傳輸數據使用該
    key 進行加密后再傳輸;

抓包工具抓包的原理

先來看看抓 HTTP 包的原理

HTTP抓包過程

  1. 首先抓包工具會提供出代理服務,客戶端需要連接該代理;
  2. 客戶端發出
    HTTP 請求時,會經過抓包工具的代理,抓包工具將請求的原文進行展示;
  3. 抓包工具使用該原文將請求發送給服務器;
  4. 服務器返回結果給抓包工具,抓包工具將返回結果進行展示;
  5. 抓包工具將服務器返回的結果原樣返回給客戶端;

抓包工具就相當於個透明的中間人,數據經過的時候它一隻手接到數據,然後另一隻手把數據傳出去。

再來看看 HTTPS 的抓包

HTTPS抓包過程

這個時候抓包工具對客戶端來說相當於服務器,對服務器來說相當於客戶端。在這個傳輸過程中,客戶端會以為它就是目標服務器,服務器也會以為它就是請求發起的客戶端。

  1. 客戶端連接抓包工具提供的代理服務;
  2. 客戶端需要安裝抓包工具的根證書;
  3. 客戶端發出
    HTTPS 請求,抓包工具模擬服務器與客戶端進行
    TLS 握手交換密鑰等流程;
  4. 抓包工具發送一個
    HTTPS 請求給客戶端請求的目標服務器,並與目標服務器進行
    TLS 握手交換密鑰等流程;
  5. 客戶端使用與抓包工具協定好的密鑰加密數據后發送給抓包工具;
  6. 抓包工具使用與客戶端協定好的密鑰解密數據,並將結果進行展示;
  7. 抓包工具將解密后的客戶端數據,使用與服務器協定好的密鑰進行加密后發送給目標服務器;
  8. 服務器解密數據后,做對應的邏輯處理,然後將返回結果使用與抓包工具協定好的密鑰進行加密發送給抓包工具;
  9. 抓包工具將服務器返回的結果,用與服務器協定好的密鑰解密,並將結果進行展示;
  10. 抓包工具將解密后的服務器返回數據,使用與客戶端協定好的密鑰進行加密后發送給客戶端;
  11. 客戶端解密數據;

總結

  • HTTPS 不是單獨的一個協議,它是
    HTTP +
    SSL/TLS 的組合;
  • TLS 是傳輸層安全性協議,它會對傳輸的
    HTTP 數據進行加密,使用非對稱加密和對稱加密的混合方式;
  • 抓包工具的原理就是“偽裝“,對客戶端偽裝成服務器,對服務器偽裝成客戶端;
  • 使用抓包工具抓
    HTTPS 包必須要將抓包工具的證書安裝到客戶端本地,並設置信任;
  • HTTPS 數據只是在傳輸時進行了加密,而抓包工具是接收到數據后再重新加密轉發,所以抓包工具抓到的
    HTTPS 包可以直接看到明文;

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準

分類
發燒車訊

Python 為什麼不支持 i++ 自增語法,不提供 ++ 操作符?

在 C/C++/Java 等等語言中,整型變量的自增或自減操作是標配,它們又可分為前綴操作(++i 和 –i)與後綴操作(i++ 和 i–),彼此存在着一些細微差別,各有不同的用途。

這些語言的使用者在接觸 Python 時,可能會疑惑為什麼它不提供 ++ 或 — 的操作呢?在我前不久發的《Python的十萬個為什麼?》里,就有不少同學在調查問卷中表示了對此話題感興趣。

Python 中雖然可能出現 ++i 這種前綴形式的寫法,但是它並沒有“++”自增操作符,此處只是兩個“+”(正數符號)的疊加而已,至於後綴形式的“++”,則完全不支持(SyntaxError: invalid syntax)。

本期“Python為什麼 ”欄目,我們將會從兩個主要的角度來回答:Python 為什麼不支持 i++ 自增語法? (PS:此處自增指代“自增和自減”,下同)

首先,Python 當然可以實現自增效果,即寫成i += 1 或者 i = i + 1 ,這在其它語言中也是通用的。

雖然 Python 在底層用了不同的魔術方法(__add__()__iadd__() )來完成計算,但表面上的效果完全相同。

所以,我們的問題可以轉化成:為什麼上面的兩種寫法會勝過 i++,成為 Python 的最終選擇呢?

1、Python 的整數是不可變類型

當我們定義i = 1000 時,不同語言會作出不同的處理:

  • C 之類的語言(寫法 int i = 1000)會申請一塊內存空間,並給它“綁定”一個固定的名稱 i,同時寫入一個可變的值 1000。在這裏,i 的地址以及類型是固定的,而值是可變的(在一定的表示範圍內)
  • Python(寫法i = 1000)也會申請一塊內存空間,但是它會“綁定”給数字 1000,即這個 1000 的地址以及類型是固定的(immutable),至於 i,只是一個名稱標籤貼在 1000 上,自身沒有固定的地址和類型

所以當我們令 i “自增”時(i = i + 1),它們的處理是不同的:

  • C 之類的語言先找到 i 的地址上存的數值,然後令它加 1,操作后新的數值就取代了舊的數值
  • Python 的操作過程是把 i 指向的数字加 1,然後把結果綁定到新申請的一塊內存空間,再把名稱標籤 i “貼”到新的数字上。新舊数字可以同時存在,不是取代關係

打一個不太恰當的比方:C 中的 i 就像一個宿主,数字 1000 寄生在它上面;而 Python 中的 1000 像個宿主,名稱 i 寄生在它上面。C 中的 i 與 Python 中的 1000,它們則寄生在底層的內存空間上……

還可以這樣理解:C 中的變量 i 是一等公民,数字 1000 是它的一個可變的屬性;Python 中的数字 1000 是一等公民,名稱 i 是它的一個可變的屬性。

有了以上的鋪墊,我們再來看看 i++,不難發現:

  • C 之類的語言,i++ 可以表示 i 的数字屬性的增加,它不會開闢新的內存空間,也不會產生新的一等公民
  • Python 之類的語言,i++ 如果是對其名稱屬性的操作,那樣就沒有意義了(總不能按字母表順序,把 i 變成 j 吧);如果理解成對数字本體的操作,那麼情況就會變得複雜:它會產生新的一等公民 1001,因此需要給它分配一個內存地址,此時若佔用 1000 的地址,則涉及舊對象的回收,那原有對於 1000 的引用關係都會受到影響,所以只能開闢新的內存空間給 1001

Python 若支持 i++,其操作過程要比 C 的 i++ 複雜,而且其含義也不再是“令数字增加1”(自增),而是“創建一個新的数字”(新增), 這樣的話,“自增操作符”(increment operator)就名不副實了。

Python 在理論上可以實現 i++ 操作,但它就必須重新定義“自增操作符”,還會令有其它語言經驗的人產生誤解,不如就讓大家直接寫成i += 1 或者 i = i + 1 好了。

2、Python 有可迭代對象

C/C++ 等語言設計出 i++,最主要的目的是為了方便使用三段式的 for 結構:

for(int i = 0; i < 100; i++){
    // 執行 xxx
}

這種程序關心的是数字本身的自增過程,数字做加法與程序體的執行相關聯。

Python 中沒有這種 for 結構的寫法,它提供了更為優雅的方式:

for i in range(100):
    # 執行 xxx

my_list = ["你好", "我是Python貓", "歡迎關注"]
for info in my_list:
    print(info)

這裏體現了不同的思維方式,它關心的是在一個數值範圍內的迭代遍歷,並不關心也不需要人為對数字做加法。

Python 中的可迭代對象/迭代器/生成器提供了非常良好的迭代/遍歷用法,能夠做到對 i++ 的完全替代。

例如,上例中實現了對列表內值的遍歷,Python 還可以用 enumerate() 實現對下標與具體值的同時遍歷:

my_list = ["你好", "我是Python貓", "歡迎關注"]
for i, info in enumerate(my_list):
    print(i, info)

# 打印結果:
0 你好
1 我是Python貓
2 歡迎關注

再例如對於字典的遍歷,Python 提供了 keys()、values()、items() 等遍歷方法,非常好用:

my_dict = {'a': '1', 'b': '2', 'c': '3'}
for key in my_dict.keys():
    print(key)

for key, value in my_dict.items():
    print(key, value)

有了這樣的利器,哪裡還有 i++ 的用武之地呢?

不僅如此,Python 中基本上很少使用i += 1 或者 i = i + 1 ,由於存在着隨處可見的可迭代對象,開發者們很容易實現對一個數值區間的操作,也就很少有對於某個數值作累加的訴求了。

所以,回到我們開頭的問題,其實這兩種“自增”寫法並沒有勝出 i++ 多少,只因為它們是通用型操作,又不需要引入新的操作符,所以 Python 才延續了一種基礎性的支持。真正的贏家其實是各種各樣的可迭代對象!

稍微小結下:Python 不支持自增操作符,一方面是因為它的整數是不可變類型的一等公民,自增操作(++)若要支持,則會帶來歧義;另一方面主要因為它有更合適的實現,即可迭代對象,對遍歷操作有很好的支持。

如果你覺得本文分析得不錯,那你應該會喜歡這些文章:

1、Python為什麼使用縮進來劃分代碼塊?

2、Python 的縮進是不是反人類的設計?

3、Python 為什麼不用分號作語句終止符?

4、Python 為什麼沒有 main 函數?為什麼我不推薦寫 main 函數?

5、Python 為什麼推薦蛇形命名法?

寫在最後:本文屬於“Python為什麼”系列(Python貓出品),該系列主要關注 Python 的語法、設計和發展等話題,以一個個“為什麼”式的問題為切入點,試着展現 Python 的迷人魅力。部分話題會推出視頻版,請在 B 站收看,觀看地址:視頻地址

公眾號【Python貓】, 本號連載優質的系列文章,有Python為什麼系列、喵星哲學貓系列、Python進階系列、好書推薦系列、技術寫作、優質英文推薦與翻譯等等,歡迎關注哦。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

新北清潔公司,居家、辦公、裝潢細清專業服務

※教你寫出一流的銷售文案?

分類
發燒車訊

一文讀懂:GBDT梯度提升

先縷一縷幾個關係:

  • GBDT是gradient-boost decision tree
  • GBDT的核心就是gradient boost,我們搞清楚什麼是gradient boost就可以了
  • GBDT是boost中的一種方法,boost還有XGBoost,adaboost。

基本概念

【Boost】就是讓多個弱分類器,通過不同的集成方式,來讓多個弱分類器變成一個強分類器。

【gradient-boost】 梯度提升。簡單的說,先訓練一個弱分類器,然後弱分類器和目標值之間的殘差,作為下一個弱分類器訓練的目標值。這裡有一個非常簡單的例子

  • 第一個模型預測年齡,雖然真實值是30歲,第一個模型只給出了20歲的估計值;
  • 第二棵樹要預測的就是這個10歲的殘差,但是第二棵樹只給出了6歲的估計值;
  • 第三棵樹預測的是第二棵樹的4歲的殘差,但是………………(禁止套娃)

梯度 or 殘差 ?

對於GBDT,網上的很多文章都沒有講清楚,學習梯度還是學習殘差?從上面的那個例子來看,是學習殘差的。

其實,從來GBDT都是學習梯度的,學習殘差只是學習梯度的一個特例!

如果我們是在做一個回歸任務(就像是上面例子中預測年齡),採用平方損失:\(loss = \frac{1}{2}\sum^n_i{(y_i-\hat{y_i})^2}\)
其中\(y_i\)是真實數值,\(\hat{y_i}\)是模型預測的值。

然後想求取這個關於\(\hat{y_i}\)的梯度,那就是:
\(\frac{\partial loss}{\partial \hat{y^i}}=(-1)(y_i-\hat{y_i})\)

所以殘差在平方損失的情況下,就是等於負梯度,所以兩者一回事。

殘差過於敏感

對於數據不幹凈,沒有清晰掉異常值的數據樣本。使用平方損失對異常值過於敏感了

所以,這裡在回歸問題中,也可以考慮使用下面的兩個損失函數:

  • Absolute loss:
    \(loss=|y-\hat{y}|\)

  • Huber loss:
    這個是設置一個閾值,當\(|y-\hat{y}|\)小於這個閾值的時候,採用平方損失,當\(|y-\hat{y}|\)大於這個閾值的時候,採用類似於絕對損失的線性損失:

    這裏看一下huber loss的函數圖像:

    就是一個平方損失,一個線性損失。

然後看一下平方損失,絕對損失,huber損失對於異常值的容忍程度:

CART回歸樹分裂思路(可不看)

其實這個問題看起來問的不明所以,其實是問你決策樹如何選擇特徵的。從上面的例子可以看出來,GDBT應該是處理回歸問題的(處理連續數據的)。當然,GDBT也有辦法處理分類問題,只是這裏就不說了,這裏主要說GDBT怎麼處理回歸問題的,回歸問題能處理,那麼總有回歸離散化的辦法的

這個問題是在問:CART TREE如何選擇特徵的CART TREE就是回歸決策樹,就是之前提到的弱分類器。

一個決策樹,希望讀者已經有一個大概的理解了。簡單說就是:樣本可以根據的特徵A是否超過某一個閾值劃分成兩部分,然後劃分之後的每一個部分又可以根據某一個特徵是否超過某一個閾值再分成兩部分……

這樣我們就要做出選擇了:每一個部分是根據哪一個特徵去劃分?根據這個特徵的哪一個數值作為閾值劃分?

如果我們算力無窮,那麼自然可以遍歷每一個特徵,然後窮舉每一種可能的分割點,然後對比找到最優分割點。

那麼如何判斷分割的點的好壞呢?得給出一個cost函數,或者叫做loss函數這樣的東西吧。

\(loss= \sum_{第一部分}{(y_i-me an(y_{第一部分}))^2}+\sum_{第二部分}{(y_i-mean(y_{第二部分}))^2}\)

看一下這個公式,我把公式寫的太丑了。其實這個公式非常的好理解:現在根據某一個特徵值,根據某一個閾值把樣本分成了兩個部分:第一部分和第二部分。然後計算每一個部分的樣本的label的均值,也就是公式中的:\(mean(y_{第一部分})\),\(mean(y_{第二部分})\),然後計算第一部分中所有樣本的label與第一部分label均值之間的差的平方和,同樣的過程計算第二個部分的,兩個相加起來就是這個loss。選擇能夠讓這個loss最小的分割特徵和分割閾值,就是我們要找的東西。

其實我在學這一塊的時候,發現這個過程像是什麼?像不像聚類算法,通過上面的loss的最小化的過程,把一堆樣本分成兩類,讓兩類的類內距離最小。那個均值就像是求類中心點,計算每一個label距離類中心點的距離。(這一段看不懂也沒事

喜歡的話請關注我們的微信公眾號~【你好世界煉丹師】。

  • 公眾號主要講統計學,數據科學,機器學習,深度學習,以及一些參加Kaggle競賽的經驗。
  • 公眾號內容建議作為課後的一些相關知識的補充,飯後甜點。
  • 此外,為了不過多打擾,公眾號每周推送一次,每次4~6篇精選文章。

微信搜索公眾號:你好世界煉丹師。期待您的關注。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準

分類
發燒車訊

氣候暖化影響冬眠 俄羅斯小獾提早甦醒

摘錄自2020年2月13日公視報導

受到暖冬影響,冬眠的動物提早甦醒,像是在俄羅斯,動物園裡的獾原本應該睡到月底,卻在月初就爬起來玩。

在俄羅斯西伯利亞城市伊爾庫茨克的動物園,發現有兩隻獾,在二月的第一週就醒來一起玩,牠們去年這時候還在冬眠,當時還跟往年作息一樣,睡到月底。助理獸醫史達茲卡雅表示:「牠們都是小獾,也就是新生代。成年的獾都還在睡覺,牠們冬眠會比較久。」

這個月10號,當地氣溫攝氏兩度,但去年的同一天,氣溫為零下24度。此外,動物園內這隻名為藍波的刺蝟,也在上週跑出來活動,園方表示,通常這表示春天就快到了,史達茲卡雅說:「動物比我們的感覺還要強,牠們更能適應大自然的改變,牠們也會比較早感覺得到。」

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準

分類
發燒車訊

研究:為躲避赤道高溫 海洋生物逐漸往極地方向移動

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

新北清潔公司,居家、辦公、裝潢細清專業服務

※教你寫出一流的銷售文案?

分類
發燒車訊

颱風哈吉貝襲日滿月 農林漁損恐直逼西日本豪雨

摘錄自2019年11月12日中央社報導

颱風哈吉貝10月12日侵襲日本,到12日屆滿1個月,目前已知至少造成90人死亡、5人失蹤,目前掌握農林漁業損失已逾2200億日圓,未來可能直逼2018年西日本豪雨的逾3000億日圓。

哈吉貝10月12日從日本伊豆半島登陸侵襲東日本地區,日本經濟新聞報導,目前已知至少造成90人死亡、5人失蹤,將近300條河川流經區域發生水災,逾9萬棟民宅受災;如果從發生884起土石災害來看,這是從1982年以來,單一個颱風所造成的最慘重災情。

日本總務省消防廳表示,截至11日為止,全損或半損民宅超過1萬1000棟,淹水超過一樓地板高度的民宅超過3萬1000棟。

日本內閣府表示,截至8日為止,仍有約2800人在避難所生活,且還有不少人因為家中受災,只能暫時借住在親戚家中。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準

分類
發燒車訊

廢棄漁網危環境 芬蘭展開回收計畫

摘錄自2019年12月11日公視報導

廢棄漁網在全球海洋塑膠垃圾裡就占了十分之一,尤其有著悠久漁業傳統的波羅的海,更是受到漁網的嚴重污染,現在芬蘭當局推出了一項環保計畫,希望利用特殊的吊鉤裝置,把波羅的海的海床裡的魚網都清乾淨。

根據聯合國統計,像這樣廢棄的漁網,佔了全球污染海洋塑膠量的十分之一。位於中歐和北歐之間的波羅的海非常繁忙,有著悠久的漁業傳統,同時也受到廢棄魚網嚴重污染。要找回這些海中的漁網可不簡單,因為它們在海面下幾乎看不見,所以又被稱作「鬼網」。

經過數個月的研究,這支芬蘭團隊利用特別設計的漁網釣鉤,在盡量不影響海床的前提下,在有問題的海域拖行,捕撈廢棄漁網,過程既辛苦又緩慢。過去三個星期,他們拖行了300公里的海床,收回共約1000公尺長的漁網。

芬蘭環境研究所資深科學家佩卡指出,「周邊這些海域,問題沒有波羅的海南部那麼嚴重,如果我們到瑞典沿岸就可看見,那裡問題比這裡嚴重許多。」

在幾個星期之內,團隊將決定是否遠征,前往芬蘭以外的海域捕撈廢棄漁網。研究人員指出,會出現這項計畫,代表愈來愈多國家終於意識到「鬼網」所帶來的環境問題。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

新北清潔公司,居家、辦公、裝潢細清專業服務

※教你寫出一流的銷售文案?

分類
發燒車訊

中國出臺新能源汽車補貼新政 純電動汽車直補6萬

9月17日,中國財政部、科技部、工信部、發改委聯合出臺的《關于繼續開展新能源汽車推廣應用工作的通知》(以下簡稱“通知”), 新能源家用汽車每臺直補3.5萬~6萬元(人民幣),被經濟界稱為“節能家電補貼”嫁接出了新能源汽車版。

同時,今年購買新能源汽車將最為實惠。2014年、2015年,會按照補貼標準依次下降補貼10%、20%。此次“通知”補貼的主要范疇為純電動乘用車、插電式混合動力(含增程式)乘用車、純電動專用車、燃料電池汽車四類。相比2010年4部委首次頒布的“新能源汽車補貼標準”,“通知”的最大特點是對全國普惠、優化補貼流程,並兼顧惠及生產、銷售、消費三方利益。

一步到位的購車補貼流程對消費市場是重大利好,消費者到4S店購車,即可從車款中直接減掉對應的補貼款。此後,由中央財政與車企完成結算。同時,“通知”也採取了分級補貼的形式:純電動汽車續航裏程在80~150公裏補貼3.5萬元/臺;150~250公裏補貼5萬元/臺;250公裏以上補貼6萬元/臺。插電式混合動力(含增程式)乘用車,一次直補3.5萬元。

但是,也許政策補貼可讓純電動汽車裸車購買價更低,但其綜合經濟性並不能完全超過傳統汽車。由於購車價格較高,充電不方便,以及消費者對於新能源汽車的安全係數與技術問題的擔憂,導致目前新能源汽車在中國仍沒有很大的需求。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準

分類
發燒車訊

截至9月底 日產Leaf全球累計銷量83,000台

日本汽車大廠日產汽車(Nissan)昨(8)日發布新聞稿稱,旗下全球首款量產型電動車「Leaf」於全球各個市場的銷售氣勢持續高漲,截至2013年9月底為止,Leaf全球累計銷售量達83,000台,9月Leaf全球銷售量更高達4,700台、創史上最高單月銷售紀錄。另外,截至9月底為止,Leaf於日本市場的累計銷售量達30,000台。

日產表示,Leaf於2010年10月搶先於日本/北美市場開賣,且銷售量逐年增長,其中2012年度Leaf於日本市場的銷售量就達11,600台、且預估今年度(2013年度)日本市場銷售量可望更優於2012年度水準。

為了加快電動車的普及速度,日產還計劃於2013年度下半年內(2013年10月-2014年3月)追加於日本國內的日產銷售通路增設700座快速充電器。目前日本全國的快速充電器數量總計約1,900座,其中約800座設置在日產的銷售通路。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

新北清潔公司,居家、辦公、裝潢細清專業服務

※教你寫出一流的銷售文案?