機器學習算法可以分為兩大類:監督學習與非監督學習。數據集構成:‘監督學習:特征值+目標值;非監督學習:特征值’。
監督學習:
分類:K-近鄰算法、貝葉斯分類、決策樹與隨機森林、邏輯回歸、神經網絡
回歸:線性回歸、嶺回歸
標注:隱馬爾可夫模型
注:分類:目標值離散型數據;回歸:目標值連續型數據。
無監督學習:
聚類:k-means

數據集API介紹:
sklearn.datasets 加載獲取流行數據集 datasets.load_*() 獲取小規模數據集,數據包含在datasets里 datasets.fetch_*(data_home = None) 獲取大規模的數據集,第一次使用需要從網絡上下載,時間較長,函數的第一 個參數是data_home,表示數據集的下載目錄,默認是~/scikit_lean_data/
load與fetch返回的數據類型datasets.base.Bunch(字典格式)
data: 特征數據數組,是[n_samples*n_features]的二維numpy.narray數組。
target:標簽數組,是n_samples的一維numpy.ndarray數組。
DESCR:數據描述。
feature_names:特征名。新聞數據,手寫數字、回歸數據集沒有
target_names:標簽名
數據集划分API:
sklearn.model_selection.train_test_split x:數據集的特征值 y:數據集的標簽值 test_size:測試集的大小,一般為float random_state:隨機數種子,不同的種子會造成不同的隨機采樣結果,相同 的隨機種子采樣結果相同。 return:訓練集特征值,測試集特征值,訓練標簽,測試標簽
小提示:Sklean數據集的划分比例較合理的划分:訓練集,測試集。划分比列(80%-20,75%-25%,70%-30%)
from sklearn.datasets import load_iris, fetch_20newsgroups, load_boston from sklearn.model_selection import train_test_split def max_data(): # 新聞大數據——分類 news = fetch_20newsgroups(subset="all") print(news.data) print(news.target) def house_price(): # 波士頓房價——回歸數據 lb = load_boston() print("獲取特征值") print(lb.data) print("目標值") print(lb.target) print(lb.DESCR) pass ef mim_data(): # 鳶尾花數據(小數據集) 4個特征--分類 li = load_iris() print("獲取特征值") print(li.data) print("目標值") print(li.target) print(li.DESCR) # 返回值 訓練集train:x_train,y_train 測試集test:x_test,y_test x_train, x_test, y_train, y_test = train_test_split(li.data, li.target, test_size=0.25) print("訓練集的特征值和目標值:", x_train, y_train) print("測試集的特征值和目標值:", x_test, y_test) return None
估計器
在sklearn中,估計器(estimator)是一個重要的角色,分類器和回歸器都屬於estimator,是一類實現了算法的API。
- fit方法用於從訓練集中學習模型參數
- transform用學習到的參數轉換數據
1、用於分類的估計器:
-
sklearn.neighbors k-近鄰算法
-
sklearn.naive_bayes 貝葉斯
-
sklearn.linear_model.LogisticRegression 邏輯回歸
- sklean.tree 決策樹和隨機森林
2、用於回歸的估計器:
-
sklearn.linear_model.LinearRegression 線性回歸
-
sklearn.linear_model.Ridge 嶺回歸
分類算法
K-近鄰算法
定義:如果一個樣本在特征控件中的k個最相似的樣本中的大多數屬於某一個類別,則該樣本也屬於這個類別。
注:樣本距離使用歐式距離時,數據需要進行標准化處理。
sklearn.neighbors.KNeighborsClassifier(n_neighbors=5, algorithm="auto") n_neighbors: 查詢默認使用的鄰居數,默認為5 algorithm:{'auto','ball_tree','kd_tree','brute'},可選用於計算最近鄰 居的算法:'ball_tree'將會使用BallTree,'kd_tree'將使用 KDTree。'auto'將嘗試根據傳遞給fit方法的值來決定最合適的 算法。(不同實現方式影響效率)
def kNN(): from sklearn.neighbors import KNeighborsClassifier from sklearn.preprocessing import StandardScaler from sklearn.model_selection import GridSearchCV """ 預測入住位置,數據無法下載,貌似要FQ :return None """ # 讀取數據 import pandas as pd #處理數據--縮小數據,刪選距離為x公里內的位置, data = pd.read_csv("https://www.kaggle.com/c/facebook-v-predicting-check-ins/data") data.query('x>1.0&x<1.25&y>2.5&y<2.75') time_value = pd.to_datetime(data['time'], unit='s') # 轉換時間戳 time_value = pd.DatetimeIndex(time_value) #把日期轉換為字典格式 # 增加特征,增加一個day特征 data['day'] = time_value.day data['hour'] = time_value.hour data['weekday'] = time_value.weekday data.drop(["time"], axis=1) # axis=1 按列刪除 # 把簽到數量少於n=3的目標位置刪除 place_count = data.groupby("place_id").count() tf = place_count[place_count.row_id>3].reset_index() # reset_index()索引變為一列 data = data[data['place_id'].isin(tf.place_id)] # 取出數據中的特征值和目標值 y = data["place_id"] x = data.drop(["place_id"], axis=1) # 將數據分割為訓練集和測試集 x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25) # 特征工程(標准化) std = StandardScaler() x_train = std.fit_transform(x_train) x_test = std.transform(x_test) # 進行算法流程,超參數5 KNN = KNeighborsClassifier(n_neighbors=5, algorithm="auto") # fit, predict, score # KNN.fit(x_train, y_train) # y_predict = KNN.predict(x_test) #得到預測結果 # print('預測的目標簽到位置為: ', y_predict) # print('預測的准確率: ', KNN.score(x_test, y_test)) # 進行網格搜素 param = {'n_neighbors': [3, 5, 10]} #構建參數值進行搜索 gc = GridSearchCV(KNN, param_grid=param, cv=2) gc.fit(x_train, y_train) #預測准確率 print('在測試集上的准確率: ', gc.score(x_test, y_test)) print("在交叉驗證當中最好的結果:", gc.best_score_) print("選擇的最好模型: ", gc.best_estimator_ ) print('每個超參數每次交叉驗證的結果: ', gc.cv_results_) return None
K-近鄰算法優缺點:
優點:簡單,易於了解,易於實現,無需估計參數,無需訓練
缺點:懶惰算法,對測試樣本分類時的計算量大,內存開銷大;必須選擇K值,K值選擇不當則分類精度不能保證。
使用場景:小數據場景,幾千~幾萬樣本,具體場景具體業務去測試。
朴素貝葉斯算法



