機器學習——算法分類


機器學習算法可以分為兩大類:監督學習與非監督學習。數據集構成:‘監督學習:特征值+目標值;非監督學習:特征值’。

監督學習:

分類: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
eg

估計器

在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
eg

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
eg

拉普拉斯分類算法優缺點:

優點:

  • 朴素貝葉斯模型發源於古典數據理論,有穩定的分類效率。
  • 對缺失數據不敏感,算法也比較簡單,常用於文本分類。
  • 分類精度高,速度快。

缺點:由於使用了樣本屬性獨立性的假設,所以如果樣本屬性有關聯時其效果不好。

 

 

 

 

 分類模型評估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_)
eg
運行: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()
eg

 無監督學習——K-means

 

 

sklearn.cluster.KMeans

 

 

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM