sklearn是python中比較常用也是非常好用的機(jī)器學(xué)習(xí)庫,總結(jié)幾個比較常用的機(jī)器學(xué)習(xí)算法,非常簡單,對于想快速入門的小白可以看看哦~
1. 拆分訓(xùn)練集和測試集
from sklearn.model_selection import train_test_split
#X是訓(xùn)練樣本;y是label(目標(biāo)值);test_size為要訓(xùn)練集和測試集的比例,通常為0.2或0.3;random_state為是隨機(jī)數(shù)的種子,其實就是該組隨機(jī)數(shù)的編號,在需要重復(fù)試驗的時候,保證得到一組一樣的隨機(jī)數(shù)。比如你每次都填1,其他參數(shù)一樣的情況下你得到的隨機(jī)數(shù)組是一樣的。
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=20)
2. logistic回歸
from sklearn import linear_model
logistic = linear_model.LogisticRegression()
#如果用正則化,可以添加參數(shù)penalty,可以是l1正則化(可以更有效的抵抗共線性),也可以是l2正則化,如果是類別不均衡的數(shù)據(jù)集,可以添加class_weight參數(shù),這個可以自己設(shè)置,也可以讓模型自己計算
logistic = linear_model.LogisticRegression( penalty='l1', class_weight='balanced')
logistic.fit(X_train,y_train)
y_pred = logistic.predict( X_test)
#如果只想預(yù)測概率大小,可以用下面這個函數(shù)
y_pred = logistic.predict_proba(X_test)
sklearn中與邏輯回歸有關(guān)的主要有2個類,分別是LogisticRegression和LogisticRegressionCV,它們的主要區(qū)別是LogisticRegressionCV使用了交叉驗證來選擇正則化系數(shù)C。而LogisticRegression需要自己每次指定一個正則化系數(shù)。除了交叉驗證,以及選擇正則化系數(shù)C以外, LogisticRegression和LogisticRegressionCV的使用方法基本相同。
邏輯回歸有很多參數(shù)可以調(diào)試,總結(jié)幾個比較重要的參數(shù):
-
penalty: 正則化選項。penalty可選擇的值為"l1"和"l2".分別對應(yīng)L1的正則化和L2的正則化,默認(rèn)是L2正則化。L1正則化可以抵抗共線性,還會起到特征選擇的作用,不重要的特征會將系數(shù)變?yōu)?;L2正則化一般不會將系數(shù)變?yōu)?,但會將不重要的特征系數(shù)變的很小,起到避免過擬合的作用。
penalty參數(shù)的選擇會影響我們損失函數(shù)優(yōu)化算法的選擇。即參數(shù)solver的選擇,如果是L2正則化,那么5種可選的算法{‘newton-cg’, ‘lbfgs’, ‘liblinear’, ‘sag’,‘saga’}都可以選擇。但是如果penalty是L1正則化的話,就只能選擇‘liblinear’和‘saga’了。這是因為L1正則化的損失函數(shù)不是連續(xù)可導(dǎo)的,而{‘newton-cg’, ‘lbfgs’,‘sag’}這三種優(yōu)化算法時都需要損失函數(shù)的一階或者二階連續(xù)導(dǎo)數(shù)。而‘liblinear’并沒有這個依賴。 -
solver: 損失函數(shù)優(yōu)化方法。默認(rèn)是“l(fā)iblinear”,有5中方法可供選擇:
a) liblinear:使用了開源的liblinear庫實現(xiàn),內(nèi)部使用了坐標(biāo)軸下降法來迭代優(yōu)化損失函數(shù)。
b) lbfgs:擬牛頓法的一種,利用損失函數(shù)二階導(dǎo)數(shù)矩陣即海森矩陣來迭代優(yōu)化損失函數(shù)。
c) newton-cg:也是牛頓法家族的一種,利用損失函數(shù)二階導(dǎo)數(shù)矩陣即海森矩陣來迭代優(yōu)化損失函數(shù)。
d) sag:即隨機(jī)平均梯度下降,是梯度下降法的變種,和普通梯度下降法的區(qū)別是每次迭代僅僅用一部分的樣本來計算梯度,適合于樣本非常大的時候。
e)saga: saga是sag的變體,它支持L1正則化,很多時候saga的效果是最好的。
從上面的描述可以看出,newton-cg, lbfgs和sag這三種優(yōu)化算法時都需要損失函數(shù)的一階或者二階連續(xù)導(dǎo)數(shù),因此不能用于沒有連續(xù)導(dǎo)數(shù)的L1正則化,只能用于L2正則化。而liblinear通吃L1正則化和L2正則化,但liblinear也有一個局限,就是在選擇分類方式的選擇時,只支持ovr,下面multi_class參數(shù)會有詳細(xì)解釋。
同時,sag每次僅僅使用了部分樣本進(jìn)行梯度迭代,所以當(dāng)樣本量少的時候不要選擇它,而如果樣本量非常大,比如大于10萬,sag是第一選擇。但是sag不能用于L1正則化,所以當(dāng)你有大量的樣本,又需要L1正則化的話就要自己做取舍了。要么通過對樣本采樣來降低樣本量,要么提前做好特征選擇,要么回到L2正則化。 -
multi_class:分類方式的選擇,有 ovr和multinomial兩個值可以選擇,默認(rèn)是 ovr。
ovr即one-vs-rest(OvR),而multinomial即many-vs-many(MvM)。如果是二元邏輯回歸,ovr和multinomial并沒有任何區(qū)別,區(qū)別主要在多元邏輯回歸上。
OvR的思想很簡單,無論你是多少元邏輯回歸,我們都可以看做二元邏輯回歸。具體做法是,對于第K類的分類決策,我們把所有第K類的樣本作為正例,除了第K類樣本以外的所有樣本都作為負(fù)例,然后在上面做二元邏輯回歸,得到第K類的分類模型。一共需要做T次分類。
而MvM則相對復(fù)雜,這里舉MvM的特例one-vs-one(OvO)作講解。如果模型有T類,我們每次在所有的T類樣本里面選擇兩類樣本出來,不妨記為T1類和T2類,把所有的輸出為T1和T2的樣本放在一起,把T1作為正例,T2作為負(fù)例,進(jìn)行二元邏輯回歸,得到模型參數(shù)。我們一共需要T(T-1)/2次分類。
從上面的描述可以看出OvR相對簡單,但分類效果相對略差(這里指大多數(shù)樣本分布情況,某些樣本分布下OvR可能更好)。而MvM分類相對精確,但是分類速度沒有OvR快。
如果選擇了ovr,則4種損失函數(shù)的優(yōu)化方法liblinear,newton-cg, lbfgs和sag都可以選擇。但是如果選擇了multinomial,則只能選擇newton-cg, lbfgs,saga和sag了。 -
class_weight:分類模型中各種類型的權(quán)重??梢圆惠斎?,即不考慮權(quán)重,或者說所有類型的權(quán)重一樣,默認(rèn)是None。
如果選擇輸入的話,可以選擇balanced讓類庫自己計算類型權(quán)重,或者我們自己輸入各個類型的權(quán)重,比如對于0,1的二元模型,我們可以定義class_weight={0:0.9, 1:0.1},這樣類型0的權(quán)重為90%,而類型1的權(quán)重為10%。如果class_weight選擇balanced,那么類庫會根據(jù)訓(xùn)練樣本量來計算權(quán)重。某種類型樣本量越多,則權(quán)重越低,樣本量越少,則權(quán)重越高。處理類別不均衡問題可以考慮調(diào)節(jié)這個參數(shù)。
參考https://blog.csdn.net/sun_shengyun/article/details/53811483
3. SVM分類
from sklearn import svm
model = svm.SVC()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
4. RandomForest分類
from sklearn.ensemble import RandomForestClassifier
#采用袋外樣本來評估模型的好壞,提高泛化能力
rf0 = RandomForestClassifier(oob_score=True)
rf0.fit(X_train,y_train)
y_pred = rf0.predict(X_test)
隨機(jī)森林也是平時經(jīng)常用到的模型,既可以做分類,也可以做回歸(回歸的時候用RandomForestRegressor),簡單介紹幾個比較重要的參數(shù):
- n_estimators:森林中樹的數(shù)量,默認(rèn)是10棵,如果資源足夠可以多設(shè)置一些
- max_features:尋找最優(yōu)分隔的最大特征數(shù),默認(rèn)是"auto",一般設(shè)置為特征數(shù)的對數(shù),或者特征數(shù)的算術(shù)平方根,也可以設(shè)置成特征數(shù)的40%-50%,這個也可以用來避免過擬合,特征數(shù)越多越容易過擬合
- max_ depth:樹的最大深度,默認(rèn)是None,如果是默認(rèn),則節(jié)點將展開到所有的葉子都是純凈的,或者直到所有的葉子都少于最小分割樣本(min_samples_split)。可以避免過擬合,分類越深越容易過擬合
- min_ samples_split:樹中一個節(jié)點所需要用來分裂的最少樣本數(shù),默認(rèn)是2。可以避免過度擬合(over-fitting),如果用于分類的樣本數(shù)太小,模型可能只適用于用來訓(xùn)練的樣本的分類,而用較多的樣本數(shù)則可以避免這個問題。但如果設(shè)置的數(shù)字過大,又可能會導(dǎo)致欠擬合,因此要根據(jù)你的最終結(jié)果進(jìn)行微調(diào)
- min_ samples_leaf:樹中葉子節(jié)點所需要的最少的樣本數(shù),默認(rèn)是1。也可以用來防止過擬合,但如果是不均等分類問題(imbalanced class problems),一般這個參數(shù)需要設(shè)定較小的值,因為大部分少數(shù)類別含有的樣本都比較小
- min_weight_fraction_leaf:與min_ samples_split類似,只是這個設(shè)置的是比例,默認(rèn)是0.
- max_ leaf_ nodes:樹中最多能有多少個葉子節(jié)點,默認(rèn)是None。這個與上面的max_ depth可能會有沖突,因此在設(shè)置的時候設(shè)置一個就好了
5. adaboost分類
from sklearn.ensemble import AdaBoostClassifier
#迭代100次 ,學(xué)習(xí)率為0.1
clf = AdaBoostClassifier(n_estimators=100,learning_rate=0.1)
clf.fit(X_train,y_train)
y_pred = clf.predict( X_test)
6. GBDT分類
from sklearn.ensemble import GradientBoostingClassifier
#迭代100次 ,學(xué)習(xí)率為0.1
clf = GradientBoostingClassifier(n_estimators=100, learning_rate=0.1)
clf.fit(X_train,y_train)
y_pred = clf.predict( X_test)
7. 神經(jīng)網(wǎng)絡(luò)
from sklearn import linear_model
from sklearn.neural_network import BernoulliRBM
from sklearn.pipeline import Pipeline
logistic = linear_model.LogisticRegression()
rbm = BernoulliRBM(random_state=0, verbose=True)
classifier = Pipeline(steps=[('rbm', rbm), ('logistic', logistic)])
rbm.learning_rate = 0.1
rbm.n_iter = 20
rbm.n_components = 100
#正則化強(qiáng)度參數(shù)
logistic.C = 1000
classifier.fit(X_train, y_train)
y_pred = classifier.predict(X_test)
8. XGboost
from xgboost import XGBClassifier
from matplotlib import pyplot
model = XGBClassifier()
model.fit(X_train,y_train)
y_pred = model.predict(X_test)
#查看預(yù)測準(zhǔn)確率
accuracy_score(y_test, y_pred)
#繪制特征的重要性
from xgboost import plot_importance
plot_importance(model)
pyplot.show()

