說明:本篇博客出自湖南師范大學基礎教育大資料研究與應用重點實驗室
人工智能基礎-數學知識之線性代數
- 一、向量
- 1.1 向量的含義
- 1.2 創建向量
- 1.3 向量的范數(模長)
- 1.4 向量加法(減法)
- 1.5 向量的數乘
- 1.6 向量的乘法(點積)
- 二、向量化
- 2.1 One-Hot Encoding方式
- 2.2 詞袋(BOW)模型
- 2.3 TF-IDF
- 2.4 三種方法的缺點
- 參考文獻
本篇博客為人工智能基礎-數學知識之線性代數的第一部分內容,主要介紹了線性代數中向量的含義及一些基本運算、文本向量化的三種方法,內含python相關實作代碼,本篇博客較為簡單,請讀者在學習的程序中,適當學習相關代碼,領會其中思想,
一、向量
1.1 向量的含義
向量是指在坐標系中的有箭頭的線段,在線性代數中,向量經常以原點作為起點,
用行的方式排列的向量叫作行向量,用列的方式排列的向量叫作列向量,習慣上,我們說向量時都是指列向量,如果是行向量,會加上一個上標符號T, T代表轉置,
| – | 行向量 | 列向量 |
|---|---|---|
| 示例 | α = ( 2 , 4 , 6 ) \boldsymbol\alpha=(2,4,6) α=(2,4,6) | β = [ 2 4 7 ] \boldsymbol\beta=\begin{bmatrix}\\2 \\4 \\7\end{bmatrix} β=???247???? |
| 列向量表示法 | α T \boldsymbol\alpha^T αT | β \boldsymbol\beta β |
1.2 創建向量
NumPy(Numerical Python) 是 Python 語言的一個擴展程式庫,支持大量的維度陣列與矩陣運算,此外也針對陣列運算提供大量的數學函式庫,此處以Numpy為例進行演示,
# 創建向量,利用Numpy中的ndarray定義一個一維陣列物件,就相當于創建了一個向量
import numpy as np
x=np.array([1,2,3,4,5])
y=np.array([2,5,6,3,2])
#結果為 [1 2 3 4 5]和 [2 5 6 3 2]
注意:如果兩個向量的維數相同,并且對應元素相等,才說明兩個向量相等,
#判斷向量是否相等
np.all(x==y)
#結果為 False
1.3 向量的范數(模長)
向量的長度,也叫作向量的二范數、模長,其計算公式就是兩點間歐氏距離公式,記作
∥
a
∥
=
[
a
1
a
2
?
a
n
]
=
a
1
2
+
a
2
2
+
?
+
a
n
2
∥a∥=\begin{bmatrix}\\a_1 \\a_2 \\\vdots\\a_n\end{bmatrix}=\sqrt {a_1^2+a_2^2+\cdots+a_n^2}
∥a∥=??????a1?a2??an????????=a12?+a22?+?+an2?
?
可以利用Numpy中的linalg(線性代數)子模塊進行運算:
#計算向量的長度
np.linalg.norm(x)
#結果為 7.416198487095663
1.4 向量加法(減法)
向量的加法(減法)就是兩個維度相同的向量的對應元素之間的相加(減),
[
a
1
α
2
]
+
[
b
1
b
2
]
=
[
a
1
+
b
1
a
2
+
b
2
]
\begin{bmatrix}\\a_1 \\\alpha_2 \\\end{bmatrix}+\begin{bmatrix}\\b_1 \\b_2 \\\end{bmatrix}=\begin{bmatrix}\\a_1+b_1 \\a_2+b_2 \\\end{bmatrix}
[a1?α2??]+[b1?b2??]=[a1?+b1?a2?+b2??]
也可以從幾何的角度理解向量的加減法運算:
將兩個向量作為兩條邊,起點相同畫一個平行四邊形,對角線向量就是兩個向量的和向量;兩個向量的減法為平行四邊形的另一條對角線,
在python中這樣計算:
#向量減法,加法類似
z=x-y
#結果為 [-1 -3 -3 1 3]
1.5 向量的數乘
指向量與一個數字相乘,等于向量的各個分量都乘以相同的系數
[
a
1
a
2
]
?
k
=
[
a
1
?
k
a
2
?
k
]
\begin{bmatrix}\\a_1 \\a_2 \\\end{bmatrix}*k=\begin{bmatrix}\\a_1*k \\a_2 *k \\\end{bmatrix}
[a1?a2??]?k=[a1??ka2??k?]
在python中這樣計算:
#向量的數乘
z=10*x
#結果為 [10 20 30 40 50]
1.6 向量的乘法(點積)
指兩個向量對應元素之積的和,得到的是一個數字,
[
a
1
a
2
?
a
n
]
.
[
b
1
b
2
?
b
n
]
=
a
1
b
1
+
a
2
b
2
?
+
a
n
b
n
\begin{bmatrix}\\a_1 \\a_2 \\\vdots\\a_n\end{bmatrix}.\begin{bmatrix}\\b_1 \\b_2 \\\vdots\\b_n\end{bmatrix}=a_1b_1 +a_2b_2 \cdots+a_nb_n
??????a1?a2??an????????.??????b1?b2??bn????????=a1?b1?+a2?b2??+an?bn?
在python中這樣計算:
#向量的點積,使用numpy.dot方法
np.dot(x,y)
#結果為 52
在數值上等于兩個向量的長度和夾角余弦之積,即:
a
?
b
=
∣
∣
a
∣
∣
?
∣
∣
b
∣
∣
?
cos
?
θ
a·b=||a||*||b||*\cos\theta
a?b=∣∣a∣∣?∣∣b∣∣?cosθ
二、向量化
文本向量化屬于自然語言處理的范疇,在所有資料任務中,機器處理的都是全是數字的向量,文本向量化就是將文本表示成一系列能夠表達文本語意的向量,
文本向量化主要有以下幾種方法:
2.1 One-Hot Encoding方式
獨熱編碼,又稱一位有效編碼,其方法是使用N位狀態暫存器來對N個狀態進行編碼,每個狀態都有它獨立的暫存器位,并且在任意時候,其中只有一位有效,
大致步驟為:①分詞②構造文本分詞后的字典③對詞語進行One-hot編碼,
例如:
對于句子’I , I , I love study’和’study is my angle!’,首先將其看做為一篇檔案,分詞之后,構成字典包括’angle’, ‘i’, ‘is’, ‘love’, ‘my’, 'study’六個單詞,再對每個句子進行分詞,若句子中出現字典中的字,則記為1,否則記為0,最終得到編碼表如下所示,
| – | angle | i | is | love | my | study |
|---|---|---|---|---|---|---|
| I , I , I love study | 0 | 1 | 0 | 1 | 0 | 1 |
| study is my angle | 1 | 0 | 1 | 0 | 1 | 1 |
代碼如下:(此處為英文句子,英文句子默認會分詞,而中文不會)
from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd
corpus=['I , I , I love study', 'study is my angle!']
vectorizer=CountVectorizer(min_df=1, binary=True, token_pattern='\w{1,}')
# token_pattern:通過正則運算式來確定哪些資料被過濾掉,默認情況下單個英文字母會被過濾掉,代碼中的\w{1,}可以避免這種情況
data=vectorizer.fit_transform(corpus)
print(vectorizer.get_feature_names()) # 特征名稱
print(vectorizer.vocabulary_) # 特征在串列中的索引位
print(data)
df = pd.DataFrame(data.toarray(), columns=vectorizer.get_feature_names()) # to DataFrame
print(df.head())
得到結果如下:
['angle', 'i', 'is', 'love', 'my', 'study'] #獲取到的特征,這里為一個一個的單詞
{'i': 1, 'love': 3, 'study': 5, 'is': 2, 'my': 4, 'angle': 0} #各個特征的索引號,例如‘i’:1 表示字符i在特征表中的索引為 1
#得到稀疏矩陣,比如(0,5) 1 表示在全部矩陣的第0行第5列有資料1,在稀疏矩陣中沒有表示的索引全部為0
(0, 5) 1
(0, 3) 1
(0, 1) 1
(1, 0) 1
(1, 4) 1
(1, 2) 1
(1, 5) 1
#以下為最終的編碼表
angle i is love my study
0 0 1 0 1 0 1
1 1 0 1 0 1 1
2.2 詞袋(BOW)模型
詞袋模型(Bag-of-words model,BOW),BOW模型假定對于一個檔案,忽略它的單詞順序和語法、句法等要素,將其僅僅看作是若干個詞匯的集合,檔案中每個單詞的出現都是獨立的,不依賴于其它單詞是否出現,
與獨熱編碼不同的是,詞袋模型要把文章中所有單詞的向量做加法運算,相當于記錄每個單詞的出現頻次,依舊使用之前的例子,利用詞袋模型得到的編碼為:
| – | angle | i | is | love | my | study |
|---|---|---|---|---|---|---|
| I , I , I love study | 0 | 3 | 0 | 1 | 0 | 1 |
| study is my angle | 1 | 0 | 1 | 0 | 1 | 1 |
代碼如下:
from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd
corpus=['I , I , I love study', 'study is my angle!']
# 將binary引數設定為False,表示不需要二值化
vectorizer=CountVectorizer(min_df=1, binary=False, token_pattern='\w{1,}')
data=vectorizer.fit_transform(corpus)
print(vectorizer.get_feature_names()) # 特征名稱
print(vectorizer.vocabulary_) # 特征在串列中的索引位
print(data)
df = pd.DataFrame(data.toarray(), columns=vectorizer.get_feature_names()) # to DataFrame
print(df.head())
最終得到結果:
['angle', 'i', 'is', 'love', 'my', 'study']
{'i': 1, 'love': 3, 'study': 5, 'is': 2, 'my': 4, 'angle': 0}
(0, 5) 1
(0, 3) 1
(0, 1) 3
(1, 0) 1
(1, 4) 1
(1, 2) 1
(1, 5) 1
angle i is love my study
0 0 3 0 1 0 1
1 1 0 1 0 1 1
2.3 TF-IDF
TF-IDF(term frequency–inverse document frequency)是一種用于資訊檢索與資料挖掘的常用加權技術,TF意思是詞頻(Term Frequency),IDF意思是逆文本頻率指數(Inverse Document Frequency),
字詞的重要性隨著它在檔案中出現的次數成正比增加,但同時會隨著它在語料庫中出現的頻率成反比下降,一個詞語在一篇文章中出現次數越多, 同時在所有檔案中出現次數越少, 越能夠代表該文章,
一個詞x的IDF值公式如下:
I
D
F
(
x
)
=
l
o
g
N
N
(
x
)
IDF(x)=log\frac{N}{N(x)}
IDF(x)=logN(x)N?
其中N代表語料庫中文本的總數,而N(x)代表語料庫中包含詞x的文本總數,
上面的IDF公式已經可以使用了,但是在一些特殊的情況會有一些小問題,比如某一個生僻詞在語料庫中沒有,這樣我們的分母為0, IDF沒有意義了,所以常用的IDF我們需要做一些平滑,使語料庫中沒有出現的詞也可以得到一個合適的IDF值,平滑的方法有很多種,最常見的IDF平滑后的公式之一為:
I
D
F
(
x
)
=
l
o
g
N
N
(
x
)
+
1
IDF(x)=log\frac{N}{N(x)+1}
IDF(x)=logN(x)+1N?
代碼如下:
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer
corpus=["I like to travel","I love tea"]
vectorizer=CountVectorizer(min_df=1, binary=False, token_pattern='\w{1,}')
transformer = TfidfTransformer()
tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))
print(tfidf)
df = pd.DataFrame(tfidf.toarray(), columns=vectorizer.get_feature_names()) # to DataFrame
print(df.head())
結果如下,可以明顯看到 i 的值較其他值是較低的:
(0, 0) 0.37997836159100784
(0, 1) 0.534046329052269
(0, 4) 0.534046329052269
(0, 5) 0.534046329052269
(1, 0) 0.4494364165239821
(1, 2) 0.6316672017376245
(1, 3) 0.6316672017376245
i like love tea to travel
0 0.379978 0.534046 0.000000 0.000000 0.534046 0.534046
1 0.449436 0.000000 0.631667 0.631667 0.000000 0.000000
或者使用用TfidfVectorizer一步到位,代碼如下:
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf2 = TfidfVectorizer(token_pattern='\w{1,}')
re = tfidf2.fit_transform(corpus)
print(re)
結果與第一種的輸出完全相同,
2.4 三種方法的缺點
較為明顯地可以看到,以上三種文本向量化的方式或多或少存在著以下缺點:
| – | 缺點 |
|---|---|
| One-hot編碼 | ①維數過高,隨著語料的增加,維數會越來越大,導致維數災難;②矩陣稀疏,從上面也可以看到,每一個詞向量只有1維是有數值的,其他維上的數值都為0;③不能保留語意,用這種方式得到的結果不能保留詞語在句子中的位置資訊, |
| 詞袋(BOW)模型 | ①不能保留語意;②矩陣稀疏 |
| TF-IDF | 不能保留語意,無法處理一詞多義與一義多詞的情況 |
上述三種方法最大的缺點就是單詞的編碼不能體現詞義,對于任何兩個單詞向量而言,它們的夾角余弦相似度都是0,無法體現詞義之間的關系,因此,谷歌提出了Word2Vec,可以在一定程度上解決這個問題,關于這個問題,我們下一篇博客詳細討論,
歡迎大家在評論區提出自己對本篇博客的看法和建議,有問題可留言或私戳我~
參考文獻
[1] 張曉明.人工智能基礎——數學知識.北京:人民郵電出版社.2020.
[2] https://www.cnblogs.com/dogecheng/p/11470196.html
[3] https://blog.csdn.net/Clannad_niu/article/details/95216996
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/289472.html
標籤:AI
