僅需10分鐘:開啟你的機器學習之路

2021-01-11 機器之心Pro

機器學習之路雖漫漫無垠,但莘莘學子依然紛紛投入到機器學習的洪流中。如何更有效地開始機器學習呢?所謂「八仙過海,各顯神通」,本文作者以Python語言為工具進行機器學習,並以Kaggle競賽中的鐵達尼號項目進行詳細解讀。跟著小編來看看吧!

隨著行業內機器學習的崛起,能夠幫用戶快速迭代整個過程的工具變得至關重要。Python,機器學習技術領域冉冉升起的一顆新星,往往是帶你走向成功的首選。因此,用 Python 實現機器學習的指南是非常必要的。

用 Python 實現機器學習的介紹

那麼為什麼是 Python 呢?根據我的經驗,Python 是最容易學習的程式語言之一。現在需要快速迭代整個過程,與此同時,數據科學家不需要深入了解這種語言,因為他們可以快速掌握它。

有多容易呢?

for anything in the_list:print(anything)

就這麼容易。Python 的語法和英語(或人類語言,而不是機器語言)語法關係密切。在 Python 的語法中沒有愚蠢的大括號造成的困擾。我有一個從事質量保證(Quality Assurance)工作的同事,雖然不是軟體工程師,但她可以在一天內寫出產品級的 Python 代碼。(真的!)

我將在下文中介紹幾個基於 Python 的庫。作為數據分析師和數據科學家,我們可以利用他們的傑作來幫助我們完成任務。這些不可思議的庫是用 Python 實現機器學習的必備工具。

NumPy

這是一個非常有名的數據分析庫。從計算數據分布的中位數,到處理多維數組,NumPy 都可以幫你完成。

Pandas

這是用來處理 CSV 文件的。當然了,你還需要處理一些表格、查看統計數據等,那 Pandas 就是可以滿足你的需求的工具。

Matplotlib

把數據存儲在 Pandas 的數據框後,你可能需要做一些可視化來理解數據的更多信息。畢竟一圖抵千言。

Seaborn

這是另一個可視化工具,但這個工具更側重於統計結果的可視化,比如直方圖、餅圖、曲線圖或相關性表等。

Scikit-Learn

這是用 Python 實現機器學習的終極工具。所謂用 Python 實現機器學習指的就是這個——Scikit-Learn。所有你需要的從算法到提升的內容都能在這裡找到。

Tensorflow 和 Pytorch

針對這兩個工具我不會說太多。但如果你對深度學習感興趣的話,可以詳細了解一下,它們值得你花時間去學習。(我下次會再寫一篇關於深度學習的教程,敬請期待!)

Python 機器學習項目

當然,只是閱讀和學習是沒法讓你達成心願的。你需要實際練習。正如我博客中所說的,如果你沒有深入數據的話,那學習這些工具將毫無意義。因此,我在這裡介紹一個可以輕鬆找到 Python 機器學習項目的地方。

博客地址:https://thedatamage.com/

Kaggle 是一個可以直接研究數據的平臺。你可以在這個平臺中解決一些項目,並達到真的擅長機器學習的地步。你可能更感興趣另外一些東西——Kaggle 舉辦的機器學習競賽,獎金高達 100,000 美元。你可能會想著碰碰運氣,哈哈。

Kaggle:https://www.kaggle.com/

但最重要的並不是錢——你真的可以在這裡找到用 Python 實現的機器學習項目。你可以試著完成很多項目。但如果你是個新手,你可能會想參加這項競賽。

我們將在後面的教程中用到一個示例項目:

