一、這里學習的算法模型包含監督學習和非監督學習兩個方式的算法。
其中監督學習的主要算法分為(分類算法,回歸算法),無監督學習(聚類算法),這里的幾種算法,主要是學習他們用來做預測的效果和具體的使用方式。
二、分類算法
1)K-近鄰算法
a、公式
2個樣本,3個特征 a(a1,a2,a3),b(b1,b2,b3) 歐式距離: ____________________________________ p = √(a1 -b1)^2 + (a2-b2)^2 + (a3 - b3)^2
b、說明:K-近鄰算法,簡而言之,就是誰理我近,我就是這個分類。2個樣本之間的距離通過公式得出p,p越小越接近改正確值的分類。
c、優缺點
優點: 簡單、易於理解、易於實現、無需估計參數、無需訓練
缺點:
懶惰算法,對測試樣本分類時的計算量大,內存開銷大
必須指定K值,K值選擇不當則分類精度不能保證
問題: k值比較小:容易受異常點影響 k值比較大:容易受K值影響(類別)影響 性能問題:每一個數據都要循環計算
說明:為了避免使用最小的值來確認分類,所以需要確定K值(即相鄰個數),通過概率的方式進行選擇分類
d、算法實現
# k-近鄰算法 def k_near(): """ 2個樣本,3個特征 a(a1,a2,a3),b(b1,b2,b3) 歐式距離: ____________________________________ p = √(a1 -b1)^2 + (a2-b2)^2 + (a3 - b3)^2 """ # 1、原始數據 # 讀取數據 train_data = pandas.read_csv("k_near/train.csv") # print(train_data.head(10)) # 2、數據處理 # 數據篩選 train_data = train_data.query("x > 1.0 & x < 1.25 & y > 2.5 & y < 2.75") # 轉換時間 time_value = pandas.to_datetime(train_data["time"], unit="s") # 轉換成字典 time_value = pandas.DatetimeIndex(time_value) # print(time_value) # 構造特征 data = train_data.copy() data["day"] = time_value.day data["hour"] = time_value.hour data["weekday"] = time_value.weekday # print(train_data.head(10)) # 刪除影響特征的數據,axis為1縱向刪除 data = data.drop(["time"], axis=1) # 刪除小於目標值的數據 place_count = data.groupby("place_id").count() # print(place_count) # 過濾數量大於5的地點ID,並且加入列中 tf = place_count[place_count.x > 5].reset_index() # print(tf) data = data[data["place_id"].isin(tf.place_id)] # 取特征值和目標值 y = data["place_id"] x = data.drop(["place_id", "row_id"], axis=1) # 數據分割 x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25) # 3、特征工程 # 特征工程(標准化) std = StandardScaler() x_train = std.fit_transform(x_train) x_test = std.transform(x_test) # 4、算法 # 算法計算 """ 優點: 簡單、易於理解、易於實現、無需估計參數、無需訓練 缺點: 懶惰算法,對測試樣本分類時的計算量大,內存開銷大 必須指定K值,K值選擇不當則分類精度不能保證 問題: k值比較小:容易受異常點影響 k值比較大:容易受K值影響(類別)影響 性能問題:每一個數據都要循環計算 """ # k值就是n_neighbors,也就是通過多少個鄰近數據確認分類 knn = KNeighborsClassifier(n_neighbors=5) knn.fit(x_train, y_train) y_predict = knn.predict(x_test) print("預測值:", y_predict) # 5、評估 # 評估 score = knn.score(x_test, y_test) print("准確率:", score)
結果:
如果覺得上面的例子太復雜,那我們簡化一下:
# K-近鄰算法 def k_near_test(): # 1、原始數據 li = load_iris() # print(li.data) # print(li.DESCR) # 2、處理數據 data = li.data target = li.target x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.25) # 3、特征工程 std = StandardScaler() x_train = std.fit_transform(x_train, y_train) x_test = std.transform(x_test) # 4、算法 knn = KNeighborsClassifier(n_neighbors=2) knn.fit(x_train, y_train) # 預估 y_predict = knn.predict(x_test) print("預估值:", y_predict) # 5、評估 source = knn.score(x_test, y_test) print("准確率:", source) """ 交叉驗證與網格搜索: 交叉驗證: 1、將一個訓練集分成對等的n份(cv值) 2、將第一個作為驗證集,其他作為訓練集,得出准確率 3、將第二個作為驗證集,其他作為訓練集,知道第n個為驗證集,得出准確率 4、把得出的n個准確率,求平均值,得出模型平均准確率 網格搜索: 1、用於參數的調整(比如,k近鄰算法中的n_neighbors值) 2、通過不同參數傳入進行驗證(超參數),得出最優的參數值(最優n_neighbors值) """ # 4、算法 knn_gc = KNeighborsClassifier() # 構造值進行搜索 param= {"n_neighbors": [2, 3, 5]} # 網格搜索 gc = GridSearchCV(knn_gc, param_grid=param,cv=4) gc.fit(x_train, y_train) # 5、評估 print("測試集的准確率:", gc.score(x_test, y_test)) print("交叉驗證當中最好的結果:", gc.best_score_) print("選擇最好的模型:", gc.best_estimator_) print("每個超參數每次交叉驗證結果:", gc.cv_results_)
結果:
其實從上面的准確率來說,這個算法的可行度很低,下面這個是用sklearn 提供的數據集來做的測試,數據精准度比較高。
a、公式
貝葉斯公式: P(W|C)P(C) P(C|W) = —————————— P(W) 說明:P為概率,|在C的前提下W的概率, C分類, W多個條件(特征值)
說明:P(W|C)為:C的條件下:P(W1) * P(W2) * ...
拉普拉斯平滑:
拉普拉斯平滑: 避免出現次數為0的時候,計算結果直接為0 Ni + a P(F1|C) = ——————— N + am 說明:a指系數一般為1, m為W(多個條件)的個數,NI為每個條件的個數,N為W(多個條件)的總個數
說明:為什么要存在拉普拉斯平滑,因為在P(W|C)中,在C分類的條件下,W為多個特征,但是如果W中存在一個為0的情況,那個整個結果就為0,這樣不合理。概率統計,為了是統計在分類條件下,特征的成立數
平滑前:P(W|C) = P(W1=Ni/N)
平滑后:P(W|C) = P(W1=(Ni + a)/(N + am)),其中m為特征數
b、優缺點
優點: 源於古典數學理論,有穩定的分類效率 對缺失數據不太敏感,算法比較簡單,常用語文本 分類精確度高,速度快 缺點: 使用樣本屬性獨立性假設,與樣本屬性關聯密切。如果訓練集准確率不高,會影響結果
c、應用(由於數據的獨立性影響,朴素貝葉斯算法一般用於文本等處理)
文本分類
from sklearn.datasets import fetch_20newsgroups from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics import classification_report from sklearn.model_selection import train_test_split from sklearn.naive_bayes import MultinomialNB # 朴素貝葉斯 def bayes(): """ 貝葉斯公式: P(W|C)P(C) P(C|W) = —————————— P(W) 說明:P為概率,|在C的前提下W的概率, C分類, W多個條件(特征值) 文檔: P(C):每個文檔類別的概率(某文檔類別數/文檔類別總數) P(W|C):給定類別特征(被預測文檔中出現的詞)的概率 拉普拉斯平滑: 避免出現次數為0的時候,計算結果直接為0 Ni + a P(F1|C) = ——————— N + am 說明:a指系數一般為1, m為W(多個條件)的個數,NI為每個條件的個數,N為W(多個條件)的總個數 優點: 源於古典數學理論,有穩定的分類效率 對缺失數據不太敏感,算法比較簡單,常用語文本 分類精確度高,速度快 缺點: 使用樣本屬性獨立性假設,與樣本屬性關聯密切。如果訓練集准確率不高,會影響結果 """ # 1、原始數據 news = fetch_20newsgroups() # 2、處理數據 x_train, x_test, y_train, y_test = train_test_split(news.data, news.target, test_size=0.25) print(x_train) # 3、特征工程 # 抽取特征數據 tf = TfidfVectorizer() # 訓練集中詞的重要性統計 x_train = tf.fit_transform(x_train) # print(tf.get_feature_names()) # 根據訓練集轉換測試集 x_test = tf.transform(x_test) # 4、算法 mlt = MultinomialNB() mlt.fit(x_train, y_train) y_predict = mlt.predict(x_test) print("預測值:", y_predict) # 5、評估 source = mlt.score(x_test, y_test) print("准確率:", source) # 精准率和召回率 """ 二分類的算法評價指標(准確率、精准率、召回率、混淆矩陣、AUC) 數據: 預測值 0 預測值 1 真實值 0 TN FP 真實值 1 FN TP 精准率(precision): TP precision = —————— TP + FP 召回率(recall): TP recall = ——————— TP + FN 模型的穩定性: 2TP 2precision * recall F1 = ————————————— = ——————————————————— 2TP + FN + FP precision + recall """ print("精准率和召回率:\n", classification_report(y_test, y_predict, target_names=news.target_names))
e、結果
3)決策樹和隨機森林
a、公式
信息熵: n H(X) = - ∑ p(x)logp(x) i=1 說明:log 低數為2,單位比特,H(X)為熵,x為特征具體值,p(x)為該值在x特征值中的概率 信息增益: g(D, A) = H(D) - H(D|A)
說明:隨機森林是在決策樹的基礎上,種植多顆樹的方式,只是每一顆樹的深度沒有決策樹那么深。
特征復雜度決定了決策樹的深度,不是樹的深度越深,就越好的,有可能存在計算不出結果。
信息熵:是確定樹深度的最大值。
信息增益:得知特征X的信息而使得類Y的信息的不確定性的減少程度。
b、優缺點
優點: 簡化理解和解釋,樹木可視化 需要很少的數據准備,其他技術通常需要數據歸一化 缺點: 樹太過於復雜,過擬合 改進: 減枝cart算法(決策樹API中已經實現) 隨機森林: 在當前所有算法中具有極好的准確率 能夠有效的運行在大數據集上 能夠處理具有高維特征的輸入樣本中,而且不需要降維 能夠評估各個特征在分類問題上的重要性
c、代碼實現
# 決策樹和隨機森林 def decision_tree(): """ 決策樹: 信息熵: n H(X) = - ∑ p(x)logp(x) i=1 說明:log 低數為2,單位比特,H(X)為熵,x為特征具體值,p(x)為該值在x特征值中的概率 信息增益: g(D, A) = H(D) - H(D|A) 優點: 簡化理解和解釋,樹木可視化 需要很少的數據准備,其他技術通常需要數據歸一化 缺點: 樹太過於復雜,過擬合 改進: 減枝cart算法(決策樹API中已經實現) 隨機森林: 在當前所有算法中具有極好的准確率 能夠有效的運行在大數據集上 能夠處理具有高維特征的輸入樣本中,而且不需要降維 能夠評估各個特征在分類問題上的重要性 """ # 1、原始數據 taitan = pandas.read_csv("decision_tree/titanic.csv") # 2、數據處理 x = taitan[["pclass", "age", "sex"]] y = taitan["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) # 3、特征工程 # 采用DictVectorizer目的是,數據更多是文本類型的,借助dict的方式來處理成0/1的方式 dict = DictVectorizer(sparse=True) x_train = dict.fit_transform(x_train.to_dict(orient="records")) # print(x_train) x_test = dict.transform(x_test.to_dict(orient="records")) # print(dict.get_feature_names()) # 4、算法 tree = DecisionTreeClassifier() tree.fit(x_train, y_train) # 5、評估 score = tree.score(x_test, y_test) print("准確率:", score) # 導出決策樹圖形 export_graphviz(tree, out_file="decision_tree/tree.dot", feature_names=['年齡', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', '女', '男']) # 隨機森林 # 4、算法 rf = RandomForestClassifier() # 超參數調優 # 網絡搜索與交叉驗證 params = { "n_estimators": [120, 200, 300, 500, 800, 1200], "max_depth": [5, 8, 15, 25, 30] } gc = GridSearchCV(rf, param_grid=params, cv=4) gc.fit(x_train, y_train) # 5、評估 score = gc.score(x_test, y_test) print("准確率:", score) print("最佳參數模型:", gc.best_params_)
n_estimators:隨機森林數量, max_depth:最大深度
d、結果
三、回歸算法
1)矩陣計算
矩陣: 必須是二維 乘法公式: (m行, l列)* (l行, n列) = (m行, n列) 例如: [[1,2,3,4]] * [[5],[6],[7],[8]] = 5 * 1 + 6 * 2 + 7 * 3 + 8 * 4
2)線性回歸
a、正規線性公式
屬性的線性組合: f(x) = w1x1 + w2x2 + w3x3 + ... + wnxn + b w:權重, b偏置項, x:特征數據 b:單個特征是更加通用 線性回歸: 通過一個或者多個自變量與因變量之間進行建模的回歸分析 其中可以為一個或者多個自變量之間的線性組合(線性回歸的一種) 一元線性回歸: 涉及的變量只有一個 多元線性回歸: 涉及變量為兩個或者兩個以上 通用公式: h(w) = w0 + w1x1 + w2x2 + ... + wnxn w,x為矩陣w0為b
b、損失函數(最小二乘法)
損失函數(最小二乘法)(誤差的平方和): j(θ) = (hw(x1) - y1)^2 + (hw(x2) - y2)^2 + ... + (hw(xn) - yn)^2 n = ∑(hw(xi) - yi)^2 i=1 yi:訓練樣本的真實值, hw(xi):第i個訓練樣本的特征、組合預測值
說明:當損失值在最小的時候,說明,函數的擬合狀態最好,這種方式,也就更加接近具體的預測軌跡
c、權重值
正規方程: W = (XtX)^(-1)XtY X:特征值矩陣, Y:目標值矩陣 Xt:轉置特征值(行列替換) 特征比較復雜時,不一定能得出結果
梯度下降: 例子(單變量): δcost(w0 + w1x1) || w1 = -w1 - α———————————————— || δw1 || (下降) δcost(w0 + w1x1) || w0 = -w0 - α———————————————— || δw1 \/ α:學習速率,需要手動指定 δcost(w0 + w1x1) ———————————————— 表示方向 δw1
說明:在求最小損失值的時候,需要不斷的求解W(權重值),權重值的求解方式一般為上面兩種。求出的值,然后在計算損失值,然后在反過來推導,權重值。如此得出結果,速率越慢當然擬合程度越高,但都是擬合越高越好。
欠擬合: 原因: 學習到的特征太少 解決辦法: 增加數據的特征數量 過擬合(訓練集和測試集表現不好): 原因: 原始特征數量過多,存在一些嘈雜的特征,模型過於復雜是因為模型嘗試去兼顧各個測試數據點 解決辦法: 進行特征選擇,消除一些關聯性不大的特征(不好做) 交叉驗證(讓所有數據進行訓練) 正則化
表現形式:
最理想的狀態不是第三種,而是第二種。
d、對比:
對比: 梯度下降: 1、需要選擇學習率α 2、需要多次迭代 3、當特征數量n很大時,也比較適用 4、適用於各種類型的模型 正規方程: 1、不需要選擇學習率α 2、一次運算得出 3、需要計算(XtX)^(-1), 如果特征數量n很大時,時間復雜度很高,通常n<100000,可以接受 4、只能用於線性模型,不適合邏輯回歸模型等其他模型
3)嶺回歸
a、存在的意義
嶺回歸: 1、因為線性回歸(LinearRegression)容易出現過擬合的情況,所有需要正則化 2、正則化的目的,就是將高冪(x^n,n很大),的權重降到接近於0 3、嶺回歸為帶有正則化的線性回歸 4、回歸得到的系數更加符合實際,更加可靠,更存在病態數據偏多的研究中存在較大價值
說明:求解模型f(x) = w0 + w1*x1 + w2*x2^2 + ... + wn*xn^n的時候,減少x^n的權重,這樣就減少了過擬合(上圖第三種)的方式
b、優勢
1、具有l2正則化的線性最小二乘法 2、alpha(λ):正則化力度 3、coef_:回歸系數
4)代碼實現
from sklearn.datasets import load_boston from sklearn.linear_model import LinearRegression, SGDRegressor, Ridge from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.metrics import mean_squared_error def regression(): """ 屬性的線性組合: f(x) = w1x1 + w2x2 + w3x3 + ... + wnxn + b w:權重, b偏置項, x:特征數據 b:單個特征是更加通用 線性回歸: 通過一個或者多個自變量與因變量之間進行建模的回歸分析 其中可以為一個或者多個自變量之間的線性組合(線性回歸的一種) 一元線性回歸: 涉及的變量只有一個 多元線性回歸: 涉及變量為兩個或者兩個以上 通用公式: h(w) = w0 + w1x1 + w2x2 + ... + wnxn w,x為矩陣w0為b 矩陣: 必須是二維 乘法公式: (m行, l列)* (l行, n列) = (m行, n列) 例如: [[1,2,3,4]] * [[5],[6],[7],[8]] = 5 * 1 + 6 * 2 + 7 * 3 + 8 * 4 損失函數(最小二乘法)(誤差的平方和): j(θ) = (hw(x1) - y1)^2 + (hw(x2) - y2)^2 + ... + (hw(xn) - yn)^2 n = ∑(hw(xi) - yi)^2 i=1 yi:訓練樣本的真實值, hw(xi):第i個訓練樣本的特征、組合預測值 權重: 正規方程: W = (XtX)^(-1)XtY X:特征值矩陣, Y:目標值矩陣 Xt:轉置特征值(行列替換) 特征比較復雜時,不一定能得出結果 梯度下降: 例子(單變量): δcost(w0 + w1x1) || w1 = -w1 - α———————————————— || δw1 || (下降) δcost(w0 + w1x1) || w0 = -w0 - α———————————————— || δw1 \/ α:學習速率,需要手動指定 δcost(w0 + w1x1) ———————————————— 表示方向 δw1 回歸性能評估: 1 m _ MSE = ——— ∑(yi - y)^2 m i=1 _ yi:預測值 y:真實值 一定要標准化之前的值 對比: 梯度下降: 1、需要選擇學習率α 2、需要多次迭代 3、當特征數量n很大時,也比較適用 4、適用於各種類型的模型 正規方程: 1、不需要選擇學習率α 2、一次運算得出 3、需要計算(XtX)^(-1), 如果特征數量n很大時,時間復雜度很高,通常n<100000,可以接受 4、只能用於線性模型,不適合邏輯回歸模型等其他模型 嶺回歸: 1、因為線性回歸(LinearRegression)容易出現過擬合的情況,所有需要正則化 2、正則化的目的,就是將高冪(x^n,n很大),的權重降到接近於0 3、嶺回歸為帶有正則化的線性回歸 4、回歸得到的系數更加符合實際,更加可靠,更存在病態數據偏多的研究中存在較大價值 Ridge: 1、具有l2正則化的線性最小二乘法 2、alpha(λ):正則化力度 3、coef_:回歸系數 """ # 1、獲取數據 lb = load_boston() # 2、處理數據 # 分隔數據 x_train, x_test, y_train, y_test = train_test_split(lb.data, lb.target, test_size=0.25) # 3、特征工程 # 數據標准化(目的,特征值差異過大,按比例縮小) # 目標值也要進行標准化(目的,特征值標准化后,特征值值過大在回歸算法中,得出的權重值差異過大) # 兩次標准化實例的目的,就是不同數據之間的實例化不一樣 std_x = StandardScaler() x_train = std_x.fit_transform(x_train) x_test = std_x.transform(x_test) std_y = StandardScaler() # 目標值也要轉成2維數組(-1,不知道樣本數) y_train = std_y.fit_transform(y_train.reshape(-1, 1)) y_test = std_y.transform(y_test.reshape(-1, 1)) # print(x_train, y_train) # 4、線性回歸正規算法 """ 1、通過結果可以看出真實值和預測值的差距還是很大的。 2、這是直接通過線性回歸的正確公式來算出權重值的結果。 3、為了更好的減少誤差,所以采用梯度下降的方式,來重新計算權重值 """ lr = LinearRegression() lr.fit(x_train, y_train) y_predict_lr = lr.predict(x_test) # 注意這里的預測值是標准化過后的數據,需要轉回來 # print("預測值:", std_y.inverse_transform(y_predict_lr).reshape(1, -1)) # print("真實值:", std_y.inverse_transform(y_test).reshape(1, -1)) print("權重值:", lr.coef_) # 5、回歸評估 print("正規方程均方誤差:", mean_squared_error(std_y.inverse_transform(y_test).reshape(1, -1), std_y.inverse_transform(y_predict_lr).reshape(1, -1))) # 4、線性回歸梯度下降算法 sgd = SGDRegressor() sgd.fit(x_train, y_train) y_predict_sgd = sgd.predict(x_test) # 注意這里的預測值是標准化過后的數據,需要轉回來 # print("預測值:", std_y.inverse_transform(y_predict_sgd).reshape(1, -1)) # print("真實值:", std_y.inverse_transform(y_test).reshape(1, -1)) print("權重值:", sgd.coef_) # 5、回歸性能評估 print("梯度下降均方誤差:", mean_squared_error(std_y.inverse_transform(y_test).reshape(1, -1), std_y.inverse_transform(y_predict_sgd).reshape(1, -1))) # 4、線性回歸正則化算法(嶺回歸) # alpha為超參數,可以通過網格搜索和交叉驗證,來確認alpha的值 # alpha范圍(0~1, 1~10) rd = Ridge(alpha=1.0) rd.fit(x_train, y_train) y_predict_rd = rd.predict(x_test) # 注意這里的預測值是標准化過后的數據,需要轉回來 # print("預測值:", std_y.inverse_transform(y_predict_rd).reshape(1, -1)) # print("真實值:", std_y.inverse_transform(y_test).reshape(1, -1)) print("權重值:", sgd.coef_) # 5、回歸性能評估 print("正則化均方誤差:", mean_squared_error(std_y.inverse_transform(y_test).reshape(1, -1), std_y.inverse_transform(y_predict_sgd).reshape(1, -1)))
5)結果
說明:從結果可以看出差異並不是很大,那是因為訓練次數的原因,可以通過多次的訓練來達到效果
四、邏輯回歸
1)公式:
公式: 1 hθ = g(θ^Tx) = ———————————— 1 + e^(-θ^Tx) 1 g(z) = —————————— 1 + e^(-z) 輸入:[0,1]區間的概率,默認值0.5作為閾值 g(z):sigmoid函數,z為回歸結果
說明:邏輯回歸,是算一種二分類算法。比如:是否是貓、狗等。我們不能完全確認,他是否是貓,那就用概率的方式來確認分類。概率值越高說明是,反之否。通過大約閾值來確認分類,這種方式人圖像識別中還是比較常用的方式。
2)損失函數:
損失函數: 與線性回歸原理相同,但是由於是分類問題。損失函數不一樣。 只能通過梯度下降求解。 對數似然損失函數: { -log(hθ(x)) if y = 1 cost(hθ(x), y) = { { -log(1 - hθ(x)) if y = 0 hθ(x)為x的概率值
說明:在均方誤差中不存在多個最低點,但是對數似然損失函數,會存在多個低點的情況 完整的損失函數: m cost(hθ(x), y) = ∑-yilog(hθ(x)) - (1 - yi)log(1 - hθ(x)) i=1 cost損失值越小,那么預測的類別精准度更高
對數似然損失函數表現:(目前沒有好的方式去解決確認最低點的問題)
改善方式:
1、多次隨機初始化,多次比較最小值結果
2、求解過程中,調整學習率
上面兩種方式只是改善,不是真正意義上的解決這個最低點的問題。雖然沒有最低點,但是最終結果還是不錯的。
損失函數,表現形式:
說明:如果真實值為y=1時,當hθ(x)的概率越接近1時,說明損失函數的值越小。圖形公式 -log(P)
說明:如果真是值為y=0時,概率越小,損失值就越小
3)代碼實現
import numpy import pandas from sklearn.linear_model import LogisticRegression from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split from sklearn.metrics import mean_squared_error, classification_report # 邏輯回歸 def logic_regression(): """ 公式: 1 hθ = g(θ^Tx) = ———————————— 1 + e^(-θ^Tx) 1 g(z) = —————————— 1 + e^(-z) 輸入:[0,1]區間的概率,默認值0.5作為閾值 g(z):sigmoid函數,z為回歸結果 損失函數: 與線性回歸原理相同,但是由於是分類問題。損失函數不一樣。 只能通過梯度下降求解。 對數似然損失函數: { -log(hθ(x)) if y = 1 cost(hθ(x), y) = { { -log(1 - hθ(x)) if y = 0 hθ(x)為x的概率值 說明:在均方誤差中不存在多個最低點,但是對數似然損失函數,會存在多個低點的情況 完整的損失函數: m cost(hθ(x), y) = ∑-yilog(hθ(x)) - (1 - yi)log(1 - hθ(x)) i=1 cost損失值越小,那么預測的類別精准度更高 """ """ penalty:正則化方式默認值l2, C為回歸系數默認值1.0 """ # 1、原始數據 # 地址:https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/ # 數據:https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data column_names = ["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 = pandas.read_csv("classify_regression/breast-cancer-wisconsin.data", names=column_names) # print(data) # 2、數據處理 # 缺失值處理 data = data.replace(to_replace="?", value=numpy.NAN) # 刪除缺失值數據 data = data.dropna() # 特征值,目標值 x = data[column_names[1:10]] y = data[column_names[10]] # 數據分割 x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25) # 3、特征工程 std = StandardScaler() x_train = std.fit_transform(x_train, y_train) x_test = std.transform(x_test) # 4、算法工程 lr = LogisticRegression(penalty="l2", C=1.0) # 訓練 lr.fit(x_train, y_train) print("權重值:", lr.coef_) # 5、評估 print("准確率:", lr.score(x_test, y_test)) y_predict = lr.predict(x_test) print("召回率:", classification_report(y_test, y_predict, labels=[2, 4], target_names=["良性", "惡性"])) print("均方誤差:", mean_squared_error(y_test, y_predict))
4)結果:
五、上面說的都是監督學習的算法,下面介紹一種非監督學習的算法(k-mean)
1)步驟和優缺點
k值: 分類個數,一般是知道分類個數的,如果不知道,進行超參數設置 算法實現過程: 1)隨機在數據中抽取K個樣本,當做K個類別的中心點 2)計算其余的點到這K個點的距離,每一個樣本有K個距離值,從中選出最近的一個距離點作為自己的標記 這樣就形成了K個族群 3)計算着K個族群的平均值,把這K個平均值,與之前的K個中心點進行比較。 如果相同:結束聚類 如果不同:把K個平均值作為新的中心點,進行計算 優點: 采用迭代式算法,直觀易懂並且非常實用 缺點: 容易收斂到局部最優解(多次聚類) 注意:聚類一般是在做分類之前
2)評估方式
輪廓系數: bi - ai sci = ——————————— max(bi, ai) 注:對於每個點i為已聚類數據中的樣本,bi為i到其他族群的所有樣本的距離 最小值,ai為i到本族群的距離平均值 最終算出所有的樣本的輪廓系數平均值 sci范圍:[-1, 1],越靠近1越好
3)代碼實現方式
from matplotlib import pyplot import pandas from sklearn.cluster import KMeans from sklearn.decomposition import PCA from sklearn.metrics import silhouette_score # 聚類 def k_means(): """ k值: 分類個數,一般是知道分類個數的,如果不知道,進行超參數設置 算法實現過程: 1)隨機在數據中抽取K個樣本,當做K個類別的中心點 2)計算其余的點到這K個點的距離,每一個樣本有K個距離值,從中選出最近的一個距離點作為自己的標記 這樣就形成了K個族群 3)計算着K個族群的平均值,把這K個平均值,與之前的K個中心點進行比較。 如果相同:結束聚類 如果不同:把K個平均值作為新的中心點,進行計算 優點: 采用迭代式算法,直觀易懂並且非常實用 缺點: 容易收斂到局部最優解(多次聚類) 注意:聚類一般是在做分類之前 """ # 1、原始數據 orders = pandas.read_csv("market/orders.csv") prior = pandas.read_csv("market/order_products__prior.csv") products = pandas.read_csv("market/products.csv") aisles = pandas.read_csv("market/aisles.csv") # 2、數據處理 # 合並數據 _msg = pandas.merge(orders, prior, on=["order_id", "order_id"]) _msg = pandas.merge(_msg, products, on=["product_id", "product_id"]) merge_data = pandas.merge(_msg, aisles, on=["aisle_id", "aisle_id"]) # 交叉表(特殊分組) # (用戶ID, 類別) cross = pandas.crosstab(merge_data["user_id"], merge_data["aisle"]) print(cross.shape) # 3、特征工程 # 降維 pca = PCA(n_components=0.9) data = pca.fit_transform(cross) print(data.shape) # 4、算法 """ n_clusters:開始均值的中心數量 """ km = KMeans(n_clusters=4) #減少數據量 # data = data[1:1000] # 訓練 km.fit(data) # 預測結果 predict = km.predict(data) print("預測值:", predict) # 5、評估 """ 輪廓系數: bi - ai sci = ——————————— max(bi, ai) 注:對於每個點i為已聚類數據中的樣本,bi為i到其他族群的所有樣本的距離 最小值,ai為i到本族群的距離平均值 最終算出所有的樣本的輪廓系數平均值 sci范圍:[-1, 1],越靠近1越好 """ print("預測效果:", silhouette_score(data, predict)) # 6、圖形展示 pyplot.figure(figsize=(10, 10)) colors = ["red", "blue", "orange", "yellow"] color = [colors[i] for i in predict] pyplot.scatter(data[:, 1], data[:, 20], color=color) pyplot.xlabel("1") pyplot.ylabel("20") pyplot.show()
4)結果: