天天看點

如何建立預估10w+軟文點選率的模型?

作者:大資料與人工智能分享

一個機器學習項目從開始到結束大緻分為 5 步,分别是定義問題、收集資料和預處理、選擇算法和确定模型、訓練拟合模型、評估并優化模型性能。這 5 步是一個循環疊代的過程,你可以參考下面的圖檔:

如何建立預估10w+軟文點選率的模型?

我們所有的項目都會按照這 5 步來做,我把它簡稱為實戰 5 步。

第 1 步 定義問題

我們先來看第一步,定義問題。在定義問題這個環節中,我們要剖析業務場景,設定清晰的目标,同時還要明确目前問題屬于哪一種機器學習類型。如果不搞清楚這些,我們後面就無法選擇模型了。

是以首先,我們先得來了解一下我們這個項目的業務場景。假設你已經入職了“易速鮮花”的營運部,正在對微信公衆号推廣文案的營運效率進行分析。你收集了大量的軟文資料,包括點贊數、轉發數和浏覽量等等,就像下面這樣:

如何建立預估10w+軟文點選率的模型?

因為微信公衆号閱讀量超過 10 萬之後,就不能顯示它的具體閱讀量了。是以針對這個問題,我們項目的目标就是,建立一個機器學習模型,根據點贊數和轉發數等名額,估計一篇文章能實作多大的浏覽量。

因為要估計浏覽量,是以在這個資料集中:點贊數、轉發數、熱度指數、文章評級,這 4 個字段都是特征,浏覽量就是标簽。這裡我們已經有要估計的标簽了,是以這是一個監督學習問題。再加上我們的标簽是連續性的數值,是以它是一個回歸問題。

不難看出,在這個資料集中,特征和标簽之間明顯呈現出一種相關性:點贊數、轉發數多的時候,往往浏覽量也多。但是,這種相關性可以通過哪個具體的函數來描繪呢?目前我們還不知道,是以我們在這個項目中的任務就是找到這個函數。

這樣,我們就已經把問題定義好了,緊接着下一步就是資料收集和預處理。

第 2 步 收集資料和預處理

資料的收集和預處理”在所有機器學習項目中都會出現,它的作用是為機器學習模型提供好的燃料。資料好,模型才跑得更帶勁。這步驟看似隻有一句話,其實裡面包含了好幾個小步驟,完整來講有 6 步:

①收集資料;

②資料可視化;

③資料清洗;

④特征工程;

⑤建構特征集和标簽集;

⑥拆分訓練集、驗證集和測試集。

你可能一眼看上去不太明白這 6 個步驟的意思。不要着急,接下來我會挨個解釋。

1.收集資料

首先是收集資料,這一步又叫采集資料。在現實中,收集資料通常很辛苦,要在營運環節做很多資料埋點、擷取使用者消費等行為資訊和興趣偏好資訊,有時候還需要上網爬取資料。有了資料集,接下來我們要做的是資料可視化的工作,也就是通過可視化去觀察一下資料,為選擇具體的機器學習模型找找感覺。

2.資料可視化

# 首先安裝 
pip3.10 install jupyter

# 運作
jupyter notebook           

資料可視化是個萬金油技能,能做的事非常多。比如說,可以看一看特征和标簽之間可能存在的關系,也可以看看資料裡有沒有“髒資料”和“離群點”等。

不過在正式可視化之前,我們需要把收集到的資料導入運作環境。資料導入我們需要用到 Pandas 資料處理工具包。這個包可是操作資料的利器,我們未來每個項目中都會用到。現在我們用 import 語句導入它:

# 導入最基本的資料處理工具
import pandas as pd # 導入Pandas資料處理工具包           

然後,我們通過下面的代碼把這個項目的資料集讀入到 Python 運作環境,用 DataFrame 的形式呈現出來:

df_ads = pd.read_csv('xxx微信軟文.csv') # 讀入資料
df_ads.head() # 顯示前幾行資料           

