一、機器學習的一些概念
-
有監督學習:監督學習是學習給定标簽的資料集,比如說有一組病人,給出他們的詳細資料,将他們是否已确診癌症作為标簽,然後預測一名(其他的)病人是否會患有癌症,就是一種典型的監督學習。監督學習中也有不同的分類,如果我們訓練的結果是得癌症和不得癌症之類離散的類型,則稱為分類(Classification),如果隻有兩種類型的話可以進一步稱為二分類(Binary Classification);如果我們訓練的結果是得癌症的機率為0.87之類連續的數字,則稱為回歸(Regression)
回歸問題往往會通過計算誤差(Error)來确定模型的精确性。誤差由于訓練集和驗證集的不同,會被分為訓練誤差(Training Error)和驗證誤差(Validation Error)。但值得注意的是,模型并不是誤差越小就一定越好,因為如果僅僅基于誤差,我們可能會得到一個過拟合(Overfitting)的模型;但是如果不考慮誤差,我們可能會得到一個欠拟合(Underfitting)的模型
分類問題衡量結果精度的有一些相關術語,首當其沖的是準确率(Accuracy)、精确率(Precision)和召回率(Recall)。這三個詞彙應用于二分類問題:将資料分為正例(Positive Class)和反例(Negative Class),準确率是預測和标簽一緻的樣本在所有樣本中所占的比例;精确率是你預測為正類的資料中,有多少确實是正類;召回率是所有正類的資料中,你預測為正類的資料有多少。這三個資料往往用來衡量一個二分類算法的優劣
-
無監督學習:無監督學習是學習沒有标簽的資料集,比如在分析大量語句之後,訓練出一個模型将較為接近的詞分為一類,而後可以根據一個新的詞在句子中的用法(和其他資訊)将這個詞分入某一類中。其中比較微妙的地方在于,這種問題下使用聚類(Clustering)(方法)所獲得的簇(Cluster)(結果),有時候是無法人為地觀察出其特征的,但是在得到聚類後,可能會對資料集有新的啟發
聚類問題的标準一般基于距離:簇内距離(Intra-cluster Distance)和簇間距離(Inter-cluster Distance)。根據常識而言,簇内距離是越小越好,也就是簇内的元素越相似越好;而簇間距離越大越好,也就是說簇間(不同簇)元素越不相同越好。一般來說,衡量聚類問題會給出一個結合簇内距離和簇間距離的公式。
- 泛化能力:訓練模型會把資料分成三部分 訓練集,交叉驗證集,測試集 ;模型中對新資料的預測能力。在實際中如果對訓練資料能很好的拟合,而對驗證集的效果較差,泛化能力較弱,可能出現過拟合。
-
過拟合和欠拟合:
過拟合:就是訓練時的結果很好,但是在預測時結果不好的情況。
欠拟合:模型沒有很好地捕捉到資料特征,不能夠很好地拟合資料的情況,就是欠拟合。
解決方法:
過拟合:
(1)盡量減少選取變量的數量。
可以人工檢查每一項變量,并确定哪些變量更重要。然後保留那些更重要的特征變量。
可以使用模型選擇算法,通過該算法自動的選擇使用哪些特征變量,舍棄哪些特征變量。
(2)正則化
正則化會保留所有的特征變量,但是會減小特征變量的數量級。
這種方法非常有效,當我們有很多特征變量時,其中每一個特征變量都對預測産生了一些影響。每一個變量都有用,是以我們希望保留所有的變量,這個時候就可以使用正則化的方法。
正則化就是使用懲罰項,通過懲罰項,我們可以将一些參數的值變小。通常參數值越小,對應的函數也就越光滑,也就是更加簡單的函數,是以不容易發生過拟合問題。
(3)資料集擴增(Data augmentation)“有時候不是因為算法好赢了,而是因為擁有更多的資料才赢了。”
(4)dropout
Dropout則是通過修改神經網絡本身來實作的,它是在訓練網絡時用的一種技巧(trike)
(5)重新清洗資料。
導緻過拟合的一個原因也有可能是資料不純導緻的,如果出現了過拟合就需要我們重新清洗資料
欠拟合:
(1)添加其他特征項,有時候我們模型出現欠拟合的時候是因為特征項不夠導緻的,可以添加其他特征項來很好地解決。例如,“組合”、“泛化”、“相關性”三類特征是特征添加的重要手段,無論在什麼場景,都可以照葫蘆畫瓢,總會得到意想不到的效果。除上面的特征之外,“上下文特征”、“平台特征”等等,都可以作為特征添加的首選項。
(2)添加多項式特征,這個在機器學習算法裡面用的很普遍,例如将線性模型通過添加二次項或者三次項使模型泛化能力更強。例如上面的圖檔的例子。
(3)減少正則化參數,正則化的目的是用來防止過拟合的,但是現在模型出現了欠拟合,則需要減少正則化參數。
什麼是Bias(偏差):Bias反映的是模型在樣本上的輸出與真實值之間的誤差,即模型本身的精準度,即算法本身的拟合能力
什麼是Variance(方差):Variance反映的是模型每一次輸出結果與模型輸出期望之間的誤差,即模型的穩定性。反應預測的波動情況。
什麼是Noise(噪聲):這就簡單了,就不是你想要的真正資料,你可以想象為來破壞你實驗的元兇和造成你可能過拟合的原因之一,至于為什麼是過拟合的原因,因為模型過度追求Low Bias會導緻訓練過度,對測試集判斷表現優秀,導緻噪聲點也被拟合進去了
(5)交叉驗證:判斷模型的好和壞,就是衡量模型的(方差+偏差)和的最小值。是以主要的關注點就是平衡Bias和Variance。現在通用的衡量方法采用的是交叉驗證的思想。交叉驗證思想能夠很好的處理方差大和偏差大這兩大痛點,能夠更好的評估模型好壞!
叉驗證的目的:在實際訓練中,模型通常對訓練資料好,但是對訓練資料之外的資料拟合程度差。用于評價模型的泛化能力,進而進行模型選擇。
交叉驗證的基本思想:把在某種意義下将原始資料(dataset)進行分組,一部分做為訓練集(train set),另一部分做為驗證集(validation set or test set),首先用訓練集對模型進行訓練,再利用驗證集來測試模型的泛化誤差。另外,現實中資料總是有限的,為了對資料形成重用,進而提出k-折疊交叉驗證。
對于個分類或回歸問題,假設可選的模型為。k-折疊交叉驗證就是将訓練集的1/k作為測試集,每個模型訓練k次,測試k次,錯誤率為k次的平均,最終選擇平均率最小的模型Mi。
2.線性回歸原理:
線性回歸是利用數理統計中回歸分析,來确定兩種或兩種以上變量間互相依賴的定量關系的一種統計分析方法,運用十分廣泛。其表達形式為y = w’x+e,e為誤差服從均值為0的正态分布。 [1]
回歸分析中,隻包括一個自變量和一個因變量,且二者的關系可用一條直線近似表示,這種回歸分析稱為一進制線性回歸分析。如果回歸分析中包括兩個或兩個以上的自變量,且因變量和自變量之間是線性關系,則稱為多元線性回歸分析。
3.線性回歸的損失函數,代價函數,目标函數
假設訓練集數量是m ,X = [x0,x1,x2…x(m-1)] , b 代表參數,θ代表變量 = [w0,w1,w2…w(m-1)] α 代表學習率
目标函數 :h(X) = np.dot(θ.T,X) +b
損失函數:J(θ)= 1/2m * (h(X)-y).T * (h(X)-y)
代價函數:θ := θ - α*np.dot((h(X)-y),X)/m
4.優化方法: (梯度下降法,牛頓法,拟牛頓法)
(1)梯度下降法:
1)首先對θ指派,這個值可以是随機的,也可以是一個零向量;
2)改變θ的值,使得J(θ)按梯度下降的方向進行減少;
3)當J(θ)下降到無法下降時為止,即J(θ)對θ的導數為0時,比較J(θ)的值是否有變化。
(2)牛頓法:
無限制條件的最優化問題,假設目标函數J(θ)J(θ)具有二階連續偏導數,若第kk次疊代值為 θ(k)θ(k),則可将J(θ(k+1))J(θ(k+1))在θ(k)θ(k)附近進行二階泰勒展開:
J(θ(k+1))=J(θ(k))+J′(θ(k))(θ(k+1)−θ(k))+12J′′(θ(k))(θ(k+1)−θ(k))2
J(θ(k+1))=J(θ(k))+J′(θ(k))(θ(k+1)−θ(k))+12J″(θ(k))(θ(k+1)−θ(k))2
如果 θ(k+1)θ(k+1)趨近于θ(k)θ(k)時,limθ(k+1)−θ(k)→0J(θ(k+1))−J(θ(k))=0limθ(k+1)−θ(k)→0J(θ(k+1))−J(θ(k))=0,帶入上式,可以得到更新參數集合θθ的疊代公式:
θ(k+1)=θ(k)−J′(θ(k))J′′(θ(k))
θ(k+1)=θ(k)−J′(θ(k))J″(θ(k))
其中,J′′(θ(k))J″(θ(k))為J(θ(k))J(θ(k))的海塞矩陣(Hesse Matrix),上式中[J′′(θ(k))]−1[J″(θ(k))]−1即為海塞矩陣的逆矩陣。
(3)拟牛頓法:
由于牛頓法中海塞矩陣的逆矩陣計算相對複雜,拟牛頓法通過一個nn階矩陣G(θ(k))G(θ(k))來近似代替[J′′(θ(k))]−1[J″(θ(k))]−1。
牛頓法中,海塞矩陣需要滿足條件:
J′(θ(k+1))−J′(θ(k))=J′′(θ(k))(θ(k+1)−θ(k))
J′(θ(k+1))−J′(θ(k))=J″(θ(k))(θ(k+1)−θ(k))
上式變形,得到拟牛頓條件:
[J′′(θ(k))]−1(J′(θ(k+1))−J′(θ(k)))=θ(k+1)−θ(k)
[J″(θ(k))]−1(J′(θ(k+1))−J′(θ(k)))=θ(k+1)−θ(k)
拟牛頓法将G(θ(k))G(θ(k))作為[J′′(θ(k))]−1[J″(θ(k))]−1的近似,則G(θ(k))G(θ(k))需要滿足如下條件:
1)每次疊代矩陣G(θ(k))G(θ(k))為正定矩陣;
2)G(θ(k))G(θ(k))滿足拟牛頓條件,即 G(θ(k))(J′(θ(k+1))−J′(θ(k)))=θ(k+1)−θ(k)G(θ(k))(J′(θ(k+1))−J′(θ(k)))=θ(k+1)−θ(k)。
5.線性回歸的評估名額
(1)、殘差估計
總體思想是計算實際值與預測值間的內插補點簡稱殘差。進而實作對回歸模型的評估,一般可以畫出殘差圖,進行分析評估、估計模型的異常值、同時還可以檢查模型是否是線性的、以及誤差是否随機分布
(2)、均方誤差(Mean Squared Error, MSE)
均方誤差是線性模型拟合過程中,最小化誤差平方和(SSE)代價函數的平均值。MSE可以用于不同模型的比較,或是通過網格搜尋進行參數調優,以及交叉驗證等。
(3)、決定系數
可以看做是MSE的标準化版本,用于更好地解釋模型的性能。換句話說,決定系數是模型捕獲相應反差的分數。
6.sklearn參數詳解
1.擷取資料
1.1 導入sklearn資料集
sklearn中包含了大量的優質的資料集,在你學習機器學習的過程中,你可以通過使用這些資料集實作出不同的模型,進而提高你的動手實踐能力,同時這個過程也可以加深你對理論知識的了解和把握。(這一步我也亟需加強,一起加油!-)
首先呢,要想使用sklearn中的資料集,必須導入datasets子產品:
from sklearn import datasets
iris = datasets.load_iris() # 導入資料集
X = iris.data # 獲得其特征向量
y = iris.target # 獲得樣本label
1.2 建立資料集
你除了可以使用sklearn自帶的資料集,還可以自己去建立訓練樣本
from sklearn.datasets.samples_generator import make_classification
X, y = make_classification(n_samples=6, n_features=5, n_informative=2,
n_redundant=2, n_classes=2, n_clusters_per_class=2, scale=1.0,
random_state=20)
# n_samples:指定樣本數
# n_features:指定特征數
# n_classes:指定幾分類
# random_state:随機種子,使得随機狀可重
2. 資料預處理
資料預處理階段是機器學習中不可缺少的一環,它會使得資料更加有效的被模型或者評估器識别。下面我們來看一下sklearn中有哪些平時我們常用的函數:
from sklearn import preprocessing
2.1 資料歸一化
為了使得訓練資料的标準化規則與測試資料的标準化規則同步,preprocessing中提供了很多Scaler:
data = [[0, 0], [0, 0], [1, 1], [1, 1]]
# 1. 基于mean和std的标準化
scaler = preprocessing.StandardScaler().fit(train_data)
scaler.transform(train_data)
scaler.transform(test_data)
# 2. 将每個特征值歸一化到一個固定範圍
scaler = preprocessing.MinMaxScaler(feature_range=(0, 1)).fit(train_data)
scaler.transform(train_data)
scaler.transform(test_data)
#feature_range: 定義歸一化範圍,注用()括起來
2.2 正則化(normalize)
當你想要計算兩個樣本的相似度時必不可少的一個操作,就是正則化。其思想是:首先求出樣本的p-範數,然後該樣本的所有元素都要除以該範數,這樣最終使得每個樣本的範數都為1。
>>> X = [[ 1., -1., 2.],
… [ 2., 0., 0.],
… [ 0., 1., -1.]]
>>> X_normalized = preprocessing.normalize(X, norm=‘l2’)
>>> X_normalized
array([[ 0.40..., -0.40..., 0.81...],
[ 1. ..., 0. ..., 0. ...],
[ 0. ..., 0.70..., -0.70...]])
2.3 one-hot編碼
one-hot編碼是一種對離散特征值的編碼方式,在LR模型中常用到,用于給線性模型增加非線性能力。
data = [[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]]
encoder = preprocessing.OneHotEncoder().fit(data)
enc.transform(data).toarray()
3. 資料集拆分
在得到訓練資料集時,通常我們經常會把訓練資料集進一步拆分成訓練集和驗證集,這樣有助于我們模型參數的選取。
# 作用:将資料集劃分為 訓練集和測試集
# 格式:train_test_split(*arrays, **options)
from sklearn.mode_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
"""
參數
---
arrays:樣本數組,包含特征向量和标簽
test_size:
float-獲得多大比重的測試樣本 (預設:0.25)
int - 獲得多少個測試樣本
train_size: 同test_size
random_state:
int - 随機種子(種子固定,實驗可複現)
shuffle - 是否在分割之前對資料進行洗牌(預設True)
傳回
---
分割後的清單,長度=2*len(arrays),
(train-test split)
"""
4. 定義模型
在這一步我們首先要分析自己資料的類型,搞清出你要用什麼模型來做,然後我們就可以在sklearn中定義模型了。sklearn為所有模型提供了非常相似的接口,這樣使得我們可以更加快速的熟悉所有模型的用法。在這之前我們先來看看模型的常用屬性和功能:
# 拟合模型
model.fit(X_train, y_train)
# 模型預測
model.predict(X_test)
# 獲得這個模型的參數
model.get_params()
# 為模型進行打分
model.score(data_X, data_y) # 線性回歸:R square; 分類問題: acc
4.1 線性回歸
from sklearn.linear_model import LinearRegression
# 定義線性回歸模型
model = LinearRegression(fit_intercept=True, normalize=False,
copy_X=True, n_jobs=1)
"""
參數
---
fit_intercept:是否計算截距。False-模型沒有截距
normalize: 當fit_intercept設定為False時,該參數将被忽略。 如果為真,則回歸前的回歸系數X将通過減去平均值并除以l2-範數而歸一化。
n_jobs:指定線程數
"""
4.2 邏輯回歸LR
from sklearn.linear_model import LogisticRegression
# 定義邏輯回歸模型
model = LogisticRegression(penalty=’l2’, dual=False, tol=0.0001, C=1.0,
fit_intercept=True, intercept_scaling=1, class_weight=None,
random_state=None, solver=’liblinear’, max_iter=100, multi_class=’ovr’,
verbose=0, warm_start=False, n_jobs=1)
"""參數
---
penalty:使用指定正則化項(預設:l2)
dual: n_samples > n_features取False(預設)
C:正則化強度的反,值越小正則化強度越大
n_jobs: 指定線程數
random_state:随機數生成器
fit_intercept: 是否需要常量
"""
4.3 樸素貝葉斯算法NB
from sklearn import naive_bayes
model = naive_bayes.GaussianNB() # 高斯貝葉斯
model = naive_bayes.MultinomialNB(alpha=1.0, fit_prior=True, class_prior=None)
model = naive_bayes.BernoulliNB(alpha=1.0, binarize=0.0, fit_prior=True, class_prior=None)
"""
文本分類問題常用MultinomialNB
參數
---
alpha:平滑參數
fit_prior:是否要學習類的先驗機率;false-使用統一的先驗機率
class_prior: 是否指定類的先驗機率;若指定則不能根據參數調整
binarize: 二值化的門檻值,若為None,則假設輸入由二進制向量組成
"""
4.4 決策樹DT
from sklearn import tree
model = tree.DecisionTreeClassifier(criterion=’gini’, max_depth=None,
min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0,
max_features=None, random_state=None, max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
class_weight=None, presort=False)
"""參數
---
criterion :特征選擇準則gini/entropy
max_depth:樹的最大深度,None-盡量下分
min_samples_split:分裂内部節點,所需要的最小樣本樹
min_samples_leaf:葉子節點所需要的最小樣本數
max_features: 尋找最優分割點時的最大特征數
max_leaf_nodes:優先增長到最大葉子節點數
min_impurity_decrease:如果這種分離導緻雜質的減少大于或等于這個值,則節點将被拆分。
"""
4.5 支援向量機SVM
from sklearn.svm import SVC
model = SVC(C=1.0, kernel=’rbf’, gamma=’auto’)
"""參數
---
C:誤差項的懲罰參數C
gamma: 核相關系數。浮點數,If gamma is ‘auto’ then 1/n_features will be used instead.
"""
4.6 k近鄰算法KNN
from sklearn import neighbors
#定義kNN分類模型
model = neighbors.KNeighborsClassifier(n_neighbors=5, n_jobs=1) # 分類
model = neighbors.KNeighborsRegressor(n_neighbors=5, n_jobs=1) # 回歸
"""參數
---
n_neighbors: 使用鄰居的數目
n_jobs:并行任務數
"""
4.7 多層感覺機(神經網絡)
from sklearn.neural_network import MLPClassifier
# 定義多層感覺機分類算法
model = MLPClassifier(activation='relu', solver='adam', alpha=0.0001)
"""參數
---
hidden_layer_sizes: 元祖
activation:激活函數
solver :優化算法{‘lbfgs’, ‘sgd’, ‘adam’}
alpha:L2懲罰(正則化項)參數。
"""
5. 模型評估與選擇篇.
5.1 交叉驗證
from sklearn.model_selection import cross_val_score
cross_val_score(model, X, y=None, scoring=None, cv=None, n_jobs=1)
"""參數
---
model:拟合資料的模型
cv : k-fold
scoring: 打分參數-‘accuracy’、‘f1’、‘precision’、‘recall’ 、‘roc_auc’、'neg_log_loss'等等
"""
5.2 檢驗曲線
from sklearn.model_selection import validation_curve
train_score, test_score = validation_curve(model, X, y, param_name, param_range, cv=None, scoring=None, n_jobs=1)
"""參數
---
model:用于fit和predict的對象
X, y: 訓練集的特征和标簽
param_name:将被改變的參數的名字
param_range: 參數的改變範圍
cv:k-fold
傳回值
---
train_score: 訓練集得分(array)
test_score: 驗證集得分(array)
"""
6. 儲存模型
6.1 儲存為pickle檔案
import pickle
# 儲存模型
with open('model.pickle', 'wb') as f:
pickle.dump(model, f)
# 讀取模型
with open('model.pickle', 'rb') as f:
model = pickle.load(f)
model.predict(X_test)
6.2 sklearn自帶方法joblib
from sklearn.externals import joblib
# 儲存模型
joblib.dump(model, 'model.pickle')
#載入模型
model = joblib.load('model.pickle')