泰坦尼克:從災難中進行機器學習(https://www.kaggle.com/c/titanic)

這就是眾所周知的鐵達尼號。這是一場發生在 1912 年的災難,這場災難波及到的乘客和機組成員共 2224 人,其中 1502 人遇難死亡。這項 Kaggle 競賽(或者說是教程)提供了災難中的真實數據。你的任務是解釋這些數據,並預測出災難中哪些人會活下來,哪些人不會。

用 Python 實現機器學習的教程

在深入了解鐵達尼號的數據之前,我們要先安裝一些必需的工具。

首先當然是 Python。第一次安裝 Python 需要從官網上安裝。你要安裝 3.6 以上的版本,這樣才能跟最新版本的庫保持同步。

Python 官方網站:https://www.python.org/downloads/

然後可以用 Python 的 pip 安裝所有的庫。你剛剛下載的 Python 發行版會自動安裝 pip。

需要的其他工具都可以用 pip 安裝。打開終端、命令行或 PowerShell,命令如下:

pip install numpypip install pandaspip install matplotlibpip install seabornpip install scikit-learnpip install jupyter

看起來一切都運行良好。但是等一下,什麼叫 jupyter?jupyter 表示 Julia、Python 和 R,因此它實際上是 Jupytr。但這個單詞看起來太奇怪了,所以他們把它變成了 Jupyter。這是一個很有名的筆記本,你可以在這個筆記本上寫交互式的 Python 代碼。

只要在終端中輸入 jupyter notebook,就可以打開如下圖所示的瀏覽器頁面:

你可以把代碼寫在綠色矩形中,而且可以交互式地編寫並評價 Python 代碼。

現在你已經安裝了所有的工具。我們開始吧!

數據探索

探索數據是第一步。你需要從 Kaggle 的 Titanic 頁面下載數據,然後將下載的數據放到你啟動 Jupyter 筆記本的文件夾中。

數據下載地址:https://www.kaggle.com/c/titanic/data

然後導入必要的庫:

import numpy as np import pandas as pdimport matplotlib.pyplot as pltimport seaborn as snsimport warningswarnings.filterwarnings('ignore')%matplotlib inline

載入數據:

train_df=pd.read_csv("train.csv")train_df.head()

輸出如下:

這就是我們的數據。它有下面幾列:

PassengerId,乘客的標識符;Survived,他(她)是否存活了下來;Pclass,艙室類別,也許 1 表示經濟艙,2 表示商務艙,3 表示頭等艙;Name,乘客的名字;Sex,性別;Age,年齡;SibSp,即兄弟姐妹(siblings)或配偶(spouses),表示在船上的兄弟姐妹以及配偶的數目;Parch,即父母(Parents)或子女(Children),表示在船上的父母和子女的數目;Ticket,船票詳情;Cabin,艙號,NaN 表示未知;Embarked,登船的起始地,S 表示南安普頓(Southampton),Q 表示皇后鎮(Queenstown),C 表示瑟堡(Cherbourg)在探索數據時,常常會遇到數據缺失的問題。我們來看一下

def missingdata(data):total = data.isnull().sum().sort_values(ascending = False) percent = (data.isnull().sum()/data.isnull().count()*100).sort_values(ascending = False) ms=pd.concat([total, percent], axis=1, keys=['Total', 'Percent']) ms= ms[ms["Percent"] > 0] f,ax =plt.subplots(figsize=(8,6)) plt.xticks(rotation='90') fig=sns.barplot(ms.index, ms["Percent"],color="green",alpha=0.8) plt.xlabel('Features', fontsize=15) plt.ylabel('Percent of missing values', fontsize=15) plt.title('Percent missing data by feature', fontsize=15) return msmissingdata(train_df)

我們會看到這樣的結果:

艙號、年齡以及登船地的數據都有一些缺失值,而艙號信息有大量的缺失。我們需要對它們進行處理,也就是所謂的數據清理(Data Cleaning)。

數據清理

我們 90% 的時間都花在這上面。我們要針對每一個機器學習項目進行大量的數據清理。當數據清理乾淨時,我們就可以輕鬆地進行下一步了,什麼都不用擔心。

數據清理中最常用的技術是填充缺失數據。你可以用眾數、平均數或中位數來填充缺失數據。選擇這些數據沒有絕對規則,你可以一一嘗試,然後看看它們的表現如何。但是根據經驗來講,分類數據只能用眾數,連續數據可以用中位數或平均數。所以我們用眾數來填充登船地數據,用中位數來填充年齡數據。

train_df['Embarked'].fillna(train_df['Embarked'].mode()[0], inplace = True)train_df['Age'].fillna(train_df['Age'].median(), inplace = True)

接下來的重要操作是刪除數據,尤其針對大量缺失的數據。我們針對艙號數據進行以下處理:

drop_column = ['Cabin']train_df.drop(drop_column, axis=1, inplace = True)

現在檢查一下清理過的數據。

print('check the nan value in train data')print(train_df.isnull().sum())

完美!沒有任何缺失數據了!這表示數據已經清理乾淨了。

特徵工程

現在數據已經清理乾淨了。接下來我們要進行特徵工程。

特徵工程基本上就是根據當前可用數據發現特徵或數據的技術。有幾種方法可以實現這種技術。在很多時候這都是常識。

我們以登船地數據為例——這是用 Q、S 或 C 填充的數據。Python 庫不能處理這個,因為它只能處理數字。所以你需要用所謂的獨熱向量化(One Hot Vectorization)來處理,它可以把一列變成三列。用 0 或 1 填充 Embarked_Q、Embarked_S 和 Embarked_C,來表示這個人是不是從這個港口出發的。

再以 SibSp 和 Parch 為例。這兩列沒有什麼有趣的,但是你可能會想知道某個乘客有多少家人登上了這艘船。如果家人多的話可能會增加生存機率,因為他們可以互相幫助。從另一個角度說,單獨登船的乘客可能很難生存下去。

因此你可以創建新的一列,這一列是成員數量(family size),family size = SibSp + Parch + 1(乘客自己)。

最後一個例子是以 bin 列為例的。由於你認為很難區分具有相似值的事物,所以這種操作創建了值範圍(ranges of values),然後將多個值組合在一起。比如,5 歲和 6 歲的乘客之間有顯著的差異嗎?或者 45 和 46 歲的人之間有顯著的差異嗎?

這就是創建 bin 列的原因。也許就年齡而言,我們可以創建 4 列——幼兒(0~14 歲)、青少年(14~20 歲)、成年人(20~40 歲)以及年長的人(40 歲以上)。

編碼如下:

all_data = train_dffor dataset in all_data :dataset['FamilySize'] = dataset['SibSp'] + dataset['Parch'] + 1import re# Define function to extract titles from passenger namesdef get_title(name): title_search = re.search(' ([A-Za-z]+).', name) # If the title exists, extract and return it. if title_search: return title_search.group(1) return ""# Create a new feature Title, containing the titles of passenger namesfor dataset in all_data: dataset['Title'] = dataset['Name'].apply(get_title)# Group all non-common titles into one single grouping "Rare"for dataset in all_data: dataset['Title'] = dataset['Title'].replace(['Lady', 'Countess','Capt', 'Col','Don', 'Dr', 'Major', 'Rev', 'Sir', 'Jonkheer', 'Dona'], 'Rare')dataset['Title'] = dataset['Title'].replace('Mlle', 'Miss') dataset['Title'] = dataset['Title'].replace('Ms', 'Miss') dataset['Title'] = dataset['Title'].replace('Mme', 'Mrs')for dataset in all_data: dataset['Age_bin'] = pd.cut(dataset['Age'], bins=[0,14,20,40,120], labels=['Children','Teenage','Adult','Elder'])for dataset in all_data: dataset['Fare_bin'] = pd.cut(dataset['Fare'], bins=[0,7.91,14.45,31,120], labels ['Low_fare','median_fare', 'Average_fare','high_fare'])traindf=train_dffor dataset in traindf: drop_column = ['Age','Fare','Name','Ticket'] dataset.drop(drop_column, axis=1, inplace = True)drop_column = ['PassengerId']traindf.drop(drop_column, axis=1, inplace = True)traindf = pd.get_dummies(traindf, columns = ["Sex","Title","Age_bin","Embarked","Fare_bin"], prefix=["Sex","Title","Age_type","Em_type","Fare_type"])

現在,你已經創建完成所有的特徵了。接著我們看看這些特徵之間的相關性:

sns.heatmap(traindf.corr(),annot=True,cmap='RdYlGn',linewidths=0.2) #data.corr()-->correlation matrixfig=plt.gcf()fig.set_size_inches(20,12)plt.show()

相關值接近 1 意味著高度正相關,-1 意味著高度負相關。例如,性別為男和性別為女之間就呈負相關,因為必須將乘客識別為一種性別(或另一種)。此外,你還可以看到,除了用特徵工程創建的內容外,沒有哪兩種是高度相關的。這證明我們做得對。

如果某些因素之間高度相關會怎麼樣?我們可以刪除其中的一個,新列中的信息並不能給系統提供任何新信息,因為這兩者是完全一樣的。

用 Python 實現機器學習

現在我們已經到達本教程的高潮——機器學習建模。

from sklearn.model_selection import train_test_split #for split the datafrom sklearn.metrics import accuracy_score #for accuracy_scorefrom sklearn.model_selection import KFold #for K-fold cross validationfrom sklearn.model_selection import cross_val_score #score evaluationfrom sklearn.model_selection import cross_val_predict #predictionfrom sklearn.metrics import confusion_matrix #for confusion matrixall_features = traindf.drop("Survived",axis=1)Targeted_feature = traindf["Survived"]X_train,X_test,y_train,y_test = train_test_split(all_features,Targeted_feature,test_size=0.3,random_state=42)X_train.shape,X_test.shape,y_train.shape,y_test.shape

Scikit-Learn 庫中有多種算法供你選擇:

邏輯回歸隨機森林支持向量機K 最近鄰樸素貝葉斯決策樹AdaBoostLDA梯度增強你可能感到不知所措,想弄清什麼是什麼。別擔心,只要將它當做「黑箱」對待就好——選一個表現最好的。(我之後會寫一篇完整的文章討論如何選擇這些算法。)

以我最喜歡的隨機森林算法為例:

from sklearn.ensemble import RandomForestClassifiermodel = RandomForestClassifier(criterion='gini', n_estimators=700,min_samples_split=10,min_samples_leaf=1, max_features='auto',oob_score=True, random_state=1,n_jobs=-1)model.fit(X_train,y_train)prediction_rm=model.predict(X_test)print('----The Accuracy of the model---')print('The accuracy of the Random Forest Classifier is', round(accuracy_score(prediction_rm,y_test)*100,2))kfold = KFold(n_splits=10, random_state=22) # k=10, split the data into 10 equal partsresult_rm=cross_val_score(model,all_features,Targeted_feature,cv=10,scoring='accuracy')print('The cross validated score for Random Forest Classifier is:',round(result_rm.mean()*100,2))y_pred = cross_val_predict(model,all_features,Targeted_feature,cv=10)sns.heatmap(confusion_matrix(Targeted_feature,y_pred),annot=True,fmt='3.0f',cmap="summer")plt.title('Confusion_matrix', y=1.05, size=15)

哇哦!準確率高達 83%。就第一次嘗試而言,這個結果已經很好了。

交叉驗證分數的意思是 K 折驗證方法。如果 K=10,就是說要把數據分成 10 個變量,計算所有分數的均值,並將它們作為最終分數。

微調

現在你已經完成了用 Python 實現機器學習的步驟。但再加一個步驟可以讓你得到更好的結果——微調。微調的意思是為機器學習算法找到最佳參數。以上面的隨機森林代碼為例:

model = RandomForestClassifier(criterion='gini', n_estimators=700,min_samples_split=10,min_samples_leaf=1, max_features'auto',oob_score=True, random_state=1,n_jobs=-1)

你需要設置許多參數。順便說一下,上面的都是默認值。你可以根據需要改變參數。但當然了,這需要花費很多時間。

別擔心——有一種叫做網格搜索(Grid Search)的工具,它可以自動找出最佳參數。聽起來還不錯,對吧?

# Random Forest Classifier Parameters tunning model = RandomForestClassifier()n_estim=range(100,1000,100)## Search grid for optimal parametersparam_grid = {"n_estimators" :n_estim}model_rf = GridSearchCV(model,param_grid = param_grid, cv=5, scoring="accuracy", n_jobs= 4, verbose = 1)model_rf.fit(train_X,train_Y)# Best scoreprint(model_rf.best_score_)#best estimatormodel_rf.best_estimator_

好了,你可以自己嘗試一下,並從中享受機器學習的樂趣。

總結

怎麼樣?機器學習看起來似乎並不難吧?用 Python 實現機器學習很簡單。一切都已經為你準備好了。你可以做一些神奇的事,並給人們帶來快樂。

相關焦點

  • 給新冠病毒分類 機器學習僅需幾分鐘
    據物理學家組織網28日報導,加拿大計算機科學家和生物學家在當日出版的《科學公共圖書館·綜合》(PLOS ONE)雜誌撰文指出,他們藉助機器學習方法,在短短幾分鐘內對29個不同新冠病毒DNA序列進行分類,鑑定出一個潛在的「基因籤名」。
  • 二戰時圖靈機破譯的Enigma密碼,現在AI僅需13分鐘便可破譯
    原標題:二戰時圖靈機破譯的Enigma密碼,現在AI僅需13分鐘便可破譯 >,破譯仍需要數年的時間,而DigitalOcean及Enigma Pattern公司發明的AI技術,僅需
  • 快速充電僅需30分鐘 充一次電可以跑一星期!僅10萬
    隨著目前汽車市場電動汽車的不斷普及,越來越多的合資與自主車企加入了純電動汽車的行列,比亞迪,作為一家電池起家的企業,在新能源汽車領域一直扮演著「老大哥」的角色,為了迎合國人的消費習慣,比亞迪推出了一款價格區間在10萬元的小型純電動SUV——比亞迪元EV360,而且它的最高續航裡程可達
  • 五分鐘向長輩解釋機器學習,這樣最通俗!
    全文共2746字,預計學習時長5分鐘什麼是機器學習呢?如果是對此一竅不通的長輩來問你這個問題,你該如何回答?本文將用最簡單的詞彙來嘗試解釋這一話題,包括每個人都應該知道的最主要也是最重要的部分。再比如說,機器學習在自動駕駛汽車上發揮著重要作用。汽車會收集大量的數據來學習怎樣開得更好更安全。顯而易見的是,機器學習將在未來的生活中扮演重要的角色。機器學習不是什麼首先,機器學習並不是像你在電影中看到的那樣,機器人想要摧毀人類。
  • 利用機器學習破解網站驗證碼 只需15分鐘
    15分鐘內,能否徹底破解這個驗證碼系統?擦亮眼睛看吧!  重要提示:這絕不是對該插件或其作者的挑釁或某種程度上的鄙視。插件作者自己也說它已經不安全了,建議你使用其他東西。  目前記時:2分鐘  我們的工具集  在我們進一步討論之前,先來羅列一下解決這個問題的工具:  Python 3  Python是一種很有趣的程式語言,有很好的機器學習和計算機視覺庫。
  • 五分鐘了解機器學習十大算法
    本文為有志於成為數據科學家或對此感興趣的讀者們介紹最流行的機器學習算法。機器學習是該行業的一個創新且重要的領域。我們為機器學習程序選擇的算法類型,取決於我們想要實現的目標。現在,機器學習有很多算法。因此,如此多的算法,可能對於初學者來說,是相當不堪重負的。
  • 紅豆總是煮不熟,教你一招,僅需7分鐘就可以,看完後告訴身邊人
    紅豆總是煮不熟,教你一招,僅需7分鐘就可以,看完後告訴身邊人!天氣越來越冷,喝上一碗粥,暖和一整天,特別是在我們北方,一天基本上都少不了粥,那麼我們在煮粥的時候,肯定是少不了放紅豆的,不知道大家有沒有發現,我們在煮粥的時候,粥已經煮好,但是裡面的紅豆卻不熟,當然很多人也感覺非常大煩惱,教你一招,僅需七分鐘就可以將紅豆給煮熟了。
  • 入門| 機器學習新手必看10大算法
    參與:程耀彤、路雪 本文介紹了機器學習新手需要了解的 10 大算法,包括線性回歸、Logistic 回歸、樸素貝葉斯、K 近鄰算法等。 因此,你應該針對具體問題嘗試多種不同算法,並留出一個數據「測試集」來評估性能、選出優勝者。 當然,你嘗試的算法必須適合你的問題,也就是選擇正確的機器學習任務。打個比方,如果你需要打掃房子,你可能會用吸塵器、掃帚或拖把,但是你不會拿出鏟子開始挖土。
  • 流行的機器學習算法總結,幫助你開啟機器學習算法學習之旅
    機器學習算法概述「機器智能是人類永遠需要的一項發明。」— Nick Bostrom.如果您可以回顧幾年前的AI並將其與現在的AI進行比較,您會驚訝地發現AI的發展速度隨著時間的增長呈指數級增長。它已擴展到各種領域,例如ML,Expert Systems,NLP等數十個領域。
  • 觀致MILE1續航可達600公裡,充電僅需15分鐘,就可以充滿80%電量
    觀致MILE1續航可達600公裡,充電僅需15分鐘,就可以充滿80%電量車友朋友們,大家上午好。3月份已經進入下半月,那麼春天萬物甦醒,又是旅遊出行好時節。自駕遊的愛好者,一般都是獨立的人格,嗅覺也是十分精準。
  • 宇通燃料電池車加氫僅10分鐘 續航600km
    場長導讀:宇通正式亮相的第三代燃料電池客車融合宇通睿控技術,實現了氫燃料加注時間僅需10分鐘,測試工況下續航裡程較之第二代產品有明顯提升,超過600公裡,尤其是成本下降了50%,加快了燃料電池客車的市場化步伐。
  • Python機器學習10:機器學習中的六種分類算法及實現(上)
    在機器學習中,可以使用多種算法模型解決同一個問題,那麼如何從中選擇出最佳的算法模型呢?當然,這個問題沒有一種固定的答案,需要根據不同的問題,嘗試使用多種機器學習方法,比較各種算法模型在該問題上的效果,最終才能決定究竟選擇哪一種模型。
  • 它花1分鐘,超算需億年
    計算玻色採樣問題,「九章」處理5000萬個樣本只需200秒,而目前世界最快的超算需6億年。這是我國首次實現「量子計算優越性」。眼下,研製量子計算機已是世界科技前沿的最大挑戰之一。未來,「九章」在機器學習、量子化學等領域有潛在應用。近日,中國科學技術大學潘建偉、陸朝陽等學者組成的研究團隊與中國科學院上海微系統所與信息技術研究所、國家並行計算機工程技術研究中心合作,構建了76個光子的量子計算原型機「九章」。
  • 它花1分鐘 超算需億年
    計算玻色採樣問題,「九章」處理5000萬個樣本只需200秒,而目前世界最快的超算需6億年。這是我國首次實現「量子計算優越性」。眼下,研製量子計算機已是世界科技前沿的最大挑戰之一。未來,「九章」在機器學習、量子化學等領域有潛在應用。近日,中國科學技術大學潘建偉、陸朝陽等學者組成的研究團隊與中國科學院上海微系統所與信息技術研究所、國家並行計算機工程技術研究中心合作,構建了76個光子的量子計算原型機「九章」。
  • 流放之路S11賽季什麼時候開始 S11賽季開啟時間
    流放之路S11賽季什麼時候開始 S11賽季開啟時間 流放之路馬上S10賽季就要結束了,所以很多玩家都想知道S11賽季到底什麼時候開始,下面就來為大家詳細的介紹一下。
  • 10大機器學習算法,看懂你就是數據科學家
    你得是個博聞強識,又對新鮮事物保持好奇心的人。正因為如此,數據科學家會掌握幾乎所有的常見算法,並精通其中一門,這樣可以快速適應新領域的問題。今天我們就來聊聊,每一位數據科技家都應該了解的10大機器學習算法。下面是關於普遍機器學習算法和快速資源的風暴之旅,準好了嗎?燒腦挑戰開始: 1.
  • 分享最適合新手入門的10種機器學習算法
    最常見的機器學習類型是學習映射Y=f(X),用它來預測Y的值。這被稱為預測建模或預測分析,我們的目標是做出最準確的預測。 對於想了解機器學習基礎知識的新手,以下是數據科學家最常用的10種機器學習算法。 1.線性回歸 線性回歸也許是數據科學和機器學習中最知名、最好理解的算法了吧。
  • 選機器學習課程怕踩雷?有人幫你選出了top 5優質課
    課程提供者:吳恩達,史丹福大學費用:免費;如需課程證書,則需 79 美元課程結構:單變量線性回歸線性代數概要多變量線性回歸Octave/Matlab 教程Logistic 回歸正則化神經網絡:表徵神經網絡:學習使用機器學習的建議機器學習系統設計支持向量機降維異常檢測推薦系統大規模機器學習應用案例:Photo OCR該課程持續時間為 11 周。
  • 最好的Python機器學習庫
    Python社區所創建的庫可以讓你做任何你想做的事,包括機器學習。豐富的ML庫:目前有大量面向Python的機器學習庫。你可以根據你的使用情況、技術和需求從數百個庫中選擇最合適的一個。上面最後一點可以說是最重要的。
  • 【網信V普法】一起來開啟學習憲法之路啦!(三)
    【網信V普法】一起來開啟學習憲法之路啦!>關於憲法日,你了解多少?>原標題:《【網信V普法】一起來開啟學習憲法之路啦!閱讀原文 特別聲明本文為澎湃號作者或機構在澎湃新聞上傳並發布,僅代表該作者或機構觀點