eg:

sklearn.naive_bayes.MultinomialNB(alpha=1.0)
alpha:拉普拉斯平滑系數
def neviebayes(): """ 朴素貝葉斯進行文本分類 :return: None """ from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.naive_bayes import MultinomialNB from sklearn.metrics import classification_report news = fetch_20newsgroups(subset='all') # 數據分割 x_train, x_test, y_train, y_test = train_test_split(news.data, news.target, test_size=0.20) # 對數據進行抽取 tf = TfidfVectorizer() # 以訓練集當中的詞的列表進行每篇文章重要性統計 x_train = tf.fit_transform(x_train) print(tf.get_feature_names()) x_test = tf.transform(x_test) #進行朴素貝葉斯算法的預測,一般默認為1.0 mlt = MultinomialNB(alpha=1.0) print(x_train.toarray()) mlt.fit(x_train, y_train) y_predict = mlt.predict(x_test) print("預測的文章類別為: ", y_predict) print("准確率為: ", mlt.score(x_test, y_test)) print("每個類別的准確率和召回率: ", classification_report(y_test, y_predict, target_names=news.target_names)) return None
拉普拉斯分類算法優缺點:
優點:
- 朴素貝葉斯模型發源於古典數據理論,有穩定的分類效率。
- 對缺失數據不敏感,算法也比較簡單,常用於文本分類。
- 分類精度高,速度快。
缺點:由於使用了樣本屬性獨立性的假設,所以如果樣本屬性有關聯時其效果不好。



分類模型評估API

模型的選擇與調優:交叉驗證、網格搜索。
交叉驗證:
目的:為了讓被評估的模型更加准確可信。