DataFrame 是機器學習中常見的二維表格類型資料結構。在上面的代碼中,我用 read_csv API 把 CSV 格式的資料檔案,讀入到 Pandas 的 DataFrame 中,把它命名為了 df_ads。這段代碼輸出如下:

如何建立預估10w+軟文點選率的模型?

這樣就完成了資料的導入了,接着我們就可以正式進入“可視化”了。根據經驗,我們猜測“點贊數”最有可能和“浏覽量”之間存線上性關系。那是不是真的這樣呢?我們可以畫出圖來驗證一下。

在這個“驗證”環節中,我們需要用到兩個包:一個是 Python 畫圖工具庫“Matplotlib ”,另一個是統計學資料可視化工具庫“Seaborn”。這兩個包都是 Python 資料可視化的必備工具包,它們是 Anaconda 預設安裝包的一部分,不需要 pip install 語句重複安裝。

在導入這兩個包時,我們依舊用 import 語句。請你注意,為了節省代碼量,我并沒有導入完整的 matplotlib 包,而是隻導入了 matplotlib 包中的繪圖子產品 pyplot:

#導入資料可視化所需要的庫
import matplotlib.pyplot as plt # Matplotlib – Python畫圖工具庫
import seaborn as sns # Seaborn – 統計學資料可視化工具庫           

因為線性關系可以簡單地用散點圖來驗證一下。是以下面我們用 matplotlib 包中的 plot API,繪制出“點贊數”和“浏覽量”之間的散點圖,看看它們的分布狀态。

plt.plot(df_ads['點贊數'],df_ads['浏覽量'],'r.', label='Training data') # 用matplotlib.pyplot的plot方法顯示散點圖
plt.xlabel('點贊數') # x軸Label
plt.ylabel('浏覽量') # y軸Label
plt.legend() # 顯示圖例
plt.show() # 顯示繪圖結果!           

輸出的結果如下圖所示:

如何建立預估10w+軟文點選率的模型?

從這張圖中我們可以看出來,這些資料基本上集中在一條線附近,是以它的标簽和特征之間,好像真的存在着線性的關系,這可以為我們将來選模型提供參考資訊。

接下來,我要用 Seaborn 的 boxplot 工具畫個箱線圖。來看看這個資料集裡有沒有“離群點”。我這裡随便選擇了熱度指數這個特征,你也可以為其它特征試試繪制箱線圖。

data = pd.concat([df_ads['浏覽量'], df_ads['熱度指數']], axis=1) # 浏覽量和熱度指數
fig = sns.boxplot(x='熱度指數', y="浏覽量", data=data) # 用seaborn的箱線圖畫圖
fig.axis(ymin=0, ymax=800000); #設定y軸坐标           

下圖就是我們輸出的箱線圖:

如何建立預估10w+軟文點選率的模型?

箱線圖是由五個數值點組成,分别是最小值 (min)、下四分位數 (Q1)、中位數 (median)、上四分位數 (Q3) 和最大值 (max)。在統計學上,這叫做五數概括。這五個數值可以清楚地為我們展示資料的分布和離散程度。

這個圖中下四分位數、中位數、上四分位數組成一個“帶有隔間的盒子”,就是所謂的箱;上四分位數到最大值之間建立一條延伸線,就是所謂的線,也叫“胡須”;胡須的兩極就是最小值與最大值;此外,箱線圖還會将離群的資料點單獨繪出。

在上面這個箱線圖中,我們不難發現,熱度指數越高,浏覽量的中位數越大。我們還可以看到,有一些離群的資料點,比其它的文章浏覽量大了很多,這些“離群點”就是我們說的“爆款文章”了。

到這裡,資料可視化工作算是基本完成了。在資料可視化之後,下一步就是資料的清洗。

3.資料清洗

很多人都把資料清洗比作“炒菜”前的“洗菜”,也就是說資料越幹淨,模型的效果也就越好。清洗的資料一般分為 4 種情況:

