機器學習核心概念速覽

機器學習基本概念

  • 有監督學習
  • 分類、回歸
  • 無監督學習
  • 聚類、降維

一維數組

import numpy as np
data = np.array([1,2,3,4,5])
print(data)
print(data.shape)
print(len(data.shape))
[1 2 3 4 5]
(5,)
1

二維數組

data2 = np.array([[1,2,3],[4,5,6]])
print(data2)
print(data2.shape)
print(len(data2.shape))
[[1 2 3][4 5 6]]
(2, 3)
2

稀疏矩陣

  • scipy.sparse

可調用對象

  • 函數,lambd表達式,類,類的方法,對象的方法,實現了特殊方法__call__的類的對象

樣本

  • 定義:樣本是數據集中單個數據點的具體實例。每個樣本由一組特征和可能的目標值組成。
    • 例子:在房價預測中,一個樣本可以是一個房屋,包含特征(如面積、臥室數量)和目標值(房價)。

特征、特征向量

  • 特征:描述樣本屬性的變量,例如年齡、身高、性別。
  • 特征向量:將一個樣本的所有特征組合成一個向量(數組),表示該樣本。
    • 例子:對于一個人,特征可能是 [年齡: 25, 性別: 男, 身高: 175cm]。

特征提取器

  • 定義:一種方法或算法,用于從原始數據中提取有意義的特征。
    • 例子
      • 從文本中提取關鍵詞。
      • 從圖像中提取邊緣或紋理特征(如 HOG 特征)。

目標

  • 定義:機器學習模型試圖預測的值。
    • 例子
      • 分類問題中的類別(例如,貓或狗)。
      • 回歸問題中的數值(例如,房價)。

偏差、方差

  • 偏差:模型預測值與真實值之間的平均差距,表示模型的擬合能力。高偏差可能導致欠擬合。
  • 方差:模型對訓練數據中噪聲的敏感程度。高方差可能導致過擬合。
    • 例子
      • 偏差高的模型可能會忽略數據中的重要模式。
      • 方差高的模型可能會記住訓練數據中的噪聲。

維度

  • 定義:特征的數量。每個特征可以被看作數據的一個維度。
    • 例子
      • 如果一個樣本有 3 個特征(年齡、身高、體重),則數據是 3 維的。

早停法

  • 定義:一種正則化技術,當驗證集的性能不再提升時提前終止訓練,以防止過擬合。
    • 作用:通過停止訓練,避免模型過度學習訓練數據。

評估度量

  • 定義:用來衡量模型性能的指標。
    • 分類問題:準確率、召回率、F1 分數。
    • 回歸問題:均方誤差 (MSE)、平均絕對誤差 (MAE)。

擬合

  • 定義:訓練模型使其學習數據模式的過程。
    • 過擬合:模型學習了訓練數據中的噪聲。
    • 欠擬合:模型未能充分學習數據模式。

填充算法

  • 定義:處理缺失數據的算法。
    • 例子:用均值、中位數或眾數填充缺失值。

數據泄漏

  • 定義:訓練數據中包含了測試數據的信息,導致模型性能虛高。
    • 例子:將目標變量作為特征的一部分。

有監督學習

  • 定義:使用帶標簽的數據進行訓練。
    • 例子:預測房價,數據包含歷史房價(標簽)。

半監督學習

  • 定義:使用少量帶標簽數據和大量未帶標簽數據進行訓練。
    • 例子:網頁分類,部分網頁有類別標簽,部分沒有。

無監督學習

  • 定義:不使用標簽數據,模型通過數據的結構進行學習。
    • 例子:聚類分析(如 K-Means)。

分類器

  • 定義:將輸入數據分到特定類別的模型。
    • 例子:支持向量機(SVM)、決策樹。

聚類器

  • 定義:將數據分組為若干簇的算法。
    • 例子:K-Means、層次聚類。

離群點檢測器

  • 定義:檢測數據中的異常點。
    • 例子:銀行系統檢測信用卡欺詐。

交叉驗證生成器

  • 定義:生成交叉驗證的訓練集和驗證集。
    • 作用:確保模型性能的評估更加穩定。

損失函數

  • 定義:衡量模型預測值和真實值之間差異的函數。
    • 例子:均方誤差 (MSE)、交叉熵損失。

梯度下降

  • 定義:一種優化算法,通過最小化損失函數找到模型的最佳參數。
    • 變種
      • 批量梯度下降:使用整個數據集計算梯度。
      • 隨機梯度下降 (SGD):每次只用一個樣本更新梯度。

正則化

  • 定義:防止模型過擬合的一種方法,通過限制模型的復雜度。
    • 例子:L1 正則化(Lasso)、L2 正則化(Ridge)。

泛化

  • 定義:模型在未見過的數據上的表現能力。
    • 良好的泛化能力:模型在訓練集和測試集上都能表現良好。

學習曲線

  • 定義:顯示模型性能隨訓練數據量變化的曲線。
    • 作用:幫助診斷過擬合或欠擬合。

召回率

  • 定義:模型正確識別出所有正例的比例。
    • 公式:召回率 = 真正例 / (真正例 + 假反例)

準確率

  • 定義:模型預測正確的樣本占總樣本的比例。
    • 公式:準確率 = (真正例 + 真反例) / 總樣本數

機器學習庫scikit-learn簡介

# datasets -包含加載常用數據集的函數和生成隨機數據的函數

線性回歸算法原理與應用

1.簡單線性回歸(預測兒童身高)

import copy
import numpy as np
from sklearn import linear_model# 訓練數據,每一行表示一個樣本,包含的信息分別為:
# 兒童年齡,性別(0女1男)
# 父親、母親、祖父、祖母、外祖父、外祖母的身高
x = np.array([[1, 0, 180, 165, 175, 165, 170, 165],[3, 0, 180, 165, 175, 165, 173, 165],[4, 0, 180, 165, 175, 165, 170, 165],[6, 0, 180, 165, 175, 165, 170, 165],[8, 1, 180, 165, 175, 167, 170, 165],[10, 0, 180, 166, 175, 165, 170, 165],[11, 0, 180, 165, 175, 165, 170, 165],[12, 0, 180, 165, 175, 165, 170, 165],[13, 1, 180, 165, 175, 165, 170, 165],[14, 0, 180, 165, 175, 165, 170, 165],[17, 0, 170, 165, 175, 165, 170, 165]])# 兒童身高,單位:cm
y = np.array([60, 90, 100, 110, 130, 140, 150, 164, 160, 163, 168])
# 創建線性回歸模型
lr = linear_model.LinearRegression()
# 根據已知數據擬合最佳直線
lr.fit(x, y)# 待測的未知數據,其中每個分量的含義和訓練數據相同
xs = np.array([[10, 0, 180, 165, 175, 165, 170, 165],[17, 1, 173, 153, 175, 161, 170, 161],[34, 0, 170, 165, 170, 165, 170, 165]])for item in xs:# 為不改變原始數據,進行深復制,并假設超過18歲以后就不再長高了# 對于18歲以后的年齡,返回18歲時的身高item1 = copy.deepcopy(item)if item1[0] > 18:item1[0] = 18print(item, ':', lr.predict(item1.reshape(1,-1)))
[ 10   0 180 165 175 165 170 165] : [140.56153846]
[ 17   1 173 153 175 161 170 161] : [158.41]
[ 34   0 170 165 170 165 170 165] : [176.03076923]

2.嶺回歸

from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import RidgeClassifier
from sklearn.model_selection import train_test_split# 加載乳腺癌數據,共569個樣本,每個樣本有30個特征
X, y = load_breast_cancer(return_X_y=True)
# 使用默認參數創建嶺回歸分類器對象
clf = RidgeClassifier()
# 劃分訓練集與測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# 使用訓練集擬合模型
clf.fit(X_train, y_train)
# 使用測試集,評估模型得分
print(clf.score(X_test, y_test))
0.9649122807017544

3.Lasso回歸

