Python之算法模型-5.1
一、這里學習的算法模型包含監督學習和非監督學習兩個方式的算法。
其中監督學習的主要算法分為(分類算法,回歸算法),無監督學習(聚類算法),這里的幾種算法,主要是學習他們用來做預測的效果和具體的使用方式。
二、分類算法
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 提供的數據集來做的測試,數據精準度比較高。
2)樸素貝葉斯
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、應用(由于數據的獨立性影響,樸素貝葉斯算法一般用于文本等處理)
文本分類
樸素貝葉斯算法在文字識別, 圖像識別方向有著較為重要的作用。 可以將未知的一種文字或圖像,根據其已有的分類規則來進行分類,最終達到分類的目的。
現實生活中樸素貝葉斯算法應用廣泛,如文本分類,垃圾郵件的分類,信用評估,釣魚網站檢測等等
d、代碼實現
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("精準率和召回率:
", 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)結果:
總結
以上是生活随笔為你收集整理的Python之算法模型-5.1的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 机电传动控制个人课程报告
- 下一篇: 谷歌将 Pixel 7 / Pro 等