如何使用 SQL 對數據進行分析?
832
2025-04-03
Machine Learning | 機器學習簡介
Machine Learning | (1) Scikit-learn與特征工程
Scikit-learn與特征工程
“數據決定了機器學習的上限,而算法只是盡可能逼近這個上限”,這句話很好的闡述了數據在機器學習中的重要性。大部分直接拿過來的數據都是特征不明顯的、沒有經過處理的或者說是存在很多無用的數據,那么需要進行一些特征處理,特征的縮放等等,滿足訓練數據的要求。
將初次接觸到Scikit-learn這個機器學習庫的使用
Scikit-learn
Python語言的機器學習工具
所有人都適用,可在不同的上下文中重用
基于NumPy、SciPy和matplotlib構建
開源、商業可用 - BSD許可
目前穩定版本0.22
自2007年發布以來,scikit-learn已經成為最給力的Python機器學習庫(library)了。scikit-learn支持的機器學習算法包括分類,回歸,降維和聚類。還有一些特征提?。╡xtracting features)、數據處理(processing data)和模型評估(evaluating models)的模塊。作為Scipy庫的擴展,scikit-learn也是建立在Python的NumPy和matplotlib庫基礎之上。NumPy可以讓Python支持大量多維矩陣數據的高效操作,matplotlib提供了可視化工具,SciPy帶有許多科學計算的模型。 scikit-learn文檔完善,容易上手,豐富的API,使其在學術界頗受歡迎。開發者用scikit-learn實驗不同的算法,只要幾行代碼就可以搞定。scikit-learn包括許多知名的機器學習算法的實現,包括LIBSVM和LIBLINEAR。還封裝了其他的Python庫,如自然語言處理的NLTK庫。另外,scikit-learn內置了大量數據集,允許開發者集中于算法設計,節省獲取和整理數據集的時間。
安裝的話參考下面步驟: 創建一個基于Python3的虛擬環境:
mkvirtualenv -p /usr/local/bin/python3.6 ml3
在ubuntu的虛擬環境當中運行以下命令
pip3 install Scikit-learn
然后通過導入命令查看是否可以使用:
import sklearn
數據的特征工程
從數據中抽取出來的對預測結果有用的信息,通過專業的技巧進行數據處理,是的特征能在機器學習算法中發揮更好的作用。優質的特征往往描述了數據的固有結構。 最初的原始特征數據集可能太大,或者信息冗余,因此在機器學習的應用中,一個初始步驟就是選擇特征的子集,或構建一套新的特征集,減少功能來促進算法的學習,提高泛化能力和可解釋性。
例如:你要查看不同地域女性的穿衣品牌情況,預測不同地域的穿衣品牌。如果其中含有一些男性的數據,是不是要將這些數據給去除掉
特征工程的意義
更好的特征意味著更強的魯棒性
更好的特征意味著只需用簡單模型
更好的特征意味著更好的結果
特征工程之特征處理
特征工程中最重要的一個環節就是特征處理,特征處理包含了很多具體的專業技巧
特征預處理
單個特征
歸一化
標準化
缺失值
多個特征
降維
PCA
特征工程之特征抽取與特征選擇
如果說特征處理其實就是在對已有的數據進行運算達到我們目標的數據標準。特征抽取則是將任意數據格式(例如文本和圖像)轉換為機器學習的數字特征。而特征選擇是在已有的特征中選擇更好的特征。后面會詳細介紹特征選擇主要區別于降維。
數據的來源與類型
大部分的數據都來自已有的數據庫,如果沒有的話也可以交給很多爬蟲工程師去采集,來提供。也可以來自平時的記錄,反正數據無處不在,大都是可用的。
數據的類型
按照機器學習的數據分類我們可以將數據分成:
標稱型:標稱型目標變量的結果只在有限目標集中取值,如真與假(標稱型目標變量主要用于分類)
數值型:數值型目標變量則可以從無限的數值集合中取值,如0.100,42.001等 (數值型目標變量主要用于回歸分析)
按照數據的本身分布特性
離散型
連續型
那么什么是離散型和連續型數據呢?首先連續型數據是有規律的,離散型數據是沒有規律的
離散變量是指其數值只能用自然數或整數單位計算的則為離散變量.例如,班級人數、進球個數、是否是某個類別等等
連續型數據是指在指定區間內可以是任意一個數值,例如,票房數據、花瓣大小分布數據
數據的特征抽取
現實世界中多數特征都不是連續變量,比如分類、文字、圖像等,為了對非連續變量做特征表述,需要對這些特征做數學化表述,因此就用到了特征提取. sklearn.feature_extraction提供了特征提取的很多方法
分類特征變量提取
我們將城市和環境作為字典數據,來進行特征的提取。
sklearn.feature_extraction.DictVectorizer(sparse = True)
將映射列表轉換為Numpy數組或scipy.sparse矩陣
sparse 是否轉換為scipy.sparse矩陣表示,默認開啟
方法
fit_transform(X,y)
應用并轉化映射列表X,y為目標類型
inverse_transform(X[, dict_type])
將Numpy數組或scipy.sparse矩陣轉換為映射列表
from sklearn.feature_extraction import DictVectorizer
onehot = DictVectorizer() # 如果結果不用toarray,請開啟sparse=False
instances = [{'city': '北京','temperature':100},{'city': '上海','temperature':60}, {'city': '深圳','temperature':30}]
X = onehot.fit_transform(instances).toarray()
print(onehot.inverse_transform(X))
文本特征提?。ㄖ幌抻谟⑽模?/p>
文本的特征提取應用于很多方面,比如說文檔分類、垃圾郵件分類和新聞分類。那么文本分類是通過詞是否存在、以及詞的概率(重要性)來表示。
(1)文檔的中詞的出現
數值為1表示詞表中的這個詞出現,為0表示未出現
sklearn.feature_extraction.text.CountVectorizer()
將文本文檔的集合轉換為計數矩陣(scipy.sparse matrices)
方法
fit_transform(raw_documents,y)
學習詞匯詞典并返回詞匯文檔矩陣
from sklearn.feature_extraction.text import CountVectorizer
content = ["life is short,i like python","life is too long,i dislike python"]
vectorizer = CountVectorizer()
print(vectorizer.fit_transform(content).toarray())
需要toarray()方法轉變為numpy的數組形式
溫馨提示:每個文檔中的詞,只是整個語料庫中所有詞,的很小的一部分,這樣造成特征向量的稀疏性(很多值為0)為了解決存儲和運算速度的問題,使用Python的scipy.sparse矩陣結構
(2)TF-IDF表示詞的重要性
TfidfVectorizer會根據指定的公式將文檔中的詞轉換為概率表示。(樸素貝葉斯介紹詳細的用法)
class sklearn.feature_extraction.text.TfidfVectorizer()
方法
fit_transform(raw_documents,y)
學習詞匯和idf,返回術語文檔矩陣。
from sklearn.feature_extraction.text import TfidfVectorizer
content = ["life is short,i like python","life is too long,i dislike python"]
vectorizer = TfidfVectorizer(stop_words='english')
print(vectorizer.fit_transform(content).toarray())
print(vectorizer.vocabulary_)
數據的特征預處理
單個特征
(1)歸一化
歸一化首先在特征(維度)非常多的時候,可以防止某一維或某幾維對數據影響過大,也是為了把不同來源的數據統一到一個參考區間下,這樣比較起來才有意義,其次可以程序可以運行更快。 例如:一個人的身高和體重兩個特征,假如體重50kg,身高175cm,由于兩個單位不一樣,數值大小不一樣。如果比較兩個人的體型差距時,那么身高的影響結果會比較大,k-臨近算法會有這個距離公式。
min-max方法
常用的方法是通過對原始數據進行線性變換把數據映射到[0,1]之間,變換的函數為:
X^{'}{=}\frac{x-min}{max-min}X ′ = max?min x?min
其中min是樣本中最小值,max是樣本中最大值,注意在數據流場景下最大值最小值是變化的,另外,最大值與最小值非常容易受異常點影響,所以這種方法魯棒性較差,只適合傳統精確小數據場景。
min-max自定義處理
這里我們使用相親約會對象數據在MatchData.txt,這個樣本時男士的數據,三個特征,玩游戲所消耗時間的百分比、每年獲得的飛行常客里程數、每周消費的冰淇淋公升數。然后有一個 所屬類別,被女士評價的三個類別,不喜歡、魅力一般、極具魅力。 首先導入數據進行矩陣轉換處理
import numpy as np
def data_matrix(file_name):
"""
將文本轉化為matrix
:param file_name: 文件名
:return: 數據矩陣
"""
fr = open(file_name)
array_lines = fr.readlines()
number_lines = len(array_lines)
return_mat = zeros((number_lines, 3))
# classLabelVector = []
index = 0
for line in array_lines:
line = line.strip()
list_line = line.split('\t')
return_mat[index,:] = list_line[0:3]
# if(listFromLine[-1].isdigit()):
# classLabelVector.append(int(listFromLine[-1]))
# else:
# classLabelVector.append(love_dictionary.get(listFromLine[-1]))
# index += 1
return return_mat
輸出結果為
[[ 4.09200000e+04 8.32697600e+00 9.53952000e-01]
[ 1.44880000e+04 7.15346900e+00 1.67390400e+00]
[ 2.60520000e+04 1.44187100e+00 8.05124000e-01]
...,
[ 2.65750000e+04 1.06501020e+01 8.66627000e-01]
[ 4.81110000e+04 9.13452800e+00 7.28045000e-01]
[ 4.37570000e+04 7.88260100e+00 1.33244600e+00]]
我們查看數據集會發現,有的數值大到幾萬,有的才個位數,同樣如果計算兩個樣本之間的距離時,其中一個影響會特別大。也就是說飛行里程數對于結算結果或者說相親結果影響較大,但是統計的人覺得這三個特征同等重要,所以需要將數據進行這樣的處理。
這樣每個特征任意的范圍將變成[0,1]的區間內的值,或者也可以根據需求處理到[-1,1]之間,我們再定義一個函數,進行這樣的轉換。
def feature_normal(data_set):
"""
特征歸一化
:param data_set:
:return:
"""
# 每列最小值
min_vals = data_set.min(0)
# 每列最大值
max_vals = data_set.max(0)
ranges = max_vals - min_vals
norm_data = np.zeros(np.shape(data_set))
# 得出行數
m = data_set.shape[0]
# 矩陣相減
norm_data = data_set - np.tile(min_vals, (m,1))
# 矩陣相除
norm_data = norm_data/np.tile(ranges, (m, 1)))
return norm_data
輸出結果為
[[ 0.44832535 0.39805139 0.56233353]
[ 0.15873259 0.34195467 0.98724416]
[ 0.28542943 0.06892523 0.47449629]
...,
[ 0.29115949 0.50910294 0.51079493]
[ 0.52711097 0.43665451 0.4290048 ]
[ 0.47940793 0.3768091 0.78571804]]
這樣得出的結果都非常相近,這樣的數據可以直接提供測試驗證了
min-max的scikit-learn處理
scikit-learn.preprocessing中的類MinMaxScaler,將數據矩陣縮放到[0,1]之間
>>> X_train = np.array([[ 1., -1., 2.],
... [ 2., 0., 0.],
... [ 0., 1., -1.]])
...
>>> min_max_scaler = preprocessing.MinMaxScaler()
>>> X_train_minmax = min_max_scaler.fit_transform(X_train)
>>> X_train_minmax
array([[ 0.5 , 0. , 1. ],
[ 1. , 0.5 , 0.33333333],
[ 0. , 1. , 0. ]])
(3)標準化
常用的方法是z-score標準化,經過處理后的數據均值為0,標準差為1,處理方法是:
X^{'}{=}\frac{x-\mu}{\sigma}X ′ = σ x?μ
其中\muμ是樣本的均值,\sigmaσ是樣本的標準差,它們可以通過現有的樣本進行估計,在已有的樣本足夠多的情況下比較穩定,適合嘈雜的數據場景
sklearn中提供了StandardScalar類實現列標準化:
In [2]: import numpy as np
In [3]: X_train = np.array([[ 1., -1., 2.],[ 2., 0., 0.],[ 0., 1., -1.]])
In [4]: from sklearn.preprocessing import StandardScaler
In [5]: std = StandardScaler()
In [6]: X_train_std = std.fit_transform(X_train)
In [7]: X_train_std
Out[7]:
array([[ 0. , -1.22474487, 1.33630621],
[ 1.22474487, 0. , -0.26726124],
[-1.22474487, 1.22474487, -1.06904497]])
(3)缺失值
由于各種原因,許多現實世界的數據集包含缺少的值,通常編碼為空白,NaN或其他占位符。然而,這樣的數據集與scikit的分類器不兼容,它們假設數組中的所有值都是數字,并且都具有和保持含義。使用不完整數據集的基本策略是丟棄包含缺失值的整個行和/或列。然而,這是以丟失可能是有價值的數據(即使不完整)的代價。更好的策略是估算缺失值,即從已知部分的數據中推斷它們。
(1)填充缺失值 使用sklearn.preprocessing中的Imputer類進行數據的填充
class Imputer(sklearn.base.BaseEstimator, sklearn.base.TransformerMixin)
"""
用于完成缺失值的補充
:param param missing_values: integer or "NaN", optional (default="NaN")
丟失值的占位符,對于編碼為np.nan的缺失值,使用字符串值“NaN”
:param strategy: string, optional (default="mean")
插補策略
如果是“平均值”,則使用沿軸的平均值替換缺失值
如果為“中位數”,則使用沿軸的中位數替換缺失值
如果“most_frequent”,則使用沿軸最頻繁的值替換缺失
:param axis: integer, optional (default=0)
插補的軸
如果axis = 0,則沿列排列
如果axis = 1,則沿行排列
"""
>>> import numpy as np
>>> from sklearn.preprocessing import Imputer
>>> imp = Imputer(missing_values='NaN', strategy='mean', axis=0)
>>> imp.fit([[1, 2], [np.nan, 3], [7, 6]])
Imputer(axis=0, copy=True, missing_values='NaN', strategy='mean', verbose=0)
>>> X = [[np.nan, 2], [6, np.nan], [7, 6]]
>>> print(imp.transform(X))
[[ 4. 2. ]
[ 6. 3.666...]
[ 7. 6. ]]
多個特征
降維
PCA(Principal component analysis),主成分分析。特點是保存數據集中對方差影響最大的那些特征,PCA極其容易受到數據中特征范圍影響,所以在運用PCA前一定要做特征標準化,這樣才能保證每維度特征的重要性等同。
sklearn.decomposition.PCA
class PCA(sklearn.decomposition.base)
"""
主成成分分析
:param n_components: int, float, None or string
這個參數可以幫我們指定希望PCA降維后的特征維度數目。最常用的做法是直接指定降維到的維度數目,此時n_components是一個大于1的整數。
我們也可以用默認值,即不輸入n_components,此時n_components=min(樣本數,特征數)
:param whiten: bool, optional (default False)
判斷是否進行白化。所謂白化,就是對降維后的數據的每個特征進行歸一化。對于PCA降維本身來說一般不需要白化,如果你PCA降維后有后續的數據處理動作,可以考慮白化,默認值是False,即不進行白化
:param svd_solver:
選擇一個合適的SVD算法來降維,一般來說,使用默認值就夠了。
"""
通過一個例子來看
>>> import numpy as np
>>> from sklearn.decomposition import PCA
>>> X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
>>> pca = PCA(n_components=2)
>>> pca.fit(X)
PCA(copy=True, iterated_power='auto', n_components=2, random_state=None,
svd_solver='auto', tol=0.0, whiten=False)
>>> print(pca.explained_variance_ratio_)
[ 0.99244... 0.00755...]
數據的特征選擇
降維本質上是從一個維度空間映射到另一個維度空間,特征的多少別沒有減少,當然在映射的過程中特征值也會相應的變化。舉個例子,現在的特征是1000維,我們想要把它降到500維。降維的過程就是找個一個從1000維映射到500維的映射關系。原始數據中的1000個特征,每一個都對應著降維后的500維空間中的一個值。假設原始特征中有個特征的值是9,那么降維后對應的值可能是3。而對于特征選擇來說,有很多方法:
Filter(過濾式):VarianceThreshold
Embedded(嵌入式):正則化、決策樹
Wrapper(包裹式)
其中過濾式的特征選擇后,數據本身不變,而數據的維度減少。而嵌入式的特征選擇方法也會改變數據的值,維度也改變。Embedded方式是一種自動學習的特征選擇方法,后面講到具體的方法的時候就能理解了。
特征選擇主要有兩個功能:
(1)減少特征數量,降維,使模型泛化能力更強,減少過擬合
(2)增強特征和特征值之間的理解
sklearn.feature_selection
去掉取值變化小的特征(刪除低方差特征)
VarianceThreshold 是特征選擇中的一項基本方法。它會移除所有方差不滿足閾值的特征。默認設置下,它將移除所有方差為0的特征,即那些在所有樣本中數值完全相同的特征。
假設我們要移除那些超過80%的數據都為1或0的特征
from sklearn.feature_selection import VarianceThreshold
X = [[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 1, 1], [0, 1, 0], [0, 1, 1]]
sel = VarianceThreshold(threshold=(.8 * (1 - .8)))
sel.fit_transform(X)
array([[0, 1],
[1, 0],
[0, 0],
[1, 1],
[1, 0],
[1, 1]])
參考資料
https://scikit-learn.org/
Mac OS Python scikit-learn 機器學習
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。