from time import time
from scipy.sparse import coo_matrix
from sklearn.datasets import make_regression
from sklearn.linear_model import LassoX, y = make_regression(n_samples=1000, n_features=8000,  # 樣本數量,特征數量n_informative=20,                 # 實際有效的特征數量noise=0.9,                        # 高斯噪聲的標準差random_state=20230409,            # 使得每次運行結果相同)
# 把部分數據置0,使數據稀疏
X[X<2] = 0
# 創建壓縮稀疏列格式的矩陣,可以使用toarray()轉換為稠密格式的數組
X_sparse = coo_matrix(X).tocsc()
# 查看壓縮比,nnz屬性的值為稀疏矩陣實際保存的數據個數
print(f'壓縮后數據量變為原來的:{X_sparse.nnz/X.size:.3%}')# 創建套索回歸對象,參數alpha的值越大,選擇的特征數量越少
estimator = Lasso(alpha=3, fit_intercept=False, max_iter=10000)
# 使用原始數據擬合模型,記錄所用時間以及訓練后的模型參數
start = time()
estimator.fit(X, y)
print(f'原始稠密數據訓練用時:{time()-start}秒')
coef_dense = estimator.coef_# 使用稀疏矩陣格式的數據重新擬合模型,記錄所用時間以及訓練后的模型參數
start = time()
estimator.fit(X_sparse, y)
print(f'稀疏矩陣格式的數據訓練用時:{time()-start}秒')
coef_sparse = estimator.coef_print(f'兩種格式的數據訓練后模型參數之差的最大值為:{(coef_sparse-coef_dense).max()}')
壓縮后數據量變為原來的:2.271%
原始稠密數據訓練用時:0.8571333885192871秒
稀疏矩陣格式的數據訓練用時:0.21027755737304688秒
兩種格式的數據訓練后模型參數之差的最大值為:7.72715225139109e-14

邏輯回歸算法基本原理與應用

使用logistic回歸預測考試是否及格

from sklearn.linear_model import LogisticRegression# 復習情況,格式為(時長,效率),其中時長等位為小時
X_train = [(1, 0),(3, 0.5),(4, 0.5),(6, 0.5),(8, 1),(10, 1),(11, 1),(12, 1),(13, 1),(14, 1),(17, 1)]
y_train = [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1]# 創建邏輯回歸模型
reg = LogisticRegression()
# 擬合模型
reg.fit(X_train, y_train)# 測試數據
X_test = [(3,0.5) ,(8,1) ,(9,1) ,(10,0)]
y_test = [0, 1, 1, 0]
score = reg.score(X_test, y_test)print("模型的準確率為:", score)# 預測
learning = [(8.5,0.5)]
result = reg.predict_proba(learning)
msg = '''模型得分為:{0}
復習時長為:{1[0]}小時,效率為:{1[1]}
預測為及格的概率為:{2[1]}
預測為不及格的概率為:{2[0]}
及格的概率為:{2[1]}
綜合判斷,您會:{3}'''.format(score, learning[0], result[0], "不及格" if result[0][0] > 0.5 else "及格")
print(msg)# 使用遞歸算法尋找最優參數得出最小復習時長可以及格
def find_min_study_time(current_hours, efficiency, model, increment=0.1, max_hours=24.0):"""使用遞歸算法尋找在給定效率下,能夠及格的最小復習時長。:param current_hours: 當前嘗試的復習時長:param efficiency: 復習效率 (0到1之間):param model: 訓練好的邏輯回歸模型:param increment: 每次遞歸增加的時長:param max_hours: 允許嘗試的最大復習時長:return: 最小及格復習時長,如果超過max_hours仍未及格則返回None"""if current_hours > max_hours:return None  # 超過最大時長限制,未找到test_data = [(current_hours, efficiency)]pass_probability = model.predict_proba(test_data)[0][1]  # 獲取及格的概率if pass_probability > 0.5:return current_hours  # 找到最小及格時長else:# 遞歸調用,增加時長return find_min_study_time(current_hours + increment, efficiency, model, increment, max_hours)# 示例:尋找效率為0.5時的最小及格復習時長
efficiency_to_test = 0.5
initial_hours = 0.1 # 從一個較小的初始時長開始
min_time_eff_0_5 = find_min_study_time(initial_hours, efficiency_to_test, reg)if min_time_eff_0_5 is not None:print(f"\n在效率為 {efficiency_to_test} 時,預測的最小及格復習時長為: {min_time_eff_0_5:.1f} 小時")# 驗證一下這個時長prob_eff_0_5 = reg.predict_proba([(min_time_eff_0_5, efficiency_to_test)])[0]print(f"  - 對應及格概率: {prob_eff_0_5[1]:.4f}, 不及格概率: {prob_eff_0_5[0]:.4f}")
else:print(f"\n在效率為 {efficiency_to_test} 時,在 {max_hours} 小時內未能找到及格的復習時長。")# 示例:尋找效率為1.0時的最小及格復習時長
efficiency_to_test_2 = 1.0
min_time_eff_1_0 = find_min_study_time(initial_hours, efficiency_to_test_2, reg)if min_time_eff_1_0 is not None:print(f"\n在效率為 {efficiency_to_test_2} 時,預測的最小及格復習時長為: {min_time_eff_1_0:.1f} 小時")# 驗證一下這個時長prob_eff_1_0 = reg.predict_proba([(min_time_eff_1_0, efficiency_to_test_2)])[0]print(f"  - 對應及格概率: {prob_eff_1_0[1]:.4f}, 不及格概率: {prob_eff_1_0[0]:.4f}")
else:print(f"\n在效率為 {efficiency_to_test_2} 時,在 {max_hours} 小時內未能找到及格的復習時長。")# 以上代碼實現了一個簡單的邏輯回歸模型來預測復習情況,并使用遞歸算法尋找在給定效率下,能夠及格的最小復習時長。
模型的準確率為: 0.75
模型得分為:0.75
復習時長為:8.5小時,效率為:0.5
預測為及格的概率為:0.8134531096860228
預測為不及格的概率為:0.1865468903139772
及格的概率為:0.8134531096860228
綜合判斷,您會:及格在效率為 0.5 時,預測的最小及格復習時長為: 7.1 小時- 對應及格概率: 0.5183, 不及格概率: 0.4817在效率為 1.0 時,預測的最小及格復習時長為: 7.0 小時- 對應及格概率: 0.5141, 不及格概率: 0.4859

8.5樸素貝葉斯算法原理與應用(中文郵件分類)

import numpy as np
x= np.array([[-1,-1],[-2,-1],[-3,-2],[1,1],[2,1],[3,2]])
y=np.array([1,1,1, 2,2, 2])
from sklearn.naive_bayes import GaussianNB
clf = GaussianNB()#創建高斯樸素貝葉斯模型
clf.fit(x,y)#訓練模型
GaussianNB(priors=None)
clf.predict([[-0.8,-1]])
array([1])
# 分類
clf.predict_proba([[-0.8,-1]])#樣本屬于不同類別的概率
clf.score([[-0.8, -1]],[1])
1.0
# 評分
clf.score([[-0.8, -1],[0, 0]],[1, 2]) # 評分
0.5

重要:中文郵件分類

  • 對文件夾貝葉斯中文郵件分類中的份郵件的文本內容進行訓練,其中0.txt 到 126.txt 為垃圾郵件,127.txt 到 253.txt 為正常郵件,模型訓練結束后使用 5 封郵件 (151.txt 到 155.txt)的文本內容進行測試,判斷這 5 封郵件是否為垃圾郵件。
from re import sub
from os import listdir
from collections import Counter
from itertools import chain
from numpy import array
from jieba import cut
from sklearn.naive_bayes import MultinomialNBdef getWordsFromFile(txtFile):# 獲取每一封郵件中的所有詞語words = []# 所有存儲郵件文本內容的記事本文件都使用UTF8編碼with open(txtFile, encoding='utf8') as fp:for line in fp:# 遍歷每一行,刪除兩端的空白字符line = line.strip()# 過濾干擾字符或無效字符line = sub(r'[.【】0-9、—。,!~\*]', '', line)# 分詞line = cut(line)# 過濾長度為1的詞line = filter(lambda word: len(word)>1, line)# 把本行文本預處理得到的詞語添加到words列表中words.extend(line)# 返回包含當前郵件文本中所有有效詞語的列表return words# 存放所有文件中的單詞
# 每個元素是一個子列表,其中存放一個文件中的所有單詞
allWords = []
def getTopNWords(topN):# 按文件編號順序處理當前文件夾中所有記事本文件# 訓練集中共151封郵件內容,0.txt到126.txt是垃圾郵件內容# 127.txt到150.txt為正常郵件內容txtFiles = [str(i)+'.txt' for i in range(151)]# 獲取訓練集中所有郵件中的全部單詞for txtFile in txtFiles:allWords.append(getWordsFromFile(txtFile))# 獲取并返回出現次數最多的前topN個單詞freq = Counter(chain(*allWords))return [w[0] for w in freq.most_common(topN)]# 全部訓練集中出現次數最多的前600個單詞
topWords = getTopNWords(600)# 獲取特征向量,前600個單詞的每個單詞在每個郵件中出現的頻率
vectors = []
for words in allWords:temp = list(map(lambda x: words.count(x), topWords))vectors.append(temp)
vectors = array(vectors)
# 訓練集中每個郵件的標簽,1表示垃圾郵件,0表示正常郵件
labels = array([1]*127 + [0]*24)# 創建模型,使用已知訓練集進行訓練
model = MultinomialNB()
model.fit(vectors, labels)def predict(txtFile):# 獲取指定郵件文件內容,返回分類結果words = getWordsFromFile(txtFile)currentVector = array(tuple(map(lambda x: words.count(x),topWords)))result = model.predict(currentVector.reshape(1, -1))[0]return '垃圾郵件' if result==1 else '正常郵件'# 151.txt至155.txt為測試郵件內容
for mail in ('%d.txt'%i for i in range(151, 156)):print(mail, predict(mail), sep=':')
151.txt:垃圾郵件
152.txt:垃圾郵件
153.txt:垃圾郵件
154.txt:垃圾郵件
155.txt:正常郵件

方式二:訓練模型進行保存,格式化存儲,直接調用函數進行訓練識別

from re import sub
from jieba import cutdef getWordsFromFile(txtFile):# 獲取每一封郵件中的所有詞語words = []# 所有存儲郵件文本內容的記事本文件都使用UTF8編碼with open(txtFile, encoding='utf8') as fp:for line in fp:# 遍歷每一行,刪除兩端的空白字符line = line.strip()# 過濾干擾字符或無效字符line = sub(r'[.【】0-9、—。,!~\*]', '', line)# 分詞line = cut(line)# 過濾長度為1的詞line = filter(lambda word: len(word)>1, line)# 把本行文本預處理得到的詞語添加到words列表中words.extend(line)# 返回包含當前郵件文本中所有有效詞語的列表return words
from os import listdir
from collections import Counter
from itertools import chain
from numpy import array
from sklearn.externals import joblib
from sklearn.naive_bayes import MultinomialNB
from get_words_from_file import getWordsFromFile# 存放所有文件中的單詞
# 每個元素是一個子列表,其中存放一個文件中的所有單詞
allWords = []
def getTopNWords(topN):# 按文件編號順序處理當前文件夾中所有記事本文件# 訓練集中共151封郵件內容,0.txt到126.txt是垃圾郵件內容# 127.txt到150.txt為正常郵件內容txtFiles = [str(i)+'.txt' for i in range(151)]# 獲取訓練集中所有郵件中的全部單詞for txtFile in txtFiles:allWords.append(getWordsFromFile(txtFile))# 獲取并返回出現次數最多的前topN個單詞freq = Counter(chain(*allWords))return [w[0] for w in freq.most_common(topN)]# 全部訓練集中出現次數最多的前600個單詞
topWords = getTopNWords(600)# 獲取特征向量,前600個單詞的每個單詞在每個郵件中出現的頻率
vectors = []
for words in allWords:temp = list(map(lambda x: words.count(x), topWords))vectors.append(temp)
vectors = array(vectors)
# 訓練集中每個郵件的標簽,1表示垃圾郵件,0表示正常郵件
labels = array([1]*127 + [0]*24)# 創建模型,使用已知訓練集進行訓練
model = MultinomialNB()
model.fit(vectors, labels)joblib.dump(model, "垃圾郵件分類器.pkl")
print('保存模型和訓練結果成功。')
with open('topWords.txt', 'w', encoding='utf8') as fp:fp.write(','.join(topWords))
print('保存topWords成功。')
from numpy import array
from sklearn.externals import joblib
from sklearn.naive_bayes import MultinomialNB
from get_words_from_file import getWordsFromFilemodel = joblib.load("垃圾郵件分類器.pkl")
print('加載模型和訓練結果成功。')
with open('topWords.txt', encoding='utf8') as fp:topWords = fp.read().split(',')def predict(txtFile):# 獲取指定郵件文件內容,返回分類結果words = getWordsFromFile(txtFile)currentVector = array(tuple(map(lambda x: words.count(x),topWords)))result = model.predict(currentVector.reshape(1, -1))[0]return '垃圾郵件' if result==1 else '正常郵件'# 151.txt至155.txt為測試郵件內容
for mail in ('%d.txt'%i for i in range(151, 156)):print(mail, predict(mail), sep=':')
151.txt:垃圾郵件
152.txt:垃圾郵件
153.txt:垃圾郵件
154.txt:垃圾郵件
155.txt:正常郵件

8.6決策樹與隨機森林算法原理與應用

基尼值 G i n i = 1 ? ∑ i = 1 n P i 2 Gini=1-\sum_{i=1}^{n}P_i^{2} Gini=1?i=1n?Pi2?(考點)

使用python決策樹算法實現學員的python水平

import numpy as np
from sklearn import treequestions = ('《Python程序設計與數據采集》','《Python數據分析、挖掘與可視化》','《Python程序設計基礎(第3版)》','《Python程序設計基礎與應用(第2版)》','《Python程序設計實例教程(第2版)》','《Python程序設計(第3版)》', '《Python網絡程序設計》','《Python數據分析與數據可視化》','《大數據的Python基礎(第2版)》','《Python程序設計開發寶典》','《Python可以這樣學》', '《中學生可以這樣學Python》','《Python編程基礎與案例集錦(中學版)》','《Python程序設計實驗指導書》','《Python程序設計入門與實踐》','《Python程序設計實用教程》','微信公眾號“Python小屋”的免費資料')
# 每個樣本的數據含義:0沒看過,1很多看不懂,2大部分可以看懂,3沒壓力
answers = [[3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3],[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],[1, 0, 2, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 2, 2, 2, 1],[2, 2, 3, 3, 3, 1, 1, 1, 3, 2, 2, 3, 3, 3, 0, 3, 2],[2, 2, 3, 2, 2, 1, 1, 3, 1, 2, 2, 3, 3, 2, 2, 2, 1],[3, 3, 3, 0, 3, 2, 2, 3, 3, 2, 3, 3, 3, 3, 3, 3, 2],[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3],[0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],[2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]]
labels = ['超級高手', '門外漢', '初級選手', '初級選手', '高級選手','中級選手', '高級選手', '超級高手', '初級選手', '初級選手']clf = tree.DecisionTreeClassifier().fit(answers, labels) # 訓練yourAnswer = []
print('在下面的問卷中,''沒看過輸入0,很多看不懂輸入1,大部分可以看懂輸入2,沒壓力輸入3')
# 顯示調查問卷,并接收用戶輸入
for question in questions:print('=========\n你看過董付國老師的', question, '嗎?')# 確保輸入有效while True:try:answer = int(input('請輸入:'))assert 0<=answer<=3breakexcept:print('輸入無效,請重新輸入。')passyourAnswer.append(answer)print(clf.predict(np.array(yourAnswer).reshape(1,-1)))   # 分類
在下面的問卷中,沒看過輸入0,很多看不懂輸入1,大部分可以看懂輸入2,沒壓力輸入3
=========
你看過董付國老師的 《Python程序設計與數據采集》 嗎?
請輸入: 1
=========
你看過董付國老師的 《Python數據分析、挖掘與可視化》 嗎?
請輸入: 1
=========
你看過董付國老師的 《Python程序設計基礎(第3版)》 嗎?
請輸入: 1
=========
你看過董付國老師的 《Python程序設計基礎與應用(第2版)》 嗎?
請輸入: 1
=========
你看過董付國老師的 《Python程序設計實例教程(第2版)》 嗎?
請輸入: 1
=========
你看過董付國老師的 《Python程序設計(第3版)》 嗎?
請輸入: 1
=========
你看過董付國老師的 《Python網絡程序設計》 嗎?
請輸入: 1
=========
你看過董付國老師的 《Python數據分析與數據可視化》 嗎?
請輸入: 1
=========
你看過董付國老師的 《大數據的Python基礎(第2版)》 嗎?
請輸入: 1
=========
你看過董付國老師的 《Python程序設計開發寶典》 嗎?
請輸入: 1
=========
你看過董付國老師的 《Python可以這樣學》 嗎?
請輸入: 1
=========
你看過董付國老師的 《中學生可以這樣學Python》 嗎?
請輸入: 1
=========
你看過董付國老師的 《Python編程基礎與案例集錦(中學版)》 嗎?
請輸入: 1
=========
你看過董付國老師的 《Python程序設計實驗指導書》 嗎?
請輸入: 1
=========
你看過董付國老師的 《Python程序設計入門與實踐》 嗎?
請輸入: 1
=========
你看過董付國老師的 《Python程序設計實用教程》 嗎?
請輸入: 1
=========
你看過董付國老師的 微信公眾號“Python小屋”的免費資料 嗎?
請輸入: 1
['初級選手']

支持向量機(實現手寫文子數字圖像分類)

'''
from os import mkdir, listdir
from os.path import isdir, basename
from random import choice, randrange
from string import digits
from PIL import Image, ImageDraw   # pillow
from PIL.ImageFont import truetype
from sklearn import svm
from sklearn.model_selection import train_test_split# 圖像尺寸、圖片中的數字字體大小、噪點比例
width, height = 30, 60
fontSize = 40
noiseRate = 8def generateDigits(dstDir='datasets1', num=400):# 生成num個包含數字的圖片文件存放于當前目錄下的datasets子目錄if not isdir(dstDir):mkdir(dstDir)# digits.txt用來存儲每個圖片對應的數字with open(dstDir+'/digits.txt', 'w') as fp:font = truetype('SimHei.ttf',fontSize)for i in range(num):# 隨機選擇一個數字,生成對應的彩色圖像文件digit = choice(digits)im = Image.new('RGB', (width,height), (255,255,255))imDraw = ImageDraw.Draw(im)imDraw.text((0,0), digit, font=font, fill=(0,0,0))# 加入隨機干擾for j in range(int(noiseRate*width*height)):w, h = randrange(1, width-1), randrange(height)# 水平交換兩個相鄰像素的顏色c1 = im.getpixel((w,h))c2 = im.getpixel((w+1,h))                imDraw.point((w,h), fill=c2)imDraw.point((w+1,h), fill=c1)im.save(dstDir+'/'+str(i)+'.jpg')fp.write(digit+'\n')def loadDigits(dstDir='datasets1'):# 獲取所有圖像文件名digitsFile = [dstDir+'/'+fn for fn in listdir(dstDir)if fn.endswith('.jpg')]# 按編號排序,1.jpg,10.jpg,100.jpgdigitsFile.sort(key=lambda fn: int(basename(fn)[:-4]))# digitsData用于存放讀取的圖片中數字信息# 每個圖片中所有像素值存放于digitsData中的一行數據digitsData = []for fn in digitsFile:with Image.open(fn) as im:data = [sum(im.getpixel((w,h)))/len(im.getpixel((w,h)))for w in range(width)for h in range(height)]digitsData.append(data)# digitsLabel用于存放圖片中數字的標準分類with open(dstDir+'/digits.txt') as fp:digitsLabel = fp.readlines()# digitsLabel = [label.strip() for label in digitsLabel]digitsLabel = list(map(str.strip, digitsLabel))return (digitsData, digitsLabel)# 生成圖片文件
generateDigits(num=100)
# 加載數據
data = loadDigits()
print('數據加載完成。')# 隨機劃分訓練集和測試集,其中參數test_size用來指定測試集大小
X_train, X_test, y_train, y_test = train_test_split(data[0],data[1],test_size=0.1)
# 創建并訓練模型
svcClassifier = svm.SVC(kernel="linear", C=1000, gamma=0.001)
svcClassifier.fit(X_train, y_train)
print('模型訓練完成。')# 使用測試集對模型進行評分
score = svcClassifier.score(X_test, y_test)
print('模型測試得分:', score)
'''

KNN算法原理與應用

使用KNN判斷交通工具類型

from sklearn.neighbors import KNeighborsClassifier# X中存儲交通工具的參數
# 總長度(米)、時速(km/h)、重量(噸)、座位數量
X = [[96, 85, 120, 400],        # 普通火車[144, 92, 200, 600],[240, 87, 350, 1000],[360, 90, 495, 1300],[384, 91, 530, 1405],[240, 360, 490, 800],      # 高鐵[360, 380, 750, 1200],[290, 380, 480, 960],[120, 320, 160, 400],[384, 340, 520, 1280],[33.4, 918, 77, 180],      # 飛機[33.6, 1120, 170.5, 185],[39.5, 785, 230, 240],[33.84, 940, 150, 195],[44.5, 920, 275, 275],[75.3, 1050, 575, 490]]
# y中存儲類別,0表示普通火車,1表示高鐵,2表示飛機
y = [0]*5+[1]*5+[2]*6
# labels中存儲對應的交通工具名稱
labels = ('普通火車', '高鐵', '飛機')# 創建并訓練模型
knn = KNeighborsClassifier(n_neighbors=3,weights='distance')
knn.fit(X, y)# 對未知樣本進行分類
unKnown = [[300, 79, 320, 900],[36.7, 800, 190, 220]]
result = knn.predict(unKnown)
for para, index in zip(unKnown, result):print(para, labels[index], sep=':')
[300, 79, 320, 900]:普通火車
[36.7, 800, 190, 220]:飛機

KMeans聚類分析算法原理與應用

顏色圖像處理

import numpy as np
from sklearn.cluster import KMeans
from PIL import Image
import matplotlib.pyplot as plt
from copy import deepcopy# 打開并讀取原始圖像中像素顏色值,轉換為三維數組
imOrigin = Image.open('顏色壓縮測試圖像.jpg')
dataOrigin = np.array(imOrigin)
# 然后再轉換為二維數組,-1表示自動計算該維度的大小
data = dataOrigin.reshape(-1,3)n_clusters = 64
while n_clusters >= 4:plt.cla()print(n_clusters)    # 使用KMeans算法把所有像素的顏色值劃分為4類kmeansPredicter = KMeans(n_clusters=n_clusters)kmeansPredicter.fit(data)# 使用每個像素所屬類的中心值替換該像素的顏色# temp中存放每個數據所屬類的標簽temp = kmeansPredicter.labels_dataNew = kmeansPredicter.cluster_centers_[temp]data = deepcopy(dataNew)dataNew = np.uint8(dataNew)    dataNew.shape = dataOrigin.shapeplt.imshow(dataNew)plt.pause(0.01)n_clusters //= 2

KMeans聚類算法壓縮圖像顏色

import numpy as np
from sklearn.cluster import KMeans
from PIL import Image
import matplotlib.pyplot as plt# 打開并讀取原始圖像中像素顏色值,轉換為三維數組
imOrigin = Image.open('顏色壓縮測試圖像.jpg')
dataOrigin = np.array(imOrigin)
# 然后再轉換為二維數組,-1表示自動計算該維度的大小
data = dataOrigin.reshape(-1,3)# 使用KMeans算法把所有像素的顏色值劃分為4類
kmeansPredicter = KMeans(n_clusters=4, n_init=10)
kmeansPredicter.fit(data)# 使用每個像素所屬類的中心值替換該像素的顏色
# temp中存放每個數據所屬類的標簽
temp = kmeansPredicter.labels_
dataNew = kmeansPredicter.cluster_centers_[temp]
dataNew = np.uint8(dataNew)
dataNew.shape = dataOrigin.shape
plt.imshow(dataNew)
plt.imsave('結果圖像.jpg', dataNew)
plt.show()

分層聚類算法原理與應用

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.cluster import AgglomerativeClusteringdef AgglomerativeTest(n_clusters):assert 1 <= n_clusters <= 4predictResult = AgglomerativeClustering(n_clusters=n_clusters,linkage='ward').fit_predict(data)# 定義繪制散點圖時使用的顏色和散點符號colors = 'rgby'markers = 'o*v+'# 依次使用不同的顏色和符號繪制每個類的散點圖for i in range(n_clusters):subData = data[predictResult==i]plt.scatter(subData[:,0], subData[:,1], c=colors[i], marker=markers[i], s=40)plt.show()# 生成隨機數據,200個點,分成4類,返回樣本及標簽
data, labels = make_blobs(n_samples=200, centers=4)
print(data)
AgglomerativeTest(4)

DBSCAN算法原理與應用

  • 基于密度相連對象的最大集合
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import DBSCAN
from sklearn.datasets import make_blobsdef DBSCANtest(data, eps=0.6, min_samples=8):# 聚類db = DBSCAN(eps=eps, min_samples=min_samples).fit(data)# 聚類標簽(數組,表示每個樣本所屬聚類)和所有聚類的數量# 標簽-1對應的樣本表示噪點clusterLabels = db.labels_uniqueClusterLabels = set(clusterLabels)# 標記核心對象對應下標為TruecoreSamplesMask = np.zeros_like(db.labels_, dtype=bool)coreSamplesMask[db.core_sample_indices_] = True# 繪制聚類結果colors = ['red', 'green', 'blue', 'gray', '#88ff66','#ff00ff', '#ffff00', '#8888ff', 'black',]markers = ['v', '^', 'o', '*', 'h', 'd', 'D', '>', 'x']for label in uniqueClusterLabels:# 使用最后一種顏色和符號繪制噪聲樣本# clusterIndex是個True/False數組# 其中True表示對應樣本為cluster類clusterIndex = (clusterLabels==label)# 繪制核心對象coreSamples = data[clusterIndex&coreSamplesMask]plt.scatter(coreSamples[:, 0], coreSamples[:, 1],c=colors[label], marker=markers[label],s=100)# 繪制非核心對象nonCoreSamples = data[clusterIndex & ~coreSamplesMask]plt.scatter(nonCoreSamples[:, 0], nonCoreSamples[:, 1],c=colors[label], marker=markers[label],s=20)plt.show()data, labels = make_blobs(n_samples=300, centers=5)
DBSCANtest(data)
#DBSCANtest(data, 0.8, 15)

協同過濾算法進行電影推薦(期末考試重點)

  • 協同過濾算法常用于商品推薦或者類似的場合,根據用戶之間或商品之間的相似性進行精準推薦,可以分為基于用戶的協同過濾算法和基于商品的協同過濾算法。
  • 以電影推薦為例,假設用戶1喜歡看電影A、B、C、D、G,用戶2喜歡看電影A、D、E、F,用戶3喜歡看電影A、B、D,現在用戶3想再看個沒看過的電影,向用戶1和用戶2尋求推薦。簡單分析易知,與用戶2相比,用戶1和用戶3更相似,所以根據用戶1喜歡的電影進行推薦,也就是用戶1看過但用戶3還沒看過的電影C或G。

協同過濾算法是推薦系統中最常用的方法之一,以下是對您描述內容的進一步整理和分析:


協同過濾算法的基本概念

  • 協同過濾算法的核心思想是利用用戶或商品之間的相似性,推薦用戶可能感興趣的內容。
  • 分類
    1. 基于用戶的協同過濾:根據用戶之間的相似性推薦商品。
    2. 基于商品的協同過濾:根據商品之間的相似性推薦商品。

以電影推薦為例

數據:
  • 用戶1看過:A、B、C、D、G
  • 用戶2看過:A、D、E、F
  • 用戶3看過:A、B、D
  • 目標:為用戶3推薦一部電影。
分析:
  1. 計算用戶相似性

    • 用戶3與用戶1的共有電影:A、B、D,共3部。
    • 用戶3與用戶2的共有電影:A、D,共2部。
    • 結論:用戶3與用戶1更相似。
  2. 推薦過程

    • 找出用戶1看過但用戶3沒看過的電影:C、G。
    • 推薦結果:C 或 G。

協同過濾算法的步驟

1. 數據表示

構建用戶-商品偏好矩陣。例如:

        A   B   C   D   E   F   G
用戶1    1   1   1   1   0   0   1
用戶2    1   0   0   1   1   1   0
用戶3    1   1   0   1   0   0   0

其中:

  • 1 表示用戶看過某電影。
  • 0 表示用戶沒看過某電影。
2. 計算相似性
  • 使用相似性度量方法(如余弦相似度、皮爾遜相關系數)計算用戶之間的相似性。
  • 例如,余弦相似度公式:

相似度 ( 用戶 A , 用戶 B ) = A和B的交集數 A的電影數 × B的電影數 \text{相似度}(用戶A, 用戶B) = \frac{\text{A和B的交集數}}{\sqrt{\text{A的電影數}} \times \sqrt{\text{B的電影數}}} 相似度(用戶A,用戶B)=A的電影數 ?×B的電影數 ?AB的交集數?

3. 推薦候選集
  • 找出與目標用戶最相似的用戶。
  • 從相似用戶看過但目標用戶未看過的商品中選擇推薦。
4. 生成推薦
  • 對候選商品進行排序(例如根據相似用戶的評分權重排序)。
  • 推薦排名靠前的商品。

優缺點

優點:
  • 簡單易實現,推薦結果可解釋性強。
  • 無需商品的具體內容信息,適用于各種類型的數據。
缺點:
  • 冷啟動問題:對新用戶或新商品,缺乏足夠的數據支撐相似性計算。
  • 稀疏性問題:用戶-商品矩陣通常非常稀疏,可能導致相似性難以計算準確。
  • 擴展性問題:隨著用戶和商品數量的增加,計算相似性可能變得非常耗時。

改進方向

  1. 結合內容信息:在協同過濾中加入商品的內容特征(如電影的類型、導演信息)。
  2. 矩陣分解:將用戶-商品矩陣分解為低維的用戶和商品向量,例如 SVD(奇異值分解)。
  3. 引入深度學習:使用神經網絡建模用戶和商品的關系,例如通過嵌入層學習用戶和商品的隱式特征。

from random import randrange
#模擬歷史電影打分數據,共10個用戶,每個用戶打分的電影數量不等
data = {'user'+str(i):{'film'+str(randrange(1, 15)):randrange(16)for j in range (randrange(310))}for i in range(10)}
# 尋求推薦的用戶對電影打分的數據
user = {'film'+str (randrange (1, 15)):randrange (1, 6) for i in range (5)}
#最相似的用戶及其對電影打分情況
#兩個最相似的用戶共同打分的電影最多,同時所有電影打分差值的平方和最小
rule = lambda item:(-len(item[1].keys ()&user)sum(((item[1].get(film) -user.get (film))**2for film in user.keys()&item[1].keys())))
similarUser, films = min(data.items (),key=rule)
#輸出信息以便驗證,每行數據有3列
#分別為該用戶與當前用戶共同打分的電影數量、打分差的平方和、該用戶打分數據
print ('known data'.center(50,'='))
for item in data.items ():print (len(item[1].keys ()&user.keys())sum(((item[l].get(film) -user.get (film))**2for film in user.keys ()&item[l].keys())),item, sep=':')
print('current user'.center (50, '='),user, sep='ln')
print('most similar user and his films'.center (50, '='))
print(similarUser, films, sep=':')print ('recommended film'.center(50, '='))
#在當前用戶沒看過的電影中選擇打分最高的進行推薦
print (max (films.keys ()-user.keys (), key=lanbda film: films[film]))

關聯規則分析(期末考試重點)

常用概念:

  • 項集:包含若干物品或條目的集合。包含k的物品的集合稱作k-項集。
  • 頻繁項集:經常一起出現的物品的集合。如果某個項集是頻繁的,那么它的所有子集都是頻繁的;如果某個項集不是頻繁的,那么它的所有超集都不是頻繁的。這一點是避免頁集數量過多的重要基礎,使得快速計算頻繁項集成為可能。
  • 關聯規則:可以表示為一個蘊含式R:X==>Y,其中X&Y為空集。這樣一條關聯規則的含義是,如果X發生,那么Y很可能也會發生。

項集

  • 定義:項集是由若干物品(或條目)組成的集合。
  • k-項集:如果一個項集中包含 ( k ) 個物品,則稱其為 ( k )-項集。
    • 例子:在購物籃分析中,{牛奶, 面包} 是一個 2-項集。

頻繁項集

  • 定義:頻繁項集是指在數據集中經常出現的項集,滿足用戶設定的最小支持度閾值。

    • 支持度:某個項集在數據集中出現的次數占總事務數的比例。
    • 例子:如果 {牛奶, 面包} 出現在 60% 的交易中,并且最小支持度設定為 50%,則該項集為頻繁項集。
  • 性質

    1. 子集性質
      • 如果一個項集是頻繁項集,則它的所有子集也是頻繁項集。
    2. 剪枝性質
      • 如果一個項集不是頻繁項集,則它的所有超集都不是頻繁項集。
    • 作用:利用這些性質可以減少計算項集的數量,提高頻繁項集挖掘的效率。

關聯規則

  • 定義:關聯規則是從頻繁項集中挖掘出的規則,表示某些物品之間的關聯關系。規則的形式為:
    R : X ? Y R: X \implies Y R:X?Y

    • 解釋:如果項集 ( X ) 發生,則 ( Y ) 很可能也會發生。
    • 例子:{牛奶} ? {面包},表示購買牛奶的人很可能也會購買面包。
  • 指標

    1. 支持度 (Support)
    • 規則:
      

      X ? Y X \implies Y X?Y的支持度是 X ∪ Y X \cup Y XY出現的概率。
      S u p p o r t ( X ? Y ) = 事務中同時包含? X 和? Y 的置信度 X 發生時 Y 也發生的概率。 Support(X \implies Y )= \frac{\text{事務中同時包含 } X \text{ 和 } Y \text{的} 置信度 }{X 發生時 Y 也發生的概率。} Support(X?Y)=X發生時Y也發生的概率。事務中同時包含?X??Y置信度?

      C o n f i d e n c e ( X ? Y ) = 事務中同時包含? X 和? Y 的次數 事務表示?X?和?Y?是否獨立。 Confidence(X \implies Y) = \frac{\text{事務中同時包含 } X \text{ 和 } Y \text{ 的次數}}{\text{事務表示 X 和 Y 是否獨立。}} Confidence(X?Y)=事務表示?X??Y?是否獨立。事務中同時包含?X??Y?的次數?

      L i f t ( X ? Y ) = C o n f i d e n c e ( X ? Y ) S u p p o r t ( Y ) Lift(X \implies Y) = \frac{Confidence(X \implies Y)}{Support(Y)} Lift(X?Y)=Support(Y)Confidence(X?Y)?

  • 例子

    • 給定事務數據:
      T1: {牛奶, 面包, 黃油}
      T2: {牛奶, 面包}
      T3: {牛奶, 黃油}
      T4: {面包, 黃油}
      
    • 規則 {牛奶} ? {面包}:
      • 支持度:2/4 = 50%
      • 置信度:2/3 ≈ 66.7%

總結

  • 項集:物品的集合,包含 ( k ) 個物品的集合稱為 ( k )-項集。
  • 頻繁項集:滿足最小支持度閾值,且具有子集和超集性質。
  • 關聯規則:從頻繁項集中挖掘的規則,描述物品之間的關聯性,通常通過支持度、置信度和提升度來衡量規則的質量。

代碼實現(例如 Apriori 或 FP-Growth 算法)

import pandas as pd
# 使用關聯規則算法分析演員關系
ws = pd.read_excel('電影導演演員.xlsx')
print(ws.head())
  電影名稱   導演               演員
0  電影1  導演1  演員1,演員2,演員3,演員4
1  電影2  導演2  演員3,演員2,演員4,演員5
2  電影3  導演3  演員1,演員5,演員3,演員6
3  電影4  導演1  演員1,演員4,演員3,演員7
4  電影5  導演2  演員1,演員2,演員3,演員8
from itertools import chain, combinations
from openpyxl import load_workbookdef loadDataSet():'''加載數據,返回包含若干集合的列表'''# 返回的數據格式為 [{1, 3, 4}, {2, 3, 5}, {1, 2, 3, 5}, {2, 5}]result = []# xlsx文件中有3列,分別為電影名稱、導演名稱、演員清單# 同一個電影的多個主演演員使用逗號分隔ws = load_workbook('電影導演演員.xlsx').worksheets[0]for index, row in enumerate(ws.rows):# 跳過第一行表頭if index==0:continueresult.append(set(row[2].value.split(',')))return resultdef createC1(dataSet):'''dataSet為包含集合的列表,每個集合表示一個項集返回包含若干元組的列表,每個元組為只包含一個物品的項集,所有項集不重復'''return sorted(map(lambda i:(i,), set(chain(*dataSet))))def scanD(dataSet, Ck, Lk, minSupport):'''dataSet為包含集合的列表,每個集合表示一個項集ck為候選項集列表,每個元素為元組minSupport為最小支持度閾值返回Ck中支持度大于等于minSupport的那些項集'''# 數據集總數量total = len(dataSet)supportData = {}for candidate in Ck:# 加速,k-頻繁項集的所有k-1子集都應該是頻繁項集if Lk and (not all(map(lambda item: item in Lk,combinations(candidate,len(candidate)-1)))):continue# 遍歷每個候選項集,統計該項集在所有數據集中出現的次數# 這里隱含了一個技巧:True在內部存儲為1set_candidate = set(candidate)frequencies = sum(map(lambda item: set_candidate<=item,dataSet))# 計算支持度t = frequencies/total# 大于等于最小支持度,保留該項集及其支持度if t >= minSupport:supportData[candidate] = treturn supportDatadef aprioriGen(Lk, k):'''根據k項集生成k+1項集'''result = []for index, item1 in enumerate(Lk):for item2 in Lk[index+1:]:# 只合并前k-2項相同的項集,避免生成重復項集# 例如,(1,3)和(2,5)不會合并,# (2,3)和(2,5)會合并為(2,3,5),# (2,3)和(3,5)不會合并,# (2,3)、(2,5)、(3,5)只能得到一個項集(2,3,5)if sorted(item1[:k-2]) == sorted(item2[:k-2]):result.append(tuple(set(item1)|set(item2)))return resultdef apriori(dataSet, minSupport=0.5):'''根據給定數據集dataSet,返回所有支持度>=minSupport的頻繁項集'''C1 = createC1(dataSet)supportData = scanD(dataSet, C1, None, minSupport)k = 2while True:# 獲取滿足最小支持度的k項集Lk = [key for key in supportData if len(key)==k-1]# 合并生成k+1項集Ck = aprioriGen(Lk, k)# 篩選滿足最小支持度的k+1項集supK = scanD(dataSet, Ck, Lk, minSupport)# 無法再生成包含更多項的項集,算法結束if not supK:breaksupportData.update(supK)k = k+1return supportDatadef findRules(supportData, minConfidence=0.5):'''查找滿足最小置信度的關聯規則'''# 對頻繁項集按長度降序排列supportDataL = sorted(supportData.items(),key=lambda item:len(item[0]),reverse=True)rules = []for index, pre in enumerate(supportDataL):for aft in supportDataL[index+1:]:# 只查找k-1項集到k項集的關聯規則if len(aft[0]) < len(pre[0])-1:break# 當前項集aft[0]是pre[0]的子集# 且aft[0]==>pre[0]的置信度大于等于最小置信度閾值if set(aft[0])<set(pre[0]) and\pre[1]/aft[1]>=minConfidence:rules.append([pre[0],aft[0]])return rules# 加載數據
dataSet = loadDataSet()
# 獲取所有支持度大于0.2的項集
supportData = apriori(dataSet, 0.2)
# 在所有頻繁項集中查找并輸出關系較好的演員二人組合
bestPair = [item for item in supportData if len(item)==2]
print(bestPair)# 查找支持度大于0.6的強關聯規則
for item in findRules(supportData, 0.6):pre, aft = map(set, item)print(aft, pre-aft, sep='==>')
[('演員1', '演員3'), ('演員1', '演員4'), ('演員3', '演員4'), ('演員3', '演員5'), ('演員4', '演員9')]
{'演員1', '演員4'}==>{'演員3'}
{'演員1'}==>{'演員3'}
{'演員1'}==>{'演員4'}
{'演員3'}==>{'演員4'}
{'演員4'}==>{'演員3'}
{'演員5'}==>{'演員3'}
{'演員9'}==>{'演員4'}

數據降維

交叉驗證、網格搜索、學習曲線

1.評估模型的泛化能力

from time import time
from os import listdir
from os.path import basename
from PIL import Image
from sklearn import svm
from sklearn.model_selection import cross_val_score,\ShuffleSplit, LeaveOneOut# 圖像尺寸
width, height = 30, 60def loadDigits(dstDir='datasets'):# 獲取所有圖像文件名digitsFile = [dstDir+'/'+fn for fn in listdir(dstDir)if fn.endswith('.jpg')]# 按編號排序digitsFile.sort(key=lambda fn: int(basename(fn)[:-4]))# digitsData用于存放讀取的圖片中數字信息# 每個圖片中所有像素值存放于digitsData中的一行數據digitsData = []for fn in digitsFile:with Image.open(fn) as im:data = [sum(im.getpixel((w,h)))/len(im.getpixel((w,h)))for w in range(width)for h in range(height)]digitsData.append(data)# digitsLabel用于存放圖片中數字的標準分類with open(dstDir+'/digits.txt') as fp:digitsLabel = fp.readlines()digitsLabel = [label.strip() for label in digitsLabel]return (digitsData, digitsLabel)# 加載數據
data = loadDigits()
print('數據加載完成。')# 創建模型
svcClassifier = svm.SVC(kernel="linear", C=1000, gamma=0.001)# 交叉驗證
start = time()
scores = cross_val_score(svcClassifier, data[0], data[1], cv=8)
print('交叉驗證(k折疊)得分情況:\n', scores)
print('平均分:\n', scores.mean())
print('用時(秒):', time()-start)
print('='*20)start = time()
scores = cross_val_score(svcClassifier, data[0], data[1],cv=ShuffleSplit(test_size=0.3,train_size=0.7,n_splits=10))
print('交叉驗證(隨機拆分)得分情況:\n', scores)
print('平均分:\n', scores.mean())
print('用時(秒):', time()-start)
print('='*20)start = time()
scores = cross_val_score(svcClassifier, data[0], data[1],cv=LeaveOneOut())
print('交叉驗證(逐個測試)得分情況:\n', scores)
print('平均分:\n', scores.mean())
print('用時(秒):', time()-start)

2.使用網格搜索確定最佳參數

from time import time
from os import listdir
from os.path import basename
from PIL import Image
from sklearn import svm
from sklearn.model_selection import GridSearchCV# 圖像尺寸
width, height = 30, 60def loadDigits(dstDir='datasets'):# 獲取所有圖像文件名digitsFile = [dstDir+'/'+fn for fn in listdir(dstDir)if fn.endswith('.jpg')]# 按編號排序digitsFile.sort(key=lambda fn: int(basename(fn)[:-4]))# digitsData用于存放讀取的圖片中數字信息# 每個圖片中所有像素值存放于digitsData中的一行數據digitsData = []for fn in digitsFile:with Image.open(fn) as im:data = [sum(im.getpixel((w,h)))/len(im.getpixel((w,h)))for w in range(width)for h in range(height)]digitsData.append(data)# digitsLabel用于存放圖片中數字的標準分類with open(dstDir+'/digits.txt') as fp:digitsLabel = fp.readlines()digitsLabel = [label.strip() for label in digitsLabel]return (digitsData, digitsLabel)# 加載數據
data = loadDigits()
print('數據加載完成。')# 創建模型
svcClassifier = svm.SVC()
# 待測試的參數
parameters = {'kernel': ('linear', 'rbf'),'C': (0.001, 1, 1000),'gamma':(0.001, 1, 10)}# 網格搜索
start = time()
clf = GridSearchCV(svcClassifier, parameters)
clf.fit(data[0], data[1])
# 解除注釋可以查看詳細結果
# print(clf.cv_results_)
print(clf.best_params_)
print('得分:', clf.score(data[0], data[1]))
print('用時(秒):', time()-start)
數據加載完成。

3.繪制學習曲線

from os import listdir
from os.path import basename, join
import numpy as np
from PIL import Image
from sklearn import svm
from sklearn.model_selection import learning_curve, ShuffleSplit
import matplotlib.pyplot as plt# 圖像尺寸
width, height = 30, 60
def loadDigits(dstDir='datasets'):# 獲取所有圖像文件名digitsFile = [join(dstDir,fn) for fn in listdir(dstDir)if fn.endswith('.jpg')]# 按編號排序digitsFile.sort(key=lambda fn: int(basename(fn)[:-4]))# digitsData用于存放讀取的圖片中數字信息# 每個圖片中所有像素值存放于digitsData中的一行數據digitsData = []for fn in digitsFile:with Image.open(fn) as im:# 原始圖像尺寸不一樣,先調整成統一尺寸,確保每個子列表的長度相同digitsData.append(np.array(im.resize((width,height))).mean(axis=2).flatten('F').tolist())# digitsLabel用于存放圖片中數字的標準分類with open(fr'{dstDir}/digits.txt') as fp:digitsLabel = fp.read().splitlines(keepends=False)return (digitsData, digitsLabel)# 加載數據
X, y = loadDigits()
print('數據加載完成。')svcClassifier = svm.SVC(kernel='linear', C=1000, gamma=0.001)
# 使用20%的樣本進行測試,80%的樣本進行訓練,重復10次,計算每次的得分
cv = ShuffleSplit(test_size=0.2, train_size=0.8, n_splits=10)
# 使用交叉驗證計算不同數量樣本作為訓練集時的模型平均得分
train_sizes, train_scores, test_scores = learning_curve(svcClassifier, X, y, cv=cv,train_sizes=np.linspace(0.1,1.0,10))
# 對于不同大小的訓練集10次訓練與測試結果得分求均值
train_scores = np.mean(train_scores, axis=1)
test_scores = np.mean(test_scores, axis=1)plt.plot(train_sizes, train_scores, 'r-o', lw=2, label='training score')
plt.plot(train_sizes, test_scores, 'g--v', lw=2, label='cross validation score')
plt.legend()plt.show()

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/84420.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/84420.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/84420.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

在 Java 中實現一個標準 Service 接口,并通過配置動態選擇具體實現類供 Controller 調用

在 Java 中實現一個標準 Service 接口&#xff0c;并通過配置動態選擇具體實現類供 Controller 調用&#xff0c;是解耦和靈活擴展的常見設計模式。 需求分析 當你需要開發一個需要靈活切換業務實現的系統&#xff0c;比如不同環境使用不同策略&#xff08;如測試環境用Mock實…

input+disabled/readonly問題

背景&#xff1a; vue2elementui <el-input v-model"inputForm.projectName" class"input-font" :disabled"projectDisabled" placeholder"請選擇" :readonly"isReadonly"><el-button slot"append"…

Office2019下載安裝教程(2025最新永久方法)(附安裝包)

文章目錄 Office2019安裝包下載Office2019一鍵安裝步驟&#xff08;超詳細&#xff01;&#xff09; 大家好&#xff01;今天給大家帶來一篇超實用的Office2019專業版安裝教程&#xff01;作為日常辦公和學習的必備軟件&#xff0c;Office的安裝對很多朋友來說可能有點復雜&…

【編譯工具】(版本控制)Git + GitHub Actions:自動化工作流如何讓我的開發效率提升200%?

目錄 引言&#xff1a;現代開發中版本控制和 CI/CD 的重要性 一、Git&#xff1a;為什么它是版本控制的首選&#xff1f; &#xff08;1&#xff09;Git 的核心優勢 &#xff08;2&#xff09;Git 高效工作流示例 ① 功能開發流程 ② 緊急修復流程 二、GitHub Acti…

碼蹄杯真題分享

我的個人主頁 我的專欄&#xff1a; 人工智能領域、java-數據結構、Javase、C語言&#xff0c;MySQL&#xff0c;希望能幫助到大家&#xff01;&#xff01;&#xff01; 點贊&#x1f44d;收藏? 1&#xff1a;房間打掃&#xff08;題目鏈接&#xff09; 思路&#xff1a;要想…

小米玄戒O1架構深度解析(二):多核任務調度策略詳解

上篇文章中&#xff0c;就提到了小米玄戒O1的多核任務調度策略&#xff0c;但講得不夠詳細&#xff0c;尤其是對于完全公平調度器和能效感知調度&#xff0c;這次我們就深度剖析一下這兩種調度策略。 目錄 1. 完全公平調度器&#xff08;CFS&#xff09;1.1 完全公平調度基本原…

【技巧】win10和ubuntu互相掛在共享文件夾

回到目錄 【技巧】win10和ubuntu互相掛在共享文件夾 1. ubuntu掛載win10共享文件夾 $ sudo apt update $ sudo apt install cifs-utils $ sudo mkdir /mnt/[這里改為ubuntu共享目錄名] $ sudo mount -t cifs -o usernameadministrator //[這里改為win10機器IP]/[這里改為win…

線程(下)【Linux操作系統】

文章目錄 線程控制線程共享進程地址空間中的所有數據線程會瓜分進程的時間片線程相關庫函數庫函數&#xff1a;pthread_create庫函數&#xff1a;pthread_self庫函數&#xff1a;pthread_join庫函數&#xff1a;pthread_exit庫函數&#xff1a;pthread_cancel[盡量少用]庫函數&…

Linux 任務調度策略

&#x1f31f; 概述 Linux 內核以線程&#xff08;任務&#xff09;為單位進行調度&#xff0c;支持 SCHED_FIFO 和 SCHED_RR&#xff08;實時調度&#xff09;以及 SCHED_OTHER&#xff08;基于 CFS&#xff0c;非實時調度&#xff09;。 &#x1f50d; 調度策略 1. SCHED_…

芯片金屬層M1、M2區別

在芯片設計中&#xff0c;M1&#xff08;第一層金屬&#xff09;和 M2&#xff08;第二層金屬&#xff09;是常見的金屬層&#xff0c;它們在用途、布線方向、設計規則和應用場景等方面存在一些主要區別。以下是詳細對比&#xff1a; 1. 用途 M1&#xff08;第一層金屬&#x…

Linux離線環境下安裝Lean 4開發環境的完整指南

文章目錄 一、準備工作1. 在線環境下載必要文件2. 傳輸文件至離線環境 二、安裝elan工具鏈管理器1. 解壓并安裝elan2. 配置環境變量3. 驗證elan安裝 三、安裝Lean 4二進制包1. 解壓Lean 4二進制文件2. 注冊工具鏈到elan 四、安裝VS Code Lean 4插件1. 使用VS Code界面安裝插件 …

ffmpeg windows 32位編譯

ffmpeg windows 32位編譯 編譯后程序下載 編譯方式 自動編譯工具套件 – https://github.com/m-ab-s/media-autobuild_suite github克隆完成后&#xff0c;雙擊bat文件打開編譯窗口&#xff0c;注意git檢出的目錄需要簡短&#xff0c;最好選一個盤的根目錄。 選擇編譯版本…

P1216 [IOI 1994] 數字三角形 Number Triangles

題目描述 觀察下面的數字金字塔。 寫一個程序來查找從最高點到底部任意處結束的路徑&#xff0c;使路徑經過數字的和最大。每一步可以走到左下方的點也可以到達右下方的點。 在上面的樣例中&#xff0c;從 7 → 3 → 8 → 7 → 5 7 \to 3 \to 8 \to 7 \to 5 7→3→8→7→5 的…

(二)原型模式

原型的功能是將一個已經存在的對象作為源目標,其余對象都是通過這個源目標創建。發揮復制的作用就是原型模式的核心思想。 一、源型模式的定義 原型模式是指第二次創建對象可以通過復制已經存在的原型對象來實現,忽略對象創建過程中的其它細節。 ?? 核心特點: 避免重復初…

Css實現懸浮對角線邊框動效

動畫效果展示 鼠標懸停時&#xff0c;一個帶有圓角的水綠色邊框會從右上和左下兩個方向快速展開&#xff0c;隨后顏色緩慢填充&#xff1b;移出鼠標時顏色先褪去&#xff0c;邊框再快速收縮消失&#xff0c;形成具有節奏感的呼吸式動畫。 &#x1f4dc; 動畫原理說明 一、核…

技術創新究竟包含什么?

技術創新指的是引入新技術或改進現有技術&#xff0c;以創造新穎且更優的產品、服務或流程的過程。它涉及應用科學和技術知識開發創新解決方案&#xff0c;以創造價值、提高效率、推動增長&#xff0c;并滿足用戶和客戶不斷變化的需求。 技術創新可以有多種形式&#xff0c;例…

ArcGIS+AI:涵蓋AI大模型應用、ArcGIS功能詳解、Prompt技巧、AI助力的數據處理、空間分析、遙感分析、二次開發及綜合應用等

&#x1f310; GIS憑借其強大的空間數據處理能力、先進的空間分析工具、靈活的地圖制作與可視化功能&#xff0c;以及廣泛的擴展性和定制性&#xff0c;已成為地理信息科學的核心工具。它在城市規劃、環境科學、交通管理等多個學科領域發揮著至關重要的作用。與此同時&#xff…

數據淘金時代:公開爬取如何避開法律雷區?

首席數據官高鵬律師團隊編著 一、“數字淘金熱”里的暗礁&#xff1a;那些被爬垮的平臺和賠哭的公司 前陣子某電商平臺的“商品比價爬蟲”上了熱搜&#xff0c;技術小哥本想靠抓競品數據優化定價&#xff0c;結果收到法院傳票——對方服務器被爬癱瘓&#xff0c;索賠300萬。這…

在ARM 架構的 Mac 上 更新Navicat到17后連接Oracle時報錯:未加載 Oracle 庫。

一&#xff1a;問題 使用的M1芯片的Mac&#xff0c;將Navicat更新到了17版本后&#xff0c;原本正常的Oracle數據庫無法連接&#xff0c;報錯&#xff1a;未加載 Oracle 庫。而sqlserver庫可以正常連接 二&#xff1a;解決方法 打開聚焦搜索——〉打開訪達——〉在應用程序中…

Springboot仿抖音app開發之用短視頻務模塊后端復盤及相關業務知識總結

Springboot仿抖音app開發之用戶業務模塊后端復盤及相關業務知識總結 BO類和VO類的區別 BO (Business Object) - 業務對象 定義: 業務對象是包含業務邏輯的領域模型用途: 主要用于封裝業務邏輯相關的數據&#xff0c;在業務層(Service層)之間傳遞特點: 與業務處理密切相關通常…