第一種是處理缺失的資料。如果備份系統裡面有缺了的資料,那我們盡量補錄;如果沒有,我們可以剔除掉殘缺的資料,也可以用其他資料記錄的平均值、随機值或者 0 值來補值。這個補值的過程叫資料修複。

第二個是處理重複的資料:如果是完全相同的重複資料處理,删掉就行了。可如果同一個主鍵出現兩行不同的資料,比如同一個身份證号後面有兩條不同的位址,我們就要看看有沒有其他輔助的資訊可以幫助我們判斷(如時戳),要是無法判斷的話,隻能随機删除或者全部保留。

第三個是處理錯誤的資料:比如商品的銷售量、銷售金額出現負值,這時候就需要删除或者轉成有意義的正值。再比如表示百分比或機率的字段,如果值大于 1,也屬于邏輯錯誤資料。

第四個是處理不可用的資料:這指的是整理資料的格式,比如有些商品以人民币為機關,有些以美元為機關,就需要先統一。另一個常見例子是把“是”、“否”轉換成“1”、“0”值再輸入機器學習模型。

那麼如何看資料集中有沒有髒資料呢?

就我們這個項目的資料集來說,細心的你可能在 DataFrame 圖中已經發現,行索引為 6 的資料中“轉發數”的值是“NaN”,意思是 Not A Number。在 Python 中,它代表無法表示、也無法處理的值。這是典型的髒資料。

如何建立預估10w+軟文點選率的模型?

我們可以通過 DataFrame 的 isna().sum() 函數來統計所有的 NaN 的個數。這樣,我們就可以在看看有沒有 NaN 的同時,也看看 NaN 出現的次數。如果 NaN 過多的話,那麼說明這個資料集品質不好,就要找找資料源出了什麼問題。

df_ads.isna().sum() # NaN出現的次數           

輸出結果如下:

如何建立預估10w+軟文點選率的模型?
df_ads = df_ads.dropna() # 删除NaN值           

删去了離群點,模型針對普通的資料會拟合得比較漂亮。但是現實生活中,就是存在着這樣的離群點,讓模型不那麼漂亮。如果把這裡的離群點删掉,那模型就不能工作得那麼好了。是以,這是一個平衡和取舍的過程。

我們可以訓練出包含這些離群點的模型,以及不包含這些離群點的模型,并進行比較。在這裡,我建議保留這些“離群點”。

現在,我們就完成了對這個資料的簡單清洗。不同類型的資料有不同的清洗方法,我們這裡就不一一介紹了。後續項目中,針對具體項目和資料集,我們還會再細講的。我們繼續講下一個步驟,把資料轉換成機器所更易于讀取的格式,也就是特征工程。

4.特征工程

特征工程是一個專門的機器學習子領域,而且它是資料處理過程中最有創造力的環節,特征工程做得好不好,非常影響機器學習模型的效率。 我舉個例子來解釋下什麼是特征工程。你知道什麼是 BMI 指數嗎?它等于體重除以身高的平方,這就是一個特征工程。

計算公式 BMI = 體重(kg) ÷ 身高(m)^2           

BMI 這一個指數就替代了原來的兩個特征——體重和身高,而且完全能客觀地描繪我們的身材情況。

是以,經過了這個特征工程,我們可以把 BMI 指數作為新特征,輸入用于評估健康情況的機器學習模型。

你可能會問這樣做的好處是什麼?以 BMI 特征工程為例,它降低了特征資料集的次元。次元就是資料集特征的個數。要知道,在資料集中,每多一個特征,模型拟合時的特征空間就更大,運算量也就更大。是以,摒棄掉備援的特征、降低特征的次元,能使機器學習模型訓練得更快。

這隻是特征工程的諸多的妙處之一,此外特征工程還能更好地表示業務邏輯,并提升機器學習模型的性能。