超參數搜索--網格搜索
超參數是在建立模型時用於控制算法行為的參數。這些參數不能從常規訓練過程中獲得。在對模型進行訓練之前,需要對它們手動進行賦值。但手動過程繁雜,網格搜索是一種基本的超參數調優技術。它類似於手動調優,為網格中指定的所有給定超參數值的每個排列構建模型,評估並選擇最佳模型。(是個自動的過程)

決策樹與隨機森林
香農公式:

信息增益:當得知一個特征條件后,減少的信息熵的大小。信息增益表示得知特征X的信息而使得類Y的信息的不確定性減少的程度。信息增益是決策樹划分的依據之一。


eg:


決策樹使用的常見准則:
- ID3:信息增益最大准則
- C4.5:信息增益比最大准則
- CART:回歸樹:平方誤差最小;分類樹:基尼系數最小的准則
sklearn.tree.DecisionTreeClassifier(criterion='gini', max_depth=None, random_state=None) #決策樹分類器 criterion:默認是'gini'系數,也可以選擇信息增益的熵'entropy' max_depth:樹的深度 random_state:隨機數種子 decision_path:返回決策樹的路徑
def decision(): """ 決策樹對泰坦尼克號進行預測生死 :return: None """ import pandas as pd from sklearn.metrics import classification_report from sklearn.feature_extraction import DictVectorizer from sklearn.tree import DecisionTreeClassifier, export_graphviz from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import GridSearchCV # 獲取數據 titan = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt") # 處理數據,找出特征值和目標值 x = titan[['pclass', 'age', 'sex']] y = titan[['survived']] # 缺失值處理 x["age"].fillna(x['age'].mean(), inplace=True) # 分割數據集到訓練集和測試集 x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25) # 進行處理 (特征工程 特征-》類別-》one_hot編碼) dict = DictVectorizer(sparse=False) x_train = dict.fit_transform(x_train.to_dict(orient='records')) # 轉換為字典 print(dict.get_feature_names()) x_test = dict.transform(x_test.to_dict(orient='records')) # # 用決策樹進行預測 樹的深度設置max_depth=5 # decTree = DecisionTreeClassifier(criterion='gini',max_depth=None, random_state=None) # decTree.fit(x_train, y_train) # print('預測的准確率: ', decTree.score()) # # # 導出樹的結構, feature_names = dict.get_feature_names() # export_graphviz(decTree, out_file='./tree.dot', feature_names=['age', 'pclass=lst', 'pclass=2nd', 'pclass=3rd', 'sex=female', 'sex=male']) # 隨機森林進行預測 rf = RandomForestClassifier() param = {"n_estimators":[120,200,200,500,800,1200], 'max_depth': [5,8,15,25,30]} # 網格搜素與交叉驗證 gc= GridSearchCV(rf, param_grid=param,cv=2) gc.fit(x_train,y_train) print("准確率: ", gc.score(x_test, y_test)) print("查看選擇的參數: ", gc.best_params_)
運行:dot -Tpng ./tree.dot -o image.png 將生成保存的決策樹轉為png格式
決策樹的優缺點以及改進:
- 優點:簡單的理解和解釋,樹木可視化;不需要對數據進行過多處理,其他技術通常需要對數據進行歸一化
- 缺點:決策樹學習者可以創建不能很好地推廣數據的過於復雜的樹。(過擬合)
- 改進:剪枝cart算法;隨機森林
決策樹調優——隨機森林
集成學習:通過建立幾個模型組合來解決單一預測問題,它的工作原理是生成多個分類器/模型,各自獨立地學習和作出預測。這些預測最后結合成單預測,因此優於任何一個單分類作出的預測。
隨機森林是一個包含多個決策樹的分類器,並且其輸出的類別是由個別樹輸出的類別的眾數而定。



隨機森林的優點:
- 在當前所有算法中,具有極好的准確率
- 能夠有效地運行在大數據集上
- 能夠處理具有高維特征的輸入樣本,而且不需要降維
- 能夠評價各個特征在分類問題上的重要性
回歸算法
線性回歸
定義:通過一個或者多個自變量與因變量之間進行建模回歸分析。
一元線性回歸:涉及到的變量只有一個。多元線性分析:涉及到的變量兩個或者兩個以上。

減少誤差的兩種方式:
(1)正規方程
(2)梯度下降

