文章目錄
- 機械學習
- 機械學習分類
- 1. 監督學習
- 2. 半監督學習
- 3. 無監督學習
- 4. 強化學習
- 機械學習的項目開發步驟
- scikit-learn
- 1 scikit-learn安裝
- 2 sklearn數據集
- 1. sklearn 玩具數據集
- 鳶尾花數據集
- 糖尿病數據集
- 葡萄酒數據集
- 2. sklearn現實世界數據集
- 20 新聞組數據集
- 3. 數據集的劃分
- 特征工程
- 1 DictVectorizer - 字典列表特征提取
- 2 CountVectorizer - 文本特征提取
- 英文文本提取
- 中文文本提取
- 3 TfidfVectorizer TF-IDF - 文本特征詞的重要程度特征提取
- 4 無量綱化-預處理
- 1. MaxAbsScaler
- 2. normalize歸一化
- 3. StandardScaler
機械學習
機器學習(Machine Learning, ML)是人工智能(AI)的核心分支之一,其核心思想是讓計算機通過對數據的學習,自動發現規律、改進性能,并用于解決預測、決策、模式識別等問題。與傳統編程 “手動編寫規則” 不同,機器學習通過算法從數據中 “自主學習” 規律,實現對未知數據的有效處理。
機器學習的本質是 “從數據中學習”:
- 無需人類顯式編寫處理規則,而是通過算法從大量數據中挖掘潛在模式(如特征與結果的關聯)。
- 隨著數據量增加或訓練迭代,模型性能會逐漸優化(“學習” 過程)。
機械學習分類
根據數據是否包含 “標簽”(即是否有明確的輸出結果),機器學習可分為以下幾類:
1. 監督學習
- 特點:訓練數據包含 “輸入特征” 和對應的 “標簽(輸出結果)”,模型通過學習特征與標簽的映射關系,實現對新數據的預測。
- 典型任務
- 分類(Classification):預測離散標簽(如 “垃圾郵件 / 正常郵件”“腫瘤良性 / 惡性”)。
- 回歸(Regression):預測連續數值(如房價、氣溫、股票價格)。
- 常見算法:線性回歸、邏輯回歸、決策樹、隨機森林、支持向量機(SVM)、神經網絡等。
2. 半監督學習
- 特點:訓練數據中只有少量標簽,大部分為無標簽數據,模型結合兩種數據進行學習(適用于標簽獲取成本高的場景,如醫學影像標注)。
- 典型應用:文本分類(少量標注文本 + 大量未標注文本訓練模型)。
3. 無監督學習
- 特點:訓練數據只有 “輸入特征”,無標簽,模型需自主發現數據中的隱藏結構(如聚類、分布規律)。
- 典型任務
- 聚類(Clustering):將相似數據分組(如用戶分群、商品分類)。
- 降維(Dimensionality Reduction):簡化數據維度(如將高維圖像特征壓縮為低維向量,便于可視化或計算)。
- 異常檢測(Anomaly Detection):識別與多數數據差異顯著的樣本(如信用卡欺詐檢測)。
- 常見算法:K-Means 聚類、層次聚類、主成分分析(PCA)、t-SNE(降維可視化)等。
4. 強化學習
- 特點:模型通過與環境的 “交互” 學習:智能體(Agent)在環境中執行動作,根據動作結果獲得 “獎勵” 或 “懲罰”,最終學習出最大化累積獎勵的策略。
- 典型任務:游戲 AI(如 AlphaGo 下棋)、機器人控制(如自動駕駛避障)、資源調度等。
- 常見算法:Q-Learning、策略梯度(Policy Gradient)、深度強化學習(如 DQN)等。
機械學習的項目開發步驟
1.數據集的收集與獲取:
- 確定數據來源:從數據庫、API、文件或第三方獲取數據。
- 數據采集:編寫腳本或使用工具(如 Scrapy、Pandas)收集數據。
- 數據標注:如果是監督學習,需標注訓練數據(如人工標注圖像分類標簽)。
2.數據預處理:
- 特征工程
- 特征提取:從原始數據中提取有用特征(如文本分詞、圖像特征提取)。
- 特征轉換:標準化 / 歸一化數值特征,編碼分類特征。
- 特征選擇:篩選對目標變量最有預測力的特征。
- 數據集劃分:將數據分為訓練集、驗證集和測試集
3.模型選擇與訓練
以模型的形式選擇適當的算法和數據表示
清理后的數據分為兩部分 - 訓練和測試。第一部分(訓練數據)用于開發模型。第二部分(測試數據)用作參考依據。
4.模型評估與優化
使用驗證集評估模型性能,選擇合適的評估指標
scikit-learn
Scikit-learn(簡稱 sklearn)是 Python 中最流行的開源機器學習庫之一,提供了豐富的工具和算法,用于數據預處理、模型選擇、訓練和評估。
Scikit-learn官網:https://scikit-learn.org/stable/#
1 scikit-learn安裝
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple scikit-learn
2 sklearn數據集
1. sklearn 玩具數據集
無需額外下載:直接通過 sklearn 導入,方便快捷。
鳶尾花數據集
- 樣本數:150 條。
- 特征數:4 個(花萼長度、花萼寬度、花瓣長度、花瓣寬度)。
from sklearn.datasets import load_iris
# 加載數據集
iris = load_iris()
print(iris)#--字典
print(iris.data)#數據每一朵花的特征值(特點數據,特征數據)
print(iris.feature_names)#特征名稱:萼片長、萼片寬、花瓣長、花瓣寬
print(iris.target)#每朵花的標簽:0、1、2
print(iris.target_names)#標簽名稱:山鳶尾、變色鳶尾、維吉尼亞鳶尾
糖尿病數據集
- 樣本數:442 條。
- 特征數:10 個
- 特征含義
- 年齡
- 性別
- 體質指數(BMI)
- 平均血壓
- S1~S6:血液中 6 種血清指標
- 目標變量
- 一年后糖尿病病情進展的定量測量值(數值越大表示病情越嚴重)
from sklearn.datasets import load_diabetes
# 獲取數據集
diabetes = load_diabetes()
# 查看數據集
# print(diabetes)
#特征值 和 目標值
x,y = load_diabetes(return_X_y=True)
# print(x,y)
print(x.shape,y.shape)#(442, 10) (442,)
print("特征名稱:", diabetes.feature_names)
#['age', 'sex', 'bmi', 'bp', 's1', 's2', 's3', 's4', 's5', 's6']
葡萄酒數據集
- 樣本數:178 個
- 特征數:13 個(均為連續型數值特征)
- 特征含義
- 酒精含量
- 蘋果酸含量
- 灰分
- 灰分堿度
- 鎂含量
- 總酚含量
- 黃酮類化合物含量
- 非黃酮類酚含量
- 原花青素含量
- 顏色強度
- 色調
- 稀釋葡萄酒的 OD280/OD315 值
- 脯氨酸含量
- 目標變量
- 葡萄酒的三個類別
- class_0 有 59 個樣本,class_1 有 71 個樣本,class_2 有 48 個樣本
from sklearn.datasets import load_wine
# 獲取數據集
wine = load_wine()
# 查看數據集
print(wine)
#特征值 和 目標值
x,y = load_wine(return_X_y=True)
# print(x,y)
print(x.shape,y.shape)#(178, 13) (178,)
print("特征名稱:", wine.feature_names)
#['alcohol', 'malic_acid', 'ash', 'alcalinity_of_ash', 'magnesium', 'total_phenols', 'flavanoids', 'nonflavanoid_phenols', 'proanthocyanins', 'color_intensity', 'hue', 'od280/od315_of_diluted_wines', 'proline']
print("類別名稱:", wine.target_names)
#['class_0' 'class_1' 'class_2']
2. sklearn現實世界數據集
使用 fetch_*
函數下載更大的現實世界數據集,這些數據需要聯網獲取并存儲在本地。
20 新聞組數據集
- 任務類型:文本分類(20 個主題)。
- 樣本數:約 20,000 條新聞文章。
- 特征數:文本特征(需通過 TF-IDF 等方法轉換)。
from sklearn.datasets import fetch_20newsgroups
from sklearn import datasets
download_file_path = datasets.get_data_home()
print(datasets.get_data_home())# 獲取20newsgroups數據集
news_data = fetch_20newsgroups(data_home='../src',subset='all')
print(news_data.data[0])
3. 數據集的劃分
scikit-learn 中,將數據集劃分為訓練集(Training Set)和測試集(Test Set)
**sklearn.model_selection.train_test_split(*arrays,**options)
- array 這里用于接收1到多個"列表、numpy數組、稀疏矩陣或padas中的DataFrame"。
- 參數
- test_size 值為0.0到1.0的小數,表示劃分后測試集占的比例
- random_state 隨機種子,確保結果可復現。
- strxxxx 分層劃分,填y
- shuffle:是否在劃分前打亂數據(默認為 True)。
最常用的方法,隨機將數據集劃分為訓練集和測試集。
from sklearn.model_selection import train_test_split
a=[10,20,30,40,50,60,70,80,90,100]
a_train , a_test = train_test_split(a)
# print(a_train,a_test)
#[10, 40, 70, 20, 30, 90, 50] [80, 100, 60]
a=[10,20,30,40,50,60,70,80,90,100]
b=[1,2,3,4,5,6,7,8,9,10]
#指定訓練集和測試集的比例
# a_train , a_test , b_train , b_test = train_test_split(a,b,train_size=5)
# 隨機種子
a_train , a_test , b_train , b_test = train_test_split(a,b,train_size=0.8,random_state=42)
print(a_train,a_test,b_train,b_test)
特征工程
-
實例化轉換器對象,轉換器類有很多,都是Transformer的子類, 常用的子類有:
DictVectorizer 字典特征提取 CountVectorizer 文本特征提取 TfidfVectorizer TF-IDF文本特征詞的重要程度特征提取 MinMaxScaler 歸一化 StandardScaler 標準化 VarianceThreshold 底方差過濾降維 PCA 主成分分析降維
-
轉換器對象調用fit_transform()進行轉換, 其中fit用于計算數據,transform進行最終轉換
fit_transform()可以使用fit()和transform()代替
data_new = transfer.fit_transform(data) 可寫成 transfer.fit(data) data_new = transfer.transform(data)
1 DictVectorizer - 字典列表特征提取
將字典格式的數據(如 JSON)轉換為數值特征矩陣,特別適合處理混合類型(數值 + 分類)的特征。
創建轉換器對象:
sklearn.feature_extraction.DictVectorizer(sparse=True)
參數:
-
sparse=True返回類型為csr_matrix的稀疏矩陣
-
sparse=False表示返回的是數組,數組可以調用.toarray()方法將稀疏矩陣轉換為數組
轉換器對象:
轉換器對象調用**fit_transform(data)**函數,參數data為一維字典數組或一維字典列表,返回轉化后的矩陣或數組
轉換器對象get_feature_names_out()方法獲取特征名
[示例1] 提取為稀疏矩陣對應的數組
from sklearn.feature_extraction import DictVectorizerdata = [{'city': '北京','temperature': 100,'weather': '晴','wind': '微風','humidity': 80, },{'city': '上海','temperature': 80,'weather': '陰','wind': '小風','humidity': 60},{'city': '廣州','temperature': 70,'weather': '雨','wind': '強風','humidity': 40}
]
#模型研究x與y的關系前 必須保證xy中全是數字#創建轉換器
#spare = False 輸出結果為矩陣
transfer = DictVectorizer(sparse = False)
data = transfer.fit_transform(data)
print(data)
# 查看轉換后數據的特征名稱
print(transfer.get_feature_names_out())
[[ 0. 1. 0. 80. 100. 1. 0. 0. 0. 0. 1.][ 1. 0. 0. 60. 80. 0. 1. 0. 1. 0. 0.][ 0. 0. 1. 40. 70. 0. 0. 1. 0. 1. 0.]]
['city=上海' 'city=北京' 'city=廣州' 'humidity' 'temperature' 'weather=晴''weather=陰' 'weather=雨' 'wind=小風' 'wind=強風' 'wind=微風']
[示例2 ]提取為稀疏矩陣
from sklearn.feature_extraction import DictVectorizerdata = [{'city': '北京','temperature': 100,'weather': '晴','wind': '微風','humidity': 80, },{'city': '上海','temperature': 80,'weather': '陰','wind': '小風','humidity': 60},{'city': '廣州','temperature': 70,'weather': '雨','wind': '強風','humidity': 40}
]
#模型研究x與y的關系前 必須保證xy中全是數字#創建轉換器
#sparse = True 返回一個三元組表對象--稀松矩陣
transfer = DictVectorizer(sparse = True)
data = transfer.fit_transform(data)
print(data)
# 查看轉換后數據的特征名稱
print(transfer.get_feature_names_out())
# 稀松矩陣轉換為數組
print(data.toarray())
則輸出為
<Compressed Sparse Row sparse matrix of dtype 'float64'with 15 stored elements and shape (3, 11)>Coords Values(0, 1) 1.0(0, 3) 80.0(0, 4) 100.0(0, 5) 1.0(0, 10) 1.0(1, 0) 1.0(1, 3) 60.0(1, 4) 80.0(1, 6) 1.0(1, 8) 1.0(2, 2) 1.0(2, 3) 40.0(2, 4) 70.0(2, 7) 1.0(2, 9) 1.0
['city=上海' 'city=北京' 'city=廣州' 'humidity' 'temperature' 'weather=晴''weather=陰' 'weather=雨' 'wind=小風' 'wind=強風' 'wind=微風']
[[ 0. 1. 0. 80. 100. 1. 0. 0. 0. 0. 1.][ 1. 0. 0. 60. 80. 0. 1. 0. 1. 0. 0.][ 0. 0. 1. 40. 70. 0. 0. 1. 0. 1. 0.]]
2 CountVectorizer - 文本特征提取
將文本轉換為詞頻矩陣(Bag of Words 模型),統計每個詞在文檔中出現的次數。
sklearn.feature_extraction.text.CountVectorizer
? 構造函數關鍵字參數stop_words,值為list,表示詞的黑名單(不提取的詞)
fit_transform函數的返回值為稀疏矩陣
英文文本提取
from sklearn.feature_extraction.text import CountVectorizer
data=['hello my name is naci','my age is 18','my dog name is nacy']
counter = CountVectorizer()
# 文本詞頻轉換為矩陣
data = counter.fit_transform(data)
print(data.toarray())
print(counter.get_feature_names_out())
[[0 0 0 1 1 1 1 0 1][1 1 0 0 1 1 0 0 0][0 0 1 0 1 1 0 1 1]]
['18' 'age' 'dog' 'hello' 'is' 'my' 'naci' 'nacy' 'name']
此矩陣應該豎著看,對應所有的詞語,例如‘18’只在第二個文章出現,所以第一列只有第二行為1,以此類推
中文文本提取
from sklearn.feature_extraction.text import CountVectorizer
data=['今天天氣不錯', '今天天氣不錯,但有風']
counter = CountVectorizer()
# 文本詞頻轉換為矩陣
data = counter.fit_transform(data)
print(data.toarray())
print(counter.get_feature_names_out())
[[1 0][1 1]]
['今天天氣不錯' '但有風']
有結果可知,中文沒有空格來分割,所以以逗號分割,一句為一詞
若要統計中文詞組的詞頻,則需要使用jieba分詞,然后通過空格連接起來,再使用ContVectorizer
import jieba
from sklearn.feature_extraction.text import CountVectorizer
arr = jieba.cut('今天天真好')
print(list(arr))def cut_word(words):return ' '.join(jieba.cut(words))
data=['今天天真好','我的貓很可愛']
data2 =[cut_word(i) for i in data]
print(data2)count = CountVectorizer()
# 文本詞頻轉為矩陣
data2 = count.fit_transform(data2)
print(data2.toarray())
['今天', '天真', '好']
['今天 天真 好', '我 的 貓 很 可愛']
[[1 0 1][0 1 0]]
3 TfidfVectorizer TF-IDF - 文本特征詞的重要程度特征提取
將文本轉換為 TF-IDF 值矩陣,評估詞在文檔中的重要性(稀有詞權重更高)。
- 詞頻(TF):一個詞在文檔中出現的頻率越高,通常對該文檔的代表性越強。
- 逆文檔頻率(IDF):一個詞在所有文檔中出現的頻率越高(即越常見),其區分度越低,權重也就越低;反之,稀有詞的權重更高。
-
詞頻(Term Frequency, TF) 計算公式:
TF(t,d)=詞?t在文檔?d中出現的次數文檔?d中的總詞數\text{TF}(t,d) = \frac{\text{詞 }t\text{ 在文檔 }d\text{ 中出現的次數}}{\text{文檔 }d\text{ 中的總詞數}} TF(t,d)=文檔?d?中的總詞數詞?t?在文檔?d?中出現的次數?部分實現會使用對數變換:
TF(t,d)=1+log?(詞?t在文檔?d中出現的次數)\text{TF}(t,d) = 1 + \log(\text{詞 }t\text{ 在文檔 }d\text{ 中出現的次數}) TF(t,d)=1+log(詞?t?在文檔?d?中出現的次數) -
逆文檔頻率(Inverse Document Frequency, IDF)
IDF 的計算公式是:
IDF(t)=log??(總文檔數包含詞t的文檔數+1)IDF(t)=\log?(\dfrac{總文檔數}{包含詞t的文檔數+1})IDF(t)=log?(包含詞t的文檔數+1總文檔數?)
在 TfidfVectorizer 中,IDF 的默認計算公式是:
IDF(t)=log??(總文檔數+1包含詞t的文檔數+1)+1IDF(t)=\log?(\dfrac{總文檔數+1}{包含詞t的文檔數+1})+1IDF(t)=log?(包含詞t的文檔數+1總文檔數+1?)+1
-
分母中的 +1 是平滑處理,避免出現除以零的情況。
-
TF-IDF 值 計算公式:
TF-IDF(t,d)=TF(t,d)×IDF(t)\text{TF-IDF}(t,d) = \text{TF}(t,d) \times \text{IDF}(t) TF-IDF(t,d)=TF(t,d)×IDF(t)
sklearn.feature_extraction.text.TfidfVectorizer()
? 構造函數關鍵字參數stop_words,表示詞特征黑名單
fit_transform函數的返回值為稀疏矩陣
import jieba
from sklearn.feature_extraction.text import CountVectorizer,TfidfVectorizerdef cut_word(words):return ' '.join(jieba.cut(words))data = ["教育學會會長期間堅定支持民辦教育事業!","熱忱關心、扶持民辦學校發展","事業做出重大貢獻!"]
data2 =[cut_word(i) for i in data]
print(data2)transfer = TfidfVectorizer()
data=transfer.fit_transform(data2)
print(data.toarray())
print(transfer.get_feature_names_out())
['教育 學會 會長 期間 堅定 支持 民辦教育 事業 !', '熱忱 關心 、 扶持 民辦學校 發展', '事業 做出 重大貢獻 !']
[[0.27626457 0.36325471 0. 0. 0. 0.363254710.36325471 0. 0.36325471 0.36325471 0.36325471 0.0.36325471 0. 0. ][0. 0. 0. 0.4472136 0.4472136 0.0. 0.4472136 0. 0. 0. 0.44721360. 0.4472136 0. ][0.4736296 0. 0.62276601 0. 0. 0.0. 0. 0. 0. 0. 0.0. 0. 0.62276601]]
['事業' '會長' '做出' '關心' '發展' '堅定' '學會' '扶持' '支持' '教育' '期間' '民辦學校' '民辦教育' '熱忱''重大貢獻']
# 手動實現tfidf向量
from sklearn.feature_extraction.text import TfidfVectorizer
import numpy as np
from sklearn.preprocessing import normalize
def myTfidfVectorizer(data):# 提取詞頻tansfer = CountVectorizer()data = tansfer.fit_transform(data)TF = data.toarray()#詞頻矩陣IDF = np.log((len(TF)+1)/(1+np.sum(TF!=0,axis=0))+1)'''TF!=0 求出布爾矩陣sum(TF!=0,axis=0) 求出每列非零元素個數-->包含該詞的文檔數len(TF) 矩陣的行數-->文檔數'''tf_idf = TF*IDF #TF-IDF矩陣#對 TF-IDF 矩陣進行 L2 范數歸一化處理tf_idf = normalize(tf_idf,norm='l2')return tf_idfdef cut_word(words):return ' '.join(jieba.cut(words))data = ["教育學會會長期間堅定支持民辦教育事業!","熱忱關心、扶持民辦學校發展","事業做出重大貢獻!"]
data2 =[cut_word(i) for i in data]
res = myTfidfVectorizer(data2)
print(res)
4 無量綱化-預處理
無量綱化(Normalization/Standardization) 是數據預處理的關鍵步驟,用于消除不同特征間量綱和尺度差異的影響,確保模型能夠公平地對待每個特征。
1. MaxAbsScaler
將特征縮放到 [-1,1] 范圍,適合稀疏數據:
對于每個特征x:
若要縮放到其他區間,可以使用公式:x=x*(max-min)+min;
sklearn.preprocessing.MinMaxScaler(feature_range)
參數:feature_range=(0,1) 歸一化后的值域,可以自己設定
fit_transform函數歸一化的原始數據類型可以是list、DataFrame和ndarray, 不可以是稀疏矩陣
fit_transform函數的返回值為ndarray
缺點:最大值和最小值容易受到異常點影響,所以魯棒性較差
from sklearn.preprocessing import MinMaxScaler
data=[[1,2,3],[4,5,6],[7,8,9]]
transfer = MinMaxScaler()
data_new = transfer.fit_transform(data)
print(data_new)
[[0. 0. 0. ][0.5 0.5 0.5][1. 1. 1. ]]
若要指定范圍,則設定feature_range
from sklearn.preprocessing import MinMaxScaler
data=[[1,2,3],[4,5,6],[7,8,9]]
transfer = MinMaxScaler(feature_range=(-10,10))
data_new = transfer.fit_transform(data)
print(data_new)
[[-10. -10. -10.][ 0. 0. 0.][ 10. 10. 10.]]
2. normalize歸一化
歸一化通過縮放每個樣本向量,使其具有單位范數。
<1> L1歸一化
絕對值相加作為分母,特征值作為分子
公式:
∥x∥1=∑i=1n∣xi∣\|x\|_1 = \sum_{i=1}^n |x_i| ∥x∥1?=i=1∑n?∣xi?∣
<2> L2歸一化
平方相加作為分母,特征值作為分子
公式:
∥x∥2=∑i=1nxi2\|x\|_2 = \sqrt{\sum_{i=1}^n x_i^2} ∥x∥2?=i=1∑n?xi2??
<3> max歸一化
max作為分母,特征值作為分子
sklearn.preprocessing.normalize
X
:輸入的特征矩陣(二維數組)。norm
:范數類型,可選'l1'
、'l2'
或'max'
(按最大值縮放)。axis
:指定歸一化的方向,axis=0
表示按列歸一化,axis=1
(默認)表示按行歸一化。
from sklearn.preprocessing import MinMaxScaler, normalize
from sklearn.datasets import load_iris
x,y = load_iris(return_X_y=True)
#axis=1 按列進行歸一化
x = normalize(x,norm = 'l2',axis=1)
print(x)
3. StandardScaler
其核心原理是通過減去均值并除以標準差,將特征轉換為均值為 0、方差為 1 的標準正態分布。這有助于消除不同特征間的量綱差異,尤其適用于依賴正態分布假設或梯度優化的算法。
z是轉換后的數值,x是原始數據的值,μ是該特征的均值,σ是該特征的 標準差
sklearn.preprocessing.StandardScale
from sklearn.preprocessing import StandardScaler
data=[[1,2,3,5],[4,5,6,8],[7,8,9,11]]transfer = StandardScaler()
data_new = transfer.fit_transform(data)
print(data_new)
print(transfer.mean_)# 均值
print(transfer.var_)# 方差
[[-1.22474487 -1.22474487 -1.22474487 -1.22474487][ 0. 0. 0. 0. ][ 1.22474487 1.22474487 1.22474487 1.22474487]]
[4. 5. 6. 8.]
[6. 6. 6. 6.]