由于這個項目的問題相對簡單,對特征工程的要求并不高,這裡暫時不做特征工程。下面,直接進入下一個子步驟,也就是建構機器學習的特征集和标簽集。

5.建構特征集和标簽集

特征就是所收集的各個資料點,是要輸入機器學習模型的變量。而标簽是要預測、判斷或者分類的内容。對于所有監督學習算法,我們都需要向模型中輸入“特征集”和“标簽集”這兩組資料。是以,在開始機器學習的模型搭建之前,我們需要先建構一個特征資料集和一個标簽資料集。

具體的建構過程也很簡單,我們隻要從原始資料集删除我們不需要的資料就行了。在這個項目中,特征是點贊數、轉發數、熱度指數和文章評級,是以隻需要從原始資料集中删除“浏覽量”就行了。

X = df_ads.drop(['浏覽量'],axis=1) # 特征集,Drop掉标簽相關字段           

而标簽是我們想要預測的浏覽量,是以,我們在标簽資料集中隻保留“浏覽量”字段:

y = df_ads.浏覽量 # 标簽集           

下面我們再看看特征集和标簽集裡面都有什麼資料。

X.head() # 顯示前幾行資料
y.head() #顯示前幾行資料           

因為 Notebook 一個單元格隻能有一個輸出。是以我把顯示兩個資料的代碼放在了不同的單元格中。它們的輸出結果如下圖所示:

如何建立預估10w+軟文點選率的模型?

可以看到,除了浏覽量之外,所有其它字段仍然都在特征資料集中,而隻有浏覽量被儲存在了标簽資料集中,也就是說原始資料集就被拆分成了機器學習的特征集和标簽集。

無監督學習算法是不需要這個步驟的。因為無監督算法根本就沒有标簽。

不過,從原資料集從列的次元縱向地拆分成了特征集和标簽集後,還需要進一步從行的次元橫向拆分。你可能想問,為啥還要拆分呀?因為機器學習并不是通過訓練資料集找出一個模型就結束了,我們需要用驗證資料集看看這個模型好不好,然後用測試資料集看看模型在新資料上能不能用。

那麼具體該怎麼拆分呢?這就是我們接下來要解決的問題了。

6.拆分訓練集、驗證集和測試集。

在拆分之前,我先說明一點,對于學習型項目來說,為了簡化流程,經常會省略驗證的環節。我們今天的項目比較簡單,是以我們也省略了驗證,隻拆分訓練集和測試集,而此時的測試集就肩負着驗證和測試雙重功能了。

拆分的時候,留作測試的資料比例一般是 20% 或 30%。不過如果你的資料量非常龐大,比如超過 1 百萬的時候,那你也不一定非要留這麼多。一般來說有上萬條的測試資料就足夠了。這裡我會按照 80/20 的比例來拆分資料。具體的拆分,我們會用機器學習工具包 scikit-learn 裡的資料集拆分工具 train_test_split 來完成:

#将資料集進行80%(訓練集)和20%(驗證集)的分割
from sklearn.model_selection import train_test_split #導入train_test_split工具
X_train, X_test, y_train, y_test = train_test_split(X, y, 
                                   test_size=0.2, random_state=0)           

這裡需要注意一下,雖然是随機分割,但我們要指定一個 random_state 值,這樣就保證程式每次運作都分割一樣的訓練集和測試集。訓練集和測試集每次拆分都不一樣的話,那比較模型調參前後的優劣就失去了固定的标準。 現在,訓練集和測試集拆分也完成了,你會發現原始資料現在變成了四個資料集,分别是:

  • 特征訓練集(X_train)
  • 特征測試集(X_test)
  • 标簽訓練集(y_train)
  • 标簽測試集(y_test)

至此,我們全部的資料預處理工作就結束了。

如何建立預估10w+軟文點選率的模型?

第 3 步 選擇算法并建立模型

敬請期待。。。

第 4 步 訓練模型

敬請期待。。。

第 5 步 模型評估和優化

敬請期待。。。

繼續閱讀