欠擬合原因以及解決方法:
- 原因:學習到的數據的特征過少
- 解決方法:增加數據的特征數量
過擬合原因以及解決方法:
- 原因:原始特征過多,存在一些嘈雜特征,模型過於復雜是因為模型嘗試去兼顧各個測試數據點
- 解決方法:進行特征選擇,消除關聯性大的特征;交叉驗證(讓所有數據都有過訓練);正則化
嶺回歸
嶺回歸:回歸得到的回歸系數更符合實際,更可靠。另外,能讓估計參數的波動范圍變小,變得更穩定。在存在病態數據偏多的研究中有較大的實用價值。
邏輯回歸解決分類問題(只能解決二分類)


from sklearn.datasets import load_boston from sklearn.linear_model import LinearRegression, SGDRegressor, Ridge, LogisticRegression from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.metrics import mean_squared_error, classification_report import joblib import pandas as pd import numpy as np def mylinear(): """ 線性回歸預測房子價格 :return: None """ # 獲取數據 lb = load_boston() # 分割數據集 x_train, x_test, y_train, y_test = train_test_split(lb.data, lb.target, test_size=0.25) print(y_train, y_test) #進行標准化處理 # 特征值 目標值都要進行標准化處理,實例化兩個API # 特征值 std_x = StandardScaler() x_train = std_x.fit_transform(x_train) x_test = std_x.transform(x_test) #目標值標准化 std_y = StandardScaler() y_train = std_y.fit_transform(y_train) y_test = std_y.transform(y_test) # estimator預測 # 正規方程求解方式預測 lr = LinearRegression() lr.fit(x_train, y_train) print(lr.coef_) # 預測測試集的房子價格 y_predict = lr.predict(x_test) y_predict = std_y.inverse_transform(y_predict) print("正規方程的均方誤差: ", mean_squared_error(std_y.inverse_transform(x_test), y_predict)) # # 梯度下降進行房價預測 # sgd = SGDRegressor() # sgd.fit(x_train, y_train) # print(sgd.coef_) # # 預測測試集的房子價格 # y_predict = sgd.predict(x_test) # y_predict = std_y.inverse_transform(y_predict) # print(y_predict) # print("梯度下降的均方誤差: ", mean_squared_error(std_y.inverse_transform(x_test), y_predict)) # 嶺回歸進行房價預測 rd = Ridge(alpha=1.0) rd.fit(x_train, y_train) print(rd.coef_) # #保存訓練好的模型 # joblib.dump(rd, './tmp/test.pkl') # # 導入訓練好的模型 # model = joblib.load('./tmp/test.pkl') # y_predict = std_y.inverse_transform(model.predict(x_test)) # 預測測試集的房子價格 y_predict = rd.predict(x_test) y_predict = std_y.inverse_transform(y_predict) print("嶺回歸的均方誤差: ", mean_squared_error(std_y.inverse_transform(x_test), y_predict)) return None def logistic(): """ 邏輯回歸做二分類 :return: """ # 構建列名 column = ['Sample code number', 'Clump Thickness', 'Uniformity of Cell Size', 'Uniformity of Cell Shape', 'Marginal Adhesion', 'Single Epithelial Cell Size', 'Bare Nuclei', 'Bland Chromatin ', 'Normal Nucleoli', ' Mitoses', 'Class'] # 讀取數據 data = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data", names=column) print(data) # 缺失值處理 data = data.replace('?', np.nan) data = data.dropna() # 分割數據 x_train, x_test, y_train, y_test = train_test_split(data[column[1:10]],data[column[10]], test_size=0.25) # 進行標准化處理 std = StandardScaler() x_train = std.fit_transform(x_train) x_test = std.transform(x_test) # 邏輯回歸預測 lg = LogisticRegression(C=1.0) lg.fit(x_train, y_train) print(lg.coef_) y_predict = lg.predict(x_test) print("准確率: ", lg.score(x_test, y_test)) print('召回率: ', classification_report(y_test, y_predict, labels=[2, 4], target_names=['良性', '惡性'])) return None if __name__ == "__main__": logistic()
無監督學習——K-means

sklearn.cluster.KMeans


輪廓系數[-1,1],趨勢近於1代表內聚度和分離度都相對較優。( 外部距離最大,內部距離最小)

