機器學習2-特徵工程
特徵工程
特徵抽取
文字特徵提取-CountVectorizer
作用:對文字資料進行特徵值化
-
sklearn.feature_extraction.text.CountVectorizer(stop_words=[])
- 返回詞頻矩陣
- CountVectorizer.fit_transform(X) X:文字或者包含文字字串的可迭代物件 返回值:返回sparse矩陣
- CountVectorizer.inverse_transform(X) X:array陣列或者sparse矩陣 返回值:轉換之前資料格
- CountVectorizer.get_feature_names() 返回值:單詞列表
應用
我們對以下資料進行特徵提取
["life is short,i like python", "life is too long,i dislike python"]
具體步驟:
- 例項化類CountVectorizer
- 呼叫fit_transform方法輸入資料並轉換 (注意返回格式,利用toarray()進行sparse矩陣轉換array陣列)
def count_demo(): """ 文字特徵抽取:CountVectorizer :return: None """ data = ["life is short,i like like python", "life is too long,i dislike python"] #例項化轉換器 transfer=CountVectorizer(stop_words=["is","too"]) #呼叫fit_transform data_new=transfer.fit_transform(data) print("data_new:\n",data_new.toarray()) print("返回特徵名字:\n", transfer.get_feature_names()) return None
返回結果:
接下來將英文換成中文
def count_chinese_demo(): """ 中文文字特徵抽取:CountVectorizer :return: None """ data = ["我 愛 北京 天安門", "天安門 上 太陽 升"] #例項化轉換器 transfer=CountVectorizer() #呼叫fit_transform data_new=transfer.fit_transform(data) print("data_new:\n",data_new.toarray()) print("返回特徵名字:\n", transfer.get_feature_names()) return None
結果是:
可見不支援單箇中文,需用空格分割,如若不進行分割,會把整個句子來作為特徵處理
然後手動分詞實現是不太可能的,我們採用jieba進行分詞
jieba分詞:
def cut_word(text): text=" ".join(list(jieba.cut(text))) return text def count_chinese_demo2(): """ 中文文字特徵抽取,自動分詞 :return: None """ data = ["一種還是一種今天很殘酷,明天更殘酷,後天很美好,但絕對大部分是死在明天晚上,所以每個人不要放棄今天。", "我們看到的從很遠星系來的光是在幾百萬年之前發出的,這樣當我們看到宇宙時,我們是在看它的過去。", "如果只用一種方式瞭解某樣事物,你就不會真正瞭解它。瞭解事物真正含義的祕密取決於如何將其與我們所瞭解的事物相聯絡。"] text_new=[] for item in data: text_new.append(cut_word(item)) #例項化轉換器 transfer=CountVectorizer(stop_words=["一種","所以"]) #呼叫fit_transform data_new=transfer.fit_transform(text_new) print("data_new:\n",data_new.toarray()) print("返回特徵名字:\n", transfer.get_feature_names()) return None
例項化容器中加入:stop_words的目的是去除沒有太大意義的詞
結果為:
總結
CountVectorizer做到的是:以單詞作為統計詞,並統計出現的次數
文字特徵提取-Tf-idf
- TF-IDF的主要思想是:如果某個詞或短語在一篇文章中出現的概率高,並且在其他文章中很少出現,則認為此詞或者短語具有很好的類別區分能力,適合用來分類。
- TF-IDF作用:用以評估一字詞對於一個檔案集或一個語料庫中的其中一份檔案的重要程度。
公式
- 詞頻(term frequency,tf)指的是某一個給定的詞語在該檔案中出現的頻率
- 逆向文件頻率(inverse document frequency,idf)是一個詞語普遍重要性的度量。某一特定詞語的idf,可以由總檔案數目除以包含該詞語之檔案的數目,再將得到的商取以10為底的對數得到
案例
def tfidf(): """ 用TF-IDF的方法進行文字特徵抽取 """ data = ["一種還是一種今天很殘酷,明天更殘酷,後天很美好,但絕對大部分是死在明天晚上,所以每個人不要放棄今天。", "我們看到的從很遠星系來的光是在幾百萬年之前發出的,這樣當我們看到宇宙時,我們是在看它的過去。", "如果只用一種方式瞭解某樣事物,你就不會真正瞭解它。瞭解事物真正含義的祕密取決於如何將其與我們所瞭解的事物相聯絡。"] text_new = [] for item in data: text_new.append(cut_word(item)) # 例項化轉換器 transfer = TfidfVectorizer(stop_words=["一種", "所以"]) # 呼叫fit_transform data_new = transfer.fit_transform(text_new) print("data_new:\n", data_new.toarray()) print("返回特徵名字:\n", transfer.get_feature_names()) return None
結果如下:
總結
他所反映的是這些詞的重要性,主要應用於機器學習演算法進行文章分類中前期資料處理方式
特徵預處理
什麼是特徵預處理?
特徵預處理API
from sklearn.preprocessing import MinMaxScaler,StandardScaler
為什麼我們要進行歸一化/標準化?
特徵的單位或者大小相差較大,或者某特徵的方差相比其他的特徵要大出幾個數量級,容易影響(支配)目標結果,使得一些演算法無法學習到其它的特徵
歸一化
1 定義
通過對原始資料進行變換把資料對映到(預設為[0,1])之間
2 公式
作用於每一列,max為一列的最大值,min為一列的最小值,那麼X’’為最終結果,mx,mi分別為指定區間值預設mx為1,mi為0
3 API
- sklearn.preprocessing.MinMaxScaler (feature_range=(0,1)… )
- MinMaxScalar.fit_transform(X)
- X:numpy array格式的資料[n_samples,n_features]
- 返回值:轉換後的形狀相同的array
- MinMaxScalar.fit_transform(X)
4 資料計算
def minmax_demo(): """ 歸一化 """ #1.獲取資料 data=pd.read_csv("datingTestSet2.txt", sep=',') data=data.iloc[:,:3] #2.例項化一個轉換器,範圍在0-1 transfer = MinMaxScaler(feature_range=[0,1]) #3.呼叫fit_transform data_new=transfer.fit_transform(data) print("data_new:\n",data_new) print("特徵:\n",data.columns) return None
結果如下:
5 歸一化總結
注意最大值最小值是變化的,另外,最大值與最小值非常容易受異常點影響,所以這種方法魯棒性較差,只適合傳統精確小資料場景。
標準化
1 定義
通過對原始資料進行變換把資料變換到均值為0,標準差為1範圍內
2 公式
作用於每一列,mean為平均值,σ為標準差
所以回到剛才異常點的地方,我們再來看看標準化
- 對於歸一化來說:如果出現異常點,影響了最大值和最小值,那麼結果顯然會發生改變
- 對於標準化來說:如果出現異常點,由於具有一定資料量,少量的異常點對於平均值的影響並不大,從而方差改變較小。
3 API
- sklearn.preprocessing.StandardScaler( )
- 處理之後每列來說所有資料都聚集在均值0附近標準差差為1
- StandardScaler.fit_transform(X)
- X:numpy array格式的資料[n_samples,n_features]
- 返回值:轉換後的形狀相同的array
4 資料計算
def stand_demo(): """ 歸一化 """ #1.獲取資料 data=pd.read_csv("datingTestSet2.txt", sep=',') data=data.iloc[:,:3] #2.例項化一個轉換器 transfer = StandardScaler() #3.呼叫fit_transform data_new=transfer.fit_transform(data) print("data_new:\n",data_new) print("每一列特徵的平均值:\n", transfer.mean_) print("每一列特徵的方差:\n", transfer.var_) return None
結果如下:
5 標準化總結
在已有樣本足夠多的情況下比較穩定,適合現代嘈雜大資料場景。
特徵選擇
1 定義
資料中包含冗餘或無關變數(或稱特徵、屬性、指標等),旨在從原有特徵中找出主要特徵。
2 方法
- Filter(過濾式):主要探究特徵本身特點、特徵與特徵和目標值之間關聯
- 方差選擇法:低方差特徵過濾
- 相關係數
- Embedded (嵌入式):演算法自動選擇特徵(特徵與目標值之間的關聯)
- 決策樹:資訊熵、資訊增益
- 正則化:L1、L2
- 深度學習:卷積等
3API
from sklearn.feature_selection import VarianceThreshold
4低方差特徵過濾
刪除低方差的一些特徵,前面講過方差的意義。再結合方差的大小來考慮這個方式的角度。
- 特徵方差小:某個特徵大多樣本的值比較相近
- 特徵方差大:某個特徵很多樣本的值都有差別
難點:在於掌握閾值的大小,來進行合理的控制低方差的過濾
相關係數
反映變數之間相關關係密切程度的統計指標
相關係數的值介於–1與+1之間,即–1≤ r ≤+1。
一般可按三級劃分:|r|<0.4為低度相關;0.4≤|r|<0.7為顯著性相關;0.7≤|r|<1為高度線性相關
#低方差過濾 def variance_demo(): """ 刪除低方差特徵——特徵選擇 :return: None """ data = pd.read_csv("factor_returns.csv") data=data.iloc[:,1:-2] print("data:\n",data) # 1、例項化一個轉換器類 transfer = VarianceThreshold(threshold=10) # 2、呼叫fit_transform data_new = transfer.fit_transform(data) print("date_new:\n", data_new) print("形狀:\n", data_new.shape) #計算兩個變數之間的相關係數 r=pearsonr(data["pe_ratio"],data["pb_ratio"]) print("相關係數:\n",r) r2=pearsonr(data["revenue"],data["total_expense"]) print("revenue與total_expense之間的相關性:\n",r2) plt.figure(figsize=(20,8),dpi=100) plt.scatter(data["revenue"],data["total_expense"]) plt.show() return None
主成分分析
什麼是主成分分析(PCA)
-
定義:高維資料轉化為低維資料的過程,在此過程中可能會捨棄原有資料、創造新的變數
-
作用:是資料維數壓縮,儘可能降低原資料的維數(複雜度),損失少量資訊。
- 應用:迴歸分析或者聚類分析當中
計算案例理解
假設對於給定5個點,資料如下
(-1,-2)
(-1, 0)
( 0, 0)
( 2, 1)
( 0, 1)
要求:將這個二維的資料簡化成一維? 並且損失少量的資訊
這個過程如何計算的呢?找到一個合適的直線,通過一個矩陣運算得出主成分分析的結果(不需要理解)
2 API
- sklearn.decomposition.PCA(n_components=None)
- 將資料分解為較低維數空間
- n_components:
- 小數:表示保留百分之多少的資訊
- 整數:減少到多少特徵
- PCA.fit_transform(X) X:numpy array格式的資料[n_samples,n_features]
- 返回值:轉換後指定維度的array
3 資料計算
def pca_demo(): """ pca降維 """ data=[[2,8,4,5],[6,3,0,8],[5,4,9,1]] #例項化一個轉換器 transfer=PCA(n_components=0.95) #呼叫fit_transform data_new=transfer.fit_transform(data) print("保留95%的資訊,降維結果為:\n",data_new) # 1、例項化PCA, 整數——指定降維到的維數 transfer2 = PCA(n_components=3) # 2、呼叫fit_transform data2 = transfer2.fit_transform(data) print("降維到3維的結果:\n", data2) return None
結果如下:
&n