9. 嶺回歸
嶺回歸是通過在普通最小二乘線性回歸的RSS(殘差平方和RSS(residual sum of squares),別稱SSE(Sum of Squares for Error))基礎(chǔ)上加上正則項(L2范數(shù))來實現(xiàn)對系數(shù)進(jìn)行壓縮懲罰,從而比避免過擬合和產(chǎn)生共線性。
盡管系數(shù)較小可以有效減小方差,但不能保證系數(shù)為0,所以依然留著一大長串特征會使模型不便于解釋。這是嶺回歸的缺點。
# 嶺回歸(Ridge 回歸)
from sklearn import linear_model
X = [[0, 0], [1, 1], [2, 2]]
y = [0, 1, 2]
clf = linear_model.Ridge(alpha=0.1) # 設(shè)置正則化強(qiáng)度
clf.fit(X, y) # 參數(shù)擬合
print(clf.coef_) # 系數(shù)
print(clf.intercept_) # 常量系數(shù)
print(clf.predict([[3, 3]])) # 求預(yù)測值
print(clf.decision_function(X)) # 求預(yù)測,等同predict
print(clf.score(X, y)) # R^2,擬合優(yōu)度
print(clf.get_params()) # 獲取參數(shù)信息
print(clf.set_params(fit_intercept=False)) # 重新設(shè)置參數(shù),如將是否使用截距設(shè)置為false,即不使用截距。
10. Lasso回歸
Lasso是通過在普通最小二乘線性回歸的RSS基礎(chǔ)上加上正則項(L1范數(shù))來實現(xiàn)對系數(shù)進(jìn)行壓縮懲罰,從而比避免過擬合和產(chǎn)生共線性。
Lasso回歸的系數(shù)可以為0,這樣可以起到真正的特征篩選效果。
# Lasso回歸
from sklearn import linear_model
X = [[0, 0], [1, 1], [2, 2]]
y = [0, 1, 2]
clf = linear_model.Lasso(alpha=0.1) # 設(shè)置正則化強(qiáng)度
clf.fit(X, y) # 參數(shù)擬合
print(clf.coef_) # 系數(shù)
print(clf.intercept_) # 常量系數(shù)
print(clf.predict([[3, 3]])) # 求預(yù)測值
print(clf.decision_function(X)) # 求預(yù)測,等同predict
print(clf.score(X, y)) # R^2,擬合優(yōu)度
print(clf.get_params()) # 獲取參數(shù)信息
print(clf.set_params(fit_intercept=False)) # 重新設(shè)置參數(shù),如將是否使用截距設(shè)置為false,即不使用截距。
11. 參數(shù)調(diào)整
每種分類或者回歸算是都有很多可以設(shè)置的參數(shù),那這些應(yīng)該設(shè)置為多少才會比較合適呢,sklearn也有模塊可以幫助我們設(shè)置一個比較好的參數(shù),這個模塊叫GridSearchCV。下面以adaboost算法,用iris數(shù)據(jù)集,找最好的learning_rate為例。
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import StratifiedKFold
learning_rate = [0.0001, 0.001, 0.01, 0.1, 0.2, 0.3]
model = AdaBoostClassifier()
param_grid = dict(learning_rate=learning_rate)
#設(shè)置10折交叉驗證
kfold = StratifiedKFold(n_splits=10, shuffle=True)
grid_search = GridSearchCV(model, param_grid, scoring="neg_log_loss", n_jobs=-1, cv=kfold)
learning_rate = [0.0001, 0.001, 0.01, 0.1, 0.2, 0.3]
model = AdaBoostClassifier()
param_grid = dict(learning_rate=learning_rate)
#設(shè)置10折交叉驗證
kfold = StratifiedKFold(n_splits=10, shuffle=True)
grid_search = GridSearchCV(model, param_grid, scoring="neg_log_loss", n_jobs=-1, cv=kfold)
grid_result = grid_search.fit( iris, iris_y)
#打印最好的learning_rate
print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
Out[349]: Best: -0.160830 using {'learning_rate': 0.3}
#在給定的6個學(xué)習(xí)率中,最好的學(xué)習(xí)率是0.3
#還可以打印其它的參數(shù)
means = grid_result.cv_results_['mean_test_score']
stds = grid_result.cv_results_['std_test_score']
params = grid_result.cv_results_['params']
for mean, stdev, param in zip(means, stds, params):
print("%f (%f) with: %r" % (mean, stdev, param))
Out[350]:-0.462098 (0.000000) with: {'learning_rate': 0.0001}
-0.347742 (0.106847) with: {'learning_rate': 0.001}
-0.237053 (0.056082) with: {'learning_rate': 0.01}
-0.184642 (0.085079) with: {'learning_rate': 0.1}
-0.163586 (0.117306) with: {'learning_rate': 0.2}
-0.160830 (0.135698) with: {'learning_rate': 0.3}
12. 查看結(jié)果準(zhǔn)確率、混淆矩陣、auc等
from sklearn.metrics import accuracy_score
from sklearn.metrics import roc_auc_score
from sklearn.metrics import confusion_matrix
#計算準(zhǔn)確率
accuracy = accuracy_score(y_test, y_pred)
#計算auc,一般針對兩類分類問題
auc = roc_auc_score(y_test, y_pred)
#計算混淆矩陣,一般針對兩類分類問題
conMat = confusion_matrix(y_test, y_pred)