一.Web服務(wù)器
二.一些原理
三.Redis
四.爬蟲
五.數(shù)據(jù)分析
六.機(jī)器學(xué)習(xí)
七.深度學(xué)習(xí)
六.機(jī)器學(xué)習(xí)
0.基礎(chǔ)知識(shí)
- 基礎(chǔ)概念
訓(xùn)練集:用來進(jìn)行訓(xùn)練纲酗,產(chǎn)生模型/算法的數(shù)據(jù)集霍狰。
測(cè)試集:用來進(jìn)行測(cè)試已經(jīng)學(xué)習(xí)好模型/算法的數(shù)據(jù)集。
特征向量:屬性的集合砚哗,通常用一個(gè)向量表示龙助,影響目標(biāo)結(jié)果的一組元素。
標(biāo)記:實(shí)例類別的標(biāo)記蛛芥,目標(biāo)結(jié)果的值提鸟。
分類:目標(biāo)標(biāo)記為類別型數(shù)值脆淹。
回歸:目標(biāo)標(biāo)記為連續(xù)性數(shù)值。
有監(jiān)督學(xué)習(xí):訓(xùn)練集有類別標(biāo)記沽一。
無監(jiān)督學(xué)習(xí):無類別標(biāo)記盖溺。
半監(jiān)督學(xué)習(xí):有類別標(biāo)記的訓(xùn)練集+無類別標(biāo)記的訓(xùn)練集。 - 基礎(chǔ)步驟
a.把數(shù)據(jù)拆分為訓(xùn)練集和測(cè)試集
b.用訓(xùn)練集和訓(xùn)練集的特征向量訓(xùn)練算法
c.用學(xué)習(xí)來的算法在測(cè)試集上來評(píng)估算法(可能涉及到調(diào)整參數(shù)用驗(yàn)證集)
1.特征工程
特征是數(shù)據(jù)中抽取出來的對(duì)結(jié)果預(yù)測(cè)有用的信息铣缠,可以是文本或者數(shù)據(jù)烘嘱。
關(guān)鍵步驟是數(shù)據(jù)采集(清洗,采樣),特征處理
數(shù)據(jù)采集:哪些數(shù)據(jù)對(duì)最后的結(jié)果預(yù)測(cè)有幫助就采集哪些數(shù)據(jù),處理其中臟數(shù)據(jù)和過多缺省數(shù)據(jù)蝗蛙,采樣正負(fù)均衡的數(shù)據(jù)蝇庭。
特征處理,包括數(shù)值型捡硅,類別型哮内,時(shí)間型數(shù)據(jù)的處理。
可以使用scikit-learn模塊壮韭,基于numpy數(shù)據(jù)做統(tǒng)一處理北发。
對(duì)于特征為數(shù)值型數(shù)據(jù)的預(yù)處理(此時(shí)每個(gè)特征的重要性看為同等重要):
- 歸一化
- 標(biāo)準(zhǔn)化
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import StandardScaler
"""數(shù)值數(shù)據(jù)特征預(yù)處理"""
#使用MinMaxScaler進(jìn)行歸一化處理
"""
按列進(jìn)行x=(x-min/max-min)*(mx-mi)+mi
其中min=該列最小數(shù)值
max=該列最大數(shù)值
mx=要求結(jié)果集范圍最大上限,默認(rèn)1
mi=要求結(jié)果集范圍最小下限,默認(rèn)0
特點(diǎn):異常數(shù)據(jù)(極端值)對(duì)結(jié)果影響大
"""
def minmaxsc():
mm=MinMaxScaler(feature_range=(2,3)) #默認(rèn)(0,1)
narray =[[53,9,22],[18,66,70],[12,32,91]]
data=mm.fit_transform(narray)
print(data)
#使用StandardScaler行標(biāo)準(zhǔn)化處理
"""
按列進(jìn)行x=(x-mean)/標(biāo)準(zhǔn)差
其中mean=該列平均值
方差=(x1-mean)2+(x2-mean)2+.../n喷屋,標(biāo)準(zhǔn)差=方差的平方根
每一列計(jì)算的結(jié)果相加為0
特點(diǎn):異常數(shù)據(jù)對(duì)結(jié)果影響小
標(biāo)準(zhǔn)差反應(yīng)數(shù)據(jù)的穩(wěn)定性琳拨,越大表示數(shù)據(jù)波動(dòng)性越強(qiáng)
"""
def standarsc():
ss=StandardScaler()
narray =[[53,9,22],[18,66,70],[12,32,91]]
data=ss.fit_transform(narray)
print(data)
對(duì)類別數(shù)據(jù)特征處理,比如文本數(shù)據(jù)(one-hot方式):
- 先進(jìn)行數(shù)據(jù)的提取屯曹,
- 再按照規(guī)則使用數(shù)值表示
from sklearn.feature_extraction import DictVectorizer
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
import jieba
"""
字典處理
構(gòu)成二維矩陣
分詞的數(shù)量代表處理的行索引狱庇;數(shù)據(jù)個(gè)數(shù)作為列索引
分詞原則是非數(shù)值數(shù)據(jù)直接連接為特征(name=zs),對(duì)應(yīng)的二維數(shù)組中滿足為1,不滿足為0
數(shù)值型數(shù)據(jù)直接賦值到指定二維數(shù)組位置
"""
def dictvec():
dv=DictVectorizer(sparse=False)
data=dv.fit_transform([{"name":"zs","age":18},{"name":"mm","age":24},{"name":"cc","age":28}])
#數(shù)據(jù)提取結(jié)果
print(dv.get_feature_names())
#數(shù)據(jù)顯示樣式
print(data)
"""
文本數(shù)據(jù)處理-普通方式
同樣分詞結(jié)果作為行索引恶耽,矩陣中的數(shù)字代表分詞出現(xiàn)的次數(shù)
"""
def countvec():
cv=CountVectorizer()
#英文會(huì)自動(dòng)按照空格分詞密任,單字母忽略(認(rèn)為對(duì)預(yù)測(cè)結(jié)果無意義)
earray=["i am zs,i like mm","she is mm,like zs,hi zs"]
#中文可以先用jieba模塊進(jìn)行分詞處理
zarray=["我是一個(gè)小企鵝,我喜歡吃魚","我是一個(gè)大白熊偷俭,我喜歡吃企鵝"]
temp=[]
for zh in zarray:
temp.append(jiebafilter(zh))
print(temp)
data=cv.fit_transform(temp)
#單字母不作為特征抽取的元素
print(cv.get_feature_names())
print(data.toarray())
"""
文本數(shù)據(jù)處理-tfidf更優(yōu)化的方式
tfidf方式可以計(jì)算出分詞的重要性
一個(gè)分詞在同一段文字中出現(xiàn)的次數(shù)越多浪讳,且在整個(gè)段落中出現(xiàn)的次數(shù)越少,那么越重要
比如我們社搅,那么驻债,等等之類的分詞雖然經(jīng)常出現(xiàn)乳规,但并不重要
"""
def tfidfvec():
tf = TfidfVectorizer()
zarray = ["我是一個(gè)小企鵝形葬,我喜歡吃魚", "我是一個(gè)大白熊,我喜歡吃企鵝","我是大鯊魚暮的,我喜歡吃大白熊"]
temp = []
for zh in zarray:
temp.append(jiebafilter(zh))
print(temp)
data = tf.fit_transform(temp)
print(tf.get_feature_names())
print(data.toarray())
#使用jieba模塊進(jìn)行中文分詞處理
def jiebafilter(str):
list=jieba.cut(str)
content=" ".join(iter(list))
return content
通過數(shù)據(jù)抽取或者降維精化特征數(shù)據(jù)
在用統(tǒng)計(jì)分析方法研究多變量的課題時(shí)笙以,變量個(gè)數(shù)太多就會(huì)增加課題的復(fù)雜性。人們自然希望變量個(gè)數(shù)較少而得到的
信息較多冻辩。在很多情形猖腕,變量之間是有一定的相關(guān)關(guān)系的拆祈,當(dāng)兩個(gè)變量之間有一定相關(guān)關(guān)系時(shí),可以解釋為這兩個(gè)變量反
映此課題的信息有一定的重疊倘感。主成分分析是對(duì)于原先提出的所有變量放坏,將重復(fù)的變量(關(guān)系緊密的變量)刪去多余,建立
盡可能少的新變量老玛,使得這些新變量是兩兩不相關(guān)的淤年,而且這些新變量在反映課題的信息方面盡可能保持原有的信息。
常用方式:
- 數(shù)據(jù)特征的抽取
- 主成分分析之PCA
from sklearn.feature_selection import VarianceThreshold
from sklearn.decomposition import PCA
"""
數(shù)據(jù)抽取
"""
def varienceth():
#指定方差為0的列被屏蔽
vt=VarianceThreshold(threshold=0.0)
data=vt.fit_transform([[1,2,3],[2,2,3],[3,3,3]])
print(data)
"""
主成分分析
PCA主要通過把數(shù)據(jù)從高維映射到低維來降低特征維度蜡豹。(投影)
盡可能的保留能夠反映真實(shí)特征數(shù)據(jù)的數(shù)據(jù)量麸粮,且去除重復(fù)數(shù)據(jù)
"""
def pca():
#保留90%的有效數(shù)據(jù)
pc=PCA(n_components=0.9)
data=pc.fit_transform([[53,9,22,1],[18,66,70,16],[12,32,91,30],[23,76,45,22]])
print(data)
print(data.shape)
2.機(jī)器學(xué)習(xí)算法
開發(fā)流程
- 準(zhǔn)備數(shù)據(jù)(75%用于訓(xùn)練,25%用于測(cè)試)
- 建立模型镜廉,明確做的事情
- 基礎(chǔ)數(shù)據(jù)處理
- 特征工程
- 使用合適算法
- 評(píng)估模型
- 上線API
from sklearn.datasets import load_iris,fetch_20newsgroups,load_boston
from sklearn.model_selection import train_test_split
"""展示一組機(jī)器算法監(jiān)督類目標(biāo)離散的數(shù)據(jù)"""
def testir():
li=load_iris()
#輸入數(shù)據(jù)
print(li.data)
#目標(biāo)數(shù)據(jù)
print(li.target)
#描述
print(li.DESCR)
#把數(shù)據(jù)按照75%的訓(xùn)練數(shù)據(jù),25%的測(cè)試數(shù)據(jù)切分
xtrain,xtest,ytrain,ytest=train_test_split(li.data,li.target,test_size=0.25)
#75%訓(xùn)練的特征值和目標(biāo)值
print(xtrain,ytrain)
#25%測(cè)試的特征值和目標(biāo)值
print(xtest,ytest)
"""展示一組機(jī)器算法監(jiān)督類目標(biāo)連續(xù)的數(shù)據(jù)"""
def testlb():
lb=load_boston()
print(lb.data)
print(lb.target)
機(jī)器學(xué)習(xí)算法使用:
監(jiān)督學(xué)習(xí)-處理分類[離散目標(biāo)值]:K-鄰近算法弄诲,決策樹,支持向量機(jī)SVM娇唯,神經(jīng)網(wǎng)絡(luò)
監(jiān)督學(xué)習(xí)-處理回歸[連續(xù)目標(biāo)值]:線性回歸齐遵,非線性回歸
非監(jiān)督學(xué)習(xí)[無目標(biāo)值]:K-Means,層次聚類
K-鄰近算法
k近鄰法(k-nearest neighbor, k-NN)是1967年由Cover T和Hart P提出的一種基本分類與回歸方法塔插。它的工作原理是:存在一個(gè)樣本數(shù)據(jù)集合洛搀,也稱作為訓(xùn)練樣本集,并且樣本集中每個(gè)數(shù)據(jù)都存在標(biāo)簽佑淀,即我們知道樣本集中每一個(gè)數(shù)據(jù)與所屬分類的對(duì)應(yīng)關(guān)系留美。輸入沒有標(biāo)簽的新數(shù)據(jù)后,將新的數(shù)據(jù)的每個(gè)特征與樣本集中數(shù)據(jù)對(duì)應(yīng)的特征進(jìn)行比較伸刃,然后算法提取樣本最相似數(shù)據(jù)(最近鄰)的分類標(biāo)簽谎砾。一般來說,我們只選擇樣本數(shù)據(jù)集中前k個(gè)最相似的數(shù)據(jù)捧颅,這就是k-近鄰算法中k的出處景图,通常k是不大于20的整數(shù)。最后碉哑,選擇k個(gè)最相似數(shù)據(jù)中出現(xiàn)次數(shù)最多的分類挚币,作為新數(shù)據(jù)的分類。
參考:https://cuijiahua.com/blog/2017/11/ml_1_knn.html
0.簡(jiǎn)單理解
【我們想要預(yù)測(cè)打斗101扣典,接吻20次的電影分類妆毕,該如何使用KNN做呢?】
本例子中影響電影分類的因素只有兩個(gè)特征值,把打斗次數(shù)和接吻作為平面坐標(biāo)系x,y贮尖。在直角坐標(biāo)系中可以繪制出幾個(gè)點(diǎn)笛粘。
(如果特征數(shù)是N個(gè),那就是在N維坐標(biāo)系好了)
把想要預(yù)測(cè)的點(diǎn)繪制到該坐標(biāo)系中,計(jì)算和其他點(diǎn)之間的距離
利用距離公式:
通過計(jì)算薪前,我們可以得到如下結(jié)果:
(101,20)->動(dòng)作片(108,5)的距離約為16.55
(101,20)->動(dòng)作片(115,8)的距離約為18.44
(101,20)->愛情片(5,89)的距離約為118.22
(101,20)->愛情片(1,101)的距離約為128.69
令K=3润努,選擇距離最近的3個(gè)點(diǎn)坐標(biāo),其中2個(gè)動(dòng)作片示括,1個(gè)愛情片铺浇,取多數(shù),預(yù)測(cè)結(jié)果為愛情片垛膝。
(如果特征數(shù)是N個(gè)随抠,使用歐拉公式,一般K取奇數(shù)繁涂,目的是能選到多數(shù)值)
以上KNN模型可以看出:
優(yōu)點(diǎn):簡(jiǎn)單拱她,數(shù)據(jù)不需要迭代訓(xùn)練
缺點(diǎn):計(jì)算量大(數(shù)據(jù)量越大,性能越差)扔罪;K值定義不準(zhǔn)影響結(jié)果(過大過小都不好)秉沼;無法給出數(shù)據(jù)內(nèi)在定義。做圖像識(shí)別表現(xiàn)不好矿酵,因?yàn)槭褂玫臑橄袼靥卣骰8矗Y(jié)果可能是顏色相近的距離更近。
改進(jìn)方向:距離加權(quán)重
圖中x點(diǎn)應(yīng)該更貼近紅色點(diǎn)全肮,但是猶豫周邊藍(lán)色點(diǎn)多敞咧,影響預(yù)測(cè),所以把距離上權(quán)重一起判斷更準(zhǔn)確辜腺。
1.代碼實(shí)現(xiàn)
使用sklearn-datasets數(shù)據(jù)集預(yù)測(cè)花的種類
from sklearn import neighbors
from sklearn import datasets
#指定K=3的KNN模型算法
knn=neighbors.KNeighborsClassifier(n_neighbors=3)
#使用sklearn自帶數(shù)據(jù)集(花朵識(shí)別)
iris=datasets.load_iris()
print(iris)
#使用knn構(gòu)建模型
knn.fit(iris.data,iris.target)
#預(yù)測(cè)一個(gè)[[0.1,0.2,0.3,0.4]]的結(jié)果
predictedLabel=knn.predict([[0.1,0.2,0.3,0.4]])
print("predictedLabel=",predictedLabel)
拆分sklearn-datasets數(shù)據(jù)集休建,判斷預(yù)測(cè)準(zhǔn)確性
from sklearn.neighbors import KNeighborsClassifier
from sklearn import datasets
from sklearn.model_selection import train_test_split
def knn():
li = datasets.load_iris()
xtrain, xtest, ytrain, ytest = train_test_split(li.data, li.target, test_size=0.25)
#構(gòu)建一個(gè)K=3的K-近鄰算法模型
knn=KNeighborsClassifier(n_neighbors=3)
#根據(jù)拆分的訓(xùn)練特征值和目標(biāo)值進(jìn)行計(jì)算
knn.fit(xtrain,ytrain)
#預(yù)測(cè)測(cè)試數(shù)據(jù)集
y_predict=knn.predict(xtest)
#預(yù)測(cè)結(jié)果和真實(shí)結(jié)果進(jìn)行比較
print("預(yù)測(cè)結(jié)果:%s 實(shí)際結(jié)果:%s"%(y_predict,ytest))
#得出準(zhǔn)備率
res=knn.score(xtest,ytest)
print("準(zhǔn)確率:%s"%res)
使用交叉驗(yàn)證和網(wǎng)格搜索優(yōu)化找更合適的K值
def knn():
li = load_iris()
xtrain, xtest, ytrain, ytest = train_test_split(li.data, li.target, test_size=0.25)
knn = KNeighborsClassifier()
params={"n_neighbors":[3,5,10]}
gs=GridSearchCV(knn,param_grid=params,cv=2)
gs.fit(xtrain,ytrain)
print("測(cè)試集準(zhǔn)確率:",gs.score(xtest,ytest))
print("交叉集最好的結(jié)果:",gs.best_score_)
print("選擇最好的模型:",gs.best_estimator_)
print("每個(gè)交叉參數(shù)集結(jié)果:",gs.cv_results_)
個(gè)人理解:
把訓(xùn)練集特征數(shù)據(jù)構(gòu)建N維圖形中(eg:2個(gè)特征就對(duì)應(yīng)一個(gè)平面的點(diǎn),3個(gè)特征就對(duì)應(yīng)一個(gè)三維空間的點(diǎn))评疗,輸入一個(gè)未知目標(biāo)的特征數(shù)據(jù)組测砂,映射到該圖形中,找到附近已知目標(biāo)特征中的數(shù)據(jù)百匆,哪個(gè)多就選哪個(gè)砌些。
樸素貝葉斯算法
原理:樸素貝葉斯(naive Bayes)法是是基于貝葉斯定理 和特征條件獨(dú)立假設(shè)的分類方法,對(duì)于給定的訓(xùn)練數(shù)據(jù)集加匈,首先基于特征條件獨(dú)立假設(shè)學(xué)習(xí)輸入/輸出的聯(lián)合分布概率存璃;然后基于此模型,對(duì)給定的輸入x雕拼,再利用貝葉斯定理求出其后驗(yàn)概率最大的輸出y纵东。主要用于文本分類。
基礎(chǔ)知識(shí):
1.概率論中條件概率P(A|B)=滿足B條件下A事件的概率
2.P(A1,A2|B)=P(A1|B)P(A2|B) (A1,A2相互獨(dú)立)
3.P(A|B)=P(B|A)P(A)/P(B)
4.如果有的數(shù)據(jù)為0,使用拉普拉斯平滑悲没,讓分子和分母加一個(gè)數(shù)字,eg:1
5.精確率:預(yù)測(cè)結(jié)果為正例樣本中真實(shí)為正例的比例(準(zhǔn))
召回率:真實(shí)為正例中預(yù)測(cè)結(jié)果為正例比例(全)
參考:https://blog.csdn.net/zhengzhenxian/article/details/79052185
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics.classification import classification_report
"""樸素貝葉斯算法"""
def mnb():
newsdata=fetch_20newsgroups()
xtrain, xtest, ytrain, ytest = train_test_split(newsdata.data,newsdata.target,test_size=0.25)
tf=TfidfVectorizer()
#fit_transform訓(xùn)練數(shù)據(jù),tranform測(cè)試數(shù)據(jù)
xtrain=tf.fit_transform(xtrain)
xtest=tf.transform(xtest)
print(tf.get_feature_names())
print(xtrain.toarray())
print(xtest.toarray())
mnb=MultinomialNB(alpha=1.0)
mnb.fit(xtrain,ytrain)
y_predict=mnb.predict(xtest)
print(y_predict)
print("準(zhǔn)確率:%s"%mnb.score(xtest,ytest))
print("新聞數(shù)據(jù)每種類型的準(zhǔn)確率和召回率:",classification_report(ytest,y_predict,target_names=newsdata.target_names))
優(yōu)點(diǎn):穩(wěn)定篮迎,對(duì)缺失值不敏感
缺點(diǎn):條件獨(dú)立性假設(shè)
個(gè)人理解:
適合多分類任務(wù),特征為離散型數(shù)據(jù)且相互獨(dú)立示姿,利用概率論基礎(chǔ)甜橱,統(tǒng)計(jì)這些離散型特征數(shù)據(jù)對(duì)目標(biāo)影響概率,對(duì)于未知目標(biāo)數(shù)據(jù)栈戳,選擇最優(yōu)概率解岂傲。
決策樹算法
參考:https://www.cnblogs.com/yonghao/p/5061873.html
通過以上數(shù)據(jù)構(gòu)建一顆決策樹:
通過該決策樹,可以直觀看出子檀,通過該模型直接可以預(yù)測(cè)結(jié)果镊掖,難么如何構(gòu)建決策樹【根節(jié)點(diǎn)和葉子節(jié)點(diǎn)選取】呢?需要引入一些概念和方法褂痰。
0.基礎(chǔ)概念
- 熵(Entropy):熵描述了數(shù)據(jù)的混亂程度亩进,熵越大,混亂程度越高缩歪,也就是純度越低归薛。
其中Pi表示類i的數(shù)量占比匪蝙。以二分類問題為例主籍,如果兩類的數(shù)量相同,此時(shí)分類節(jié)點(diǎn)的純度最低逛球,熵等于1千元;如果節(jié)點(diǎn)的數(shù)據(jù)屬于同一類時(shí),此時(shí)節(jié)點(diǎn)的純度最高颤绕,熵等于0幸海。
eg:2個(gè)因素對(duì)結(jié)果影響概率都是1/2,那么Entropy=[-(1/2)log2(1/2)]+[-(1/2)log2(1/2)]=1
2個(gè)因素對(duì)結(jié)果影響概率一個(gè)是1奥务,一個(gè)是0涕烧,那么Entropy=[-(0/2)log2(0/2)]+[-(1)log2(1)]=0 - 信息獲取量(Information_Gain):Info(A)=Info(D)-Info_A(D)
【本例中,Age作為跟節(jié)點(diǎn)汗洒,說明Age對(duì)預(yù)測(cè)結(jié)果Buys Computer影響最大议纯,那么如何選取到Age特征作為根節(jié)點(diǎn)呢】
A的信息獲取量=目標(biāo)熵-去除特征A的熵。用測(cè)試數(shù)據(jù)表示Age的Information_Gain:
Info(D)[5-NO 9-YES]=-9/14log2(9/14)-5/14log(5/14)=0.94bit
Info_A(D)[5-Youth 4-Middle_age 5-Senior]=5/14[-2/5log2(2/5)-3/5log2(3/5)]+4/14[-4/4log2(4/4)-0/4log2(0/4)]+5/14[-2/5log2(2/5)-3/5*log2(3/5)]=0.69bit
那么溢谤,Gain(Age)=Info(A)=0.94-0.69=0.25bit
同理瞻凤,Gain(Income)=0.029 Gain(Student)=0.151 Gain(Credit)=0.048
所以,使用Age為根節(jié)點(diǎn)世杀。
1.構(gòu)建過程
使用每一個(gè)特征值計(jì)算該特征值的Information_Gain阀参。
選取最大的Information_Gain作為根節(jié)點(diǎn),其他節(jié)點(diǎn)通過該特征值分類分到不同分支中瞻坝。
在分支中蛛壳,同樣把每個(gè)特征值計(jì)算該特征值的Information_Gain,以此循環(huán)。
直到?jīng)]有可分的特征值衙荐,如果還有多種目標(biāo)值捞挥,那么把目標(biāo)結(jié)果最多的作為結(jié)果。
優(yōu)缺點(diǎn):
直觀忧吟,便于理解砌函,小規(guī)模數(shù)據(jù)集有效;
處理連續(xù)變量不好溜族,類別較多時(shí)錯(cuò)誤增加較多讹俊;
2.代碼實(shí)現(xiàn)
from sklearn.feature_extraction import DictVectorizer
import csv
from sklearn import preprocessing
from sklearn import tree
"""
sklearn提供相關(guān)機(jī)器學(xué)習(xí)的算法,但是數(shù)據(jù)格式需要整理成sklearn的標(biāo)準(zhǔn)
例如age屬性:youth,middle_age,senior
如果對(duì)應(yīng)youth煌抒,則化為100仍劈,middle_age化為010 senior化為001(順序可能有變化),其他屬性也類似
原始數(shù)據(jù)第一行 Youth(Youth,Middle_age,Senior) High(High,Low,Medium) No(No,Yes) Fair(Fair,Excellent) No(Yes,No)
轉(zhuǎn)化成-> 1 0 0 1 0 0 0 1 1 0 0
"""
#把原始數(shù)據(jù)用csv導(dǎo)入
allData=open(r"origindata.csv","r")
reader=csv.reader(allData)
headers=next(reader)
#第一行數(shù)據(jù)表示表頭,不作為學(xué)習(xí)模型數(shù)據(jù)
print("headers:",headers)
#定義特征數(shù)組和目標(biāo)數(shù)組
featureList=[]
labelList=[]
#csv數(shù)據(jù)整理成字典數(shù)組
for row in reader:
labelList.append(row[len(row)-1])
rowDict={}
for i in range(1,len(row)-1):
rowDict[headers[i]]=row[i]
featureList.append(rowDict)
print(featureList)
#使用整理好的字典數(shù)組生成01特征數(shù)據(jù)和01目標(biāo)數(shù)據(jù)格式(順序按照feature_names對(duì)應(yīng))
vec=DictVectorizer()
dummyX=vec.fit_transform(featureList).toarray()
print("dummyX:",dummyX)
print(vec.get_feature_names())
print("labelList:",labelList)
lb=preprocessing.LabelBinarizer()
dummyY=lb.fit_transform(labelList)
print("dummyY:",dummyY)
#使用決策樹策略-熵算法進(jìn)行模型創(chuàng)建
clf=tree.DecisionTreeClassifier(criterion="entropy")
clf=clf.fit(dummyX,dummyY)
print("clf:",clf)
#改變第一行原始數(shù)據(jù)值寡壮,并做一個(gè)預(yù)測(cè)
oneRowX=dummyX[0]
print("oneRowX",oneRowX)
newRowX=oneRowX
newRowX[0]=1
newRowX[1]=0
newRowX[2]=0
print("newRowX:",newRowX)
predictedY=clf.predict(newRowX.reshape(1,-1))
print("predictedY",predictedY)
個(gè)人理解:
以信息論為基礎(chǔ)耳奕,構(gòu)建一顆子節(jié)點(diǎn)按照重要程度下降的決策樹(影響越大的結(jié)點(diǎn)越接近根節(jié)點(diǎn)),對(duì)于未知目標(biāo)的特征數(shù)據(jù)诬像,按照路徑判斷最終所屬節(jié)點(diǎn)屋群。
其中:如何找到最重要影響特征以及分裂的屬性的選擇都是利用信息論方法決定。
支持向量機(jī)SVM
參考:https://zhuanlan.zhihu.com/p/77750026
0.基本理解
大體上坏挠,按照兩種方式劃分芍躏,一種是線性可分,另一種是線性不可分降狠。
用兩個(gè)特征值舉例对竣,繪制到平面直角坐標(biāo)系空間中:
對(duì)于2維的線性可分空間,如何找到最合適的分界線呢榜配?
該分界線要滿足劃分特質(zhì)值的前提下否纬,距離兩邊臨界邊界點(diǎn)最遠(yuǎn)的線。這條線叫最大超平面蛋褥,臨界點(diǎn)叫支撐向量临燃。因?yàn)橥卣沟?維空間就是一個(gè)平面,拓展到N維空間就是一個(gè)超平面烙心。
如何利用數(shù)學(xué)知識(shí)找到這個(gè)最大超平面呢(此處忽略N個(gè)字膜廊,利用向量距離公式+拉格朗日定律),最終求得超平面的表達(dá)式為
wTx+b=0淫茵。
那么爪瓜,對(duì)于線性不可分的超平面該如何找呢?
用2維不可分舉例匙瘪,將2維線性不可分樣本映射到高維空間中铆铆,讓樣本點(diǎn)在高維空間線性可分蝶缀,然后該超平面映射回低維度的切線就是該線性不可分的超平面。
簡(jiǎn)易模型如下:
那么薄货,如果將低維空間映射到高維空間呢翁都,這里需要使用向量和內(nèi)積運(yùn)算。
eg:將3維空間向量映射到9維空間向量中
x=(x1,x2,x3) y=(y1,y2,y3) 菲驴,定義向量運(yùn)算f(x)=(x1x1,x1x2,x1x3,x2x1,x2x2,x3x3,x3x1,x3x2,x3x3)
x=(1,2,3) y=(4,5,6)
f(x)=(1,2,3,2,4,6,3,6,9) f(y)=(16,20,24,20,25,30,24,30,36)
內(nèi)積運(yùn)算<f(x),f(y)>=116+220+324+220+425+630+324+630+936=1024
這樣產(chǎn)生另一個(gè)問題荐吵,因?yàn)榈途S空間映射到高維空間后維度可能會(huì)很大骑冗,如果將全部樣本的點(diǎn)乘全部計(jì)算好赊瞬,這樣的計(jì)算量太大了。所以引入核函數(shù)K贼涩,簡(jiǎn)化向量計(jì)算復(fù)雜度的同時(shí)巧涧,似的結(jié)果偏差最小。
其中一種核函數(shù)定義為 K(x,y)=K(<x,y>)2
K(x,y)=(4+10+18)2=1024遥倦,結(jié)果和之前復(fù)雜計(jì)算量結(jié)果相同谤绳。
同樣的結(jié)果,使用Kernel計(jì)算量小很多袒哥。
以上缩筛,全是兩類分類問題,那么堡称,如果是多分類問題呢瞎抛,該如何解決?
對(duì)于每個(gè)類却紧,把其他類都當(dāng)成另外一種分類進(jìn)行二分類桐臊,轉(zhuǎn)化成二分類問題。
1.代碼實(shí)現(xiàn)
2維2類特征值3點(diǎn)利用SVM劃分超平面
from sklearn import svm
#定義3個(gè)2維坐標(biāo)點(diǎn)晓殊,并給定目標(biāo)值
x=[[2,0],[1,1],[2,3]]
y=[0,0,1]
#使用svm建立模型
clf=svm.SVC(kernel="linear")
clf.fit(x,y)
print(clf)
#打印支撐向量
print(clf.support_vectors_)
#打印支撐向量index
print(clf.support_)
#打印支撐向量數(shù)量
print(clf.n_support_)
#預(yù)測(cè)[2,0]的目標(biāo)值
pred=clf.predict([[2,0]])
print(pred)
2維2類特征值隨機(jī)20個(gè)點(diǎn)利用SVM劃分超平面
import numpy as np
from matplotlib import pylab as pl
from sklearn import svm
#隨機(jī)生成20具有正態(tài)分布的坐標(biāo)點(diǎn)集和固定目標(biāo)集
np.random.seed(0)
x=np.r_[np.random.randn(20,2)-[2,2],np.random.randn(20,2)+[2,2]]
y=[0]*20+[1]*20
print("x:",x)
print("y:",y)
#使用SVM訓(xùn)練模型
clf=svm.SVC(kernel="linear")
clf.fit(x,y)
#利用pylab繪制圖形
w=clf.coef_[0]
a=-w[0]/w[1]
xx=np.linspace(-5,5)
yy=a*xx-(clf.intercept_[0])/w[1]
b=clf.support_vectors_[0]
yy_down=a*xx+(b[1]-a*b[0])
b=clf.support_vectors_[-1]
yy_up=a*xx+(b[1]-a*b[0])
pl.plot(xx,yy,"k-")
pl.plot(xx,yy_down,"k--")
pl.plot(xx,yy_up,"k--")
pl.scatter(clf.support_vectors_[:,0],clf.support_vectors_[:,1],
s=80,facecolors="none")
pl.scatter(x[:,0],x[:,1],c=y,cmap=pl.cm.Paired)
pl.axis("tight")
pl.show()
非線性劃分SVM人臉識(shí)別
from __future__ import print_function
from time import time
import logging
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.model_selection import train_test_split
from sklearn.datasets import fetch_lfw_people
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV
#獲取人臉數(shù)據(jù)集
logging.basicConfig(level=logging.INFO,format="%(asctime)s%(message)s")
lfw_people=fetch_lfw_people(min_faces_per_person=70,resize=0.4)
#shape返回numpy數(shù)據(jù)的維度断凶,eg:3行2列->(3,2) shape[0]->3 shape[1]->2
n_samples,h,w=lfw_people.images.shape
x=lfw_people.data
n_features=x.shape[1]
y=lfw_people.target
target_names=lfw_people.target_names
n_classes=target_names.shape[0]
print("Total dataset size:")
print("n_samples:%d"%n_samples)
print("n_features:%d"%n_features)
print("n_classes:%d"%n_classes)
#拆分?jǐn)?shù)據(jù)集為訓(xùn)練集和測(cè)試集
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.25)
#使用PCA減少人臉訓(xùn)練數(shù)據(jù)集特征向量的維度[降低數(shù)據(jù)計(jì)算復(fù)雜度]
n_components=150
print("extracting the top %d eigenfaces from %d faces"%(n_components,x_train.shape[0]))
t0=time()
pca = PCA(n_components=n_components,svd_solver='randomized',whiten=True).fit(x_train)
print("done in %0.3fs"%(time()-t0))
eigenfaces=pca.components_.reshape((n_components,h,w))
t0=time()
x_train_pca=pca.transform(x_train)
x_test_pca=pca.transform(x_test)
print("done in %0.3fs"%(time()-t0))
#使用SVM建立模型
t0=time()
param_grid={"C":[1e3,5e3,1e4,5e4,1e5],
"gamma":[0.0001,0.0005,0.001,0.005,0.01,0.1],}
clf=GridSearchCV(SVC(kernel="rbf",class_weight="balanced"),param_grid)
clf=clf.fit(x_train_pca,y_train)
print("done in %0.3fs"%(time()-t0))
print(clf.best_estimator_)
#預(yù)測(cè)測(cè)試集,并使用matplotlib繪制圖形
t0=time()
y_pred=clf.predict(x_test_pca)
print("done in %0.3fs"%(time()-t0))
print(classification_report(y_test,y_pred,target_names=target_names))
print(confusion_matrix(y_test,y_pred,labels=range(n_classes)))
def plot_gallery(images,titles,h,w,n_row=3,n_col=4):
plt.figure(figsize=(1.8*n_col,2.4*n_row))
plt.subplots_adjust(bottom=0,left=.01,right=.99,top=.90,hspace=.35)
for i in range(n_row*n_col):
plt.subplot(n_row,n_col,i+1)
plt.imshow(images[i].reshape((h,w)),cmap=plt.cm.gray)
plt.title(titles[i],size=12)
plt.xticks(())
plt.yticks(())
def title(y_pred,y_test,target_names,i):
pred_name=target_names[y_pred[i]].rsplit(" ",1)[-1]
true_name=target_names[y_test[i]].rsplit(" ",1)[-1]
return 'predicted:%s\ntrue:%s'%(pred_name,true_name)
prediction_titles=[title(y_pred,y_test,target_names,i) for i in range(y_pred.shape[0])]
plot_gallery(x_test,prediction_titles,h,w)
eigenfaces_titles=["eigenface %d"%i for i in range(eigenfaces.shape[0])]
plot_gallery(eigenfaces,eigenfaces_titles,h,w)
plt.show()
神經(jīng)網(wǎng)絡(luò)
0.基本介紹
組成結(jié)構(gòu)
1巫俺、輸入層是有訓(xùn)練集的實(shí)例特征向量傳入
2认烁、經(jīng)過連接接點(diǎn)的權(quán)重(weight)傳入下一層,一層的輸出是下一層的輸入
3介汹、隱藏層的個(gè)數(shù)可以是任意的砚著,輸入層有一層捎琐,輸出層有一層
4簇爆、每個(gè)單元也可以稱之為神經(jīng)結(jié)點(diǎn)吴超,根據(jù)生物學(xué)來源定義
5出吹、以上成為兩層的神經(jīng)網(wǎng)絡(luò)愉耙,輸入層是不算在里面的
6名段、一層中加權(quán)求和炕舵,然后根據(jù)非線性方程轉(zhuǎn)化輸出
7拄查、作為多層向前神經(jīng)網(wǎng)絡(luò),理論上餐胀,如果有足夠的隱藏層哟楷,和足夠的訓(xùn)練集,可以模擬出任何方程
設(shè)計(jì)結(jié)構(gòu)
1否灾、使用神經(jīng)網(wǎng)絡(luò)訓(xùn)練數(shù)據(jù)之前卖擅,必須確定神經(jīng)網(wǎng)絡(luò)的層數(shù),以及每層單元的個(gè)數(shù)
2墨技、特征向量在被傳入輸入層時(shí)通常要先標(biāo)準(zhǔn)化到0-1之間(為了加速學(xué)習(xí)過程)
3惩阶、離散型變量可以被編碼成每一個(gè)輸入單元對(duì)應(yīng)一個(gè)特征值可能賦的值
比如:特征值A(chǔ)可能取三個(gè)值(a0, a1, a2), 可以使用3個(gè)輸入單元來代表A。
如果A=a0, 那么代表a0的單元值就取1, 其他取0扣汪;
如果A=a1, 那么代表a1的單元值就取1断楷,其他取0,以此類推
4崭别、神經(jīng)網(wǎng)絡(luò)即可以用來做分類問題冬筒,也可以解決回歸問題
(1)對(duì)于分類問題,如果是2類茅主,可以用一個(gè)輸出單元表示(0和1分別代表2類)舞痰,如果多余2類,則每一個(gè)類別用一個(gè)輸出單元表示
(2)沒有明確的規(guī)則來設(shè)計(jì)最好有多少個(gè)隱藏層诀姚,可以根據(jù)實(shí)驗(yàn)測(cè)試和誤差以及精準(zhǔn)度來實(shí)驗(yàn)并改進(jìn)
交叉驗(yàn)證
這里有一堆數(shù)據(jù)响牛,我們把他切成3個(gè)部分(當(dāng)然還可以分的更多)
第一部分做測(cè)試集,二三部分做訓(xùn)練集学搜,算出準(zhǔn)確度娃善;
第二部分做測(cè)試集,一三部分做訓(xùn)練集瑞佩,算出準(zhǔn)確度聚磺;
第三部分做測(cè)試集,一二部分做訓(xùn)練集炬丸,算出準(zhǔn)確度瘫寝;
之后算出三個(gè)準(zhǔn)確度的平局值,作為最后的準(zhǔn)確度稠炬,如下圖:
算法
他是通過迭代性來處理訓(xùn)練集中的實(shí)例焕阿,對(duì)比經(jīng)過神經(jīng)網(wǎng)絡(luò)后,輸人層預(yù)測(cè)值與真實(shí)值之間的誤差首启,再通過反向法(從輸出層=>隱藏層=>輸入層)以最小化誤差來更新每個(gè)連接的權(quán)重暮屡。
輸入:D(數(shù)據(jù)集),學(xué)習(xí)率(learning rate)毅桃,一個(gè)多層向前神經(jīng)網(wǎng)絡(luò)
輸出:一個(gè)訓(xùn)練好的神經(jīng)網(wǎng)絡(luò)(a trained neural network)
1.初始化權(quán)重和偏向:隨機(jī)初始化在-1到1之間褒纲,或者-0.5到0.5之間准夷,每個(gè)單元有一個(gè)偏向
2.開始對(duì)數(shù)據(jù)進(jìn)行訓(xùn)練,步驟如下:
a.由輸入層向前傳送
Ij:要對(duì)其進(jìn)行非線性轉(zhuǎn)化莺掠,為下一單元的值
Oi:是輸入的值
wij:為每個(gè)單元到下一個(gè)單元連線之間的權(quán)重
θj:偏向
對(duì)Ij進(jìn)行非線性轉(zhuǎn)化衫嵌,得到下一個(gè)單元的值
b.根據(jù)誤差(error)反向傳送
對(duì)于輸出層:
對(duì)于隱藏層:
Errj:用于更新偏向
Oj:為輸出的值
Tj:為標(biāo)簽的值
權(quán)重更新:
括號(hào)里為小l ,是學(xué)習(xí)率(learning rate)
c.終止條件
方法一:權(quán)重的更新低于某個(gè)閾值
方法二:預(yù)測(cè)的錯(cuò)誤率低于某個(gè)閾值
方法三:達(dá)到預(yù)設(shè)一定的循環(huán)次數(shù)
舉例:
w14…w56這些權(quán)重是初始化隨機(jī)生成的彻秆,同樣θ4到θ6也是隨機(jī)生成的
將x的值與每一項(xiàng)的權(quán)重相乘求和算出Ij楔绞,之后對(duì)Ij進(jìn)行非線性轉(zhuǎn)化,求出輸出值
之后算出結(jié)點(diǎn)上的誤差唇兑,并對(duì)其更新酒朵,在如此反復(fù)
1.代碼實(shí)現(xiàn)
根據(jù)算法描述,定義神經(jīng)網(wǎng)絡(luò)類:
import numpy as np
"""
定義兩種非線性方程和其導(dǎo)函數(shù)
把數(shù)據(jù)映射到[-1,1]范圍中
"""
def tanh(x):
return np.tanh(x)
def tanh_deriv(x):
return 1.0-np.tanh(x)*np.tanh(x)
def logistic(x):
return 1/(1+np.exp(-x))
def logistic_derivative(x):
return logistic(x)*(1-logistic(x))
"""
定義神經(jīng)網(wǎng)絡(luò)類
用來建立模型和預(yù)測(cè)數(shù)據(jù)
"""
class NN:
def __init__(self,layers,activation='tanh'):
if(activation=='logistic'):
self.activation=logistic
self.activation_deriv=logistic_derivative
elif (activation=='tanh'):
self.activation=tanh
self.activation_deriv=tanh_deriv
#隨機(jī)初始化權(quán)重weights
self.weights=[]
for i in range(1,len(layers)-1):
self.weights.append((2*np.random.random((layers[i-1]+1,layers[i]+1))-1)*0.25)
self.weights.append((2 * np.random.random((layers[i]+1,layers[i+1]))-1)*0.25)
def fit(self,x,y,learning_rate=0.2,epochs=10000):
x=np.atleast_2d(x)
temp=np.ones([x.shape[0],x.shape[1]+1])
temp[:,0:-1]=x
x=temp
y=np.array(y)
for k in range(epochs):
i=np.random.randint(x.shape[0])
a=[x[i]]
for l in range(len(self.weights)):
a.append(self.activation(np.dot(a[l],self.weights[l])))
error=y[i]-a[-1]
deltas=[error*self.activation_deriv(a[-1])]
for l in range(len(a)-2,0,-1):
deltas.append(deltas[-1].dot(self.weights[l].T)*self.activation_deriv(a[l]))
deltas.reverse()
for i in range(len(self.weights)):
layer=np.atleast_2d(a[i])
delta=np.atleast_2d(deltas[i])
self.weights[i]+=learning_rate*layer.T.dot(delta)
def predict(self,x):
x=np.array(x)
temp=np.ones(x.shape[0]+1)
temp[0:-1]=x
a=temp
for l in range(0,len(self.weights)):
a=self.activation(np.dot(a,self.weights[l]))
return a
使用該神經(jīng)網(wǎng)絡(luò)預(yù)測(cè)異或運(yùn)算:
from NerualNetWorks import NN
import numpy as np
"""
預(yù)測(cè)異或運(yùn)算 [0,0]->0 [0,1]->1 ...
"""
#[2,2,1]-輸入層2個(gè)單元幔亥,隱藏層-2個(gè)單元(自己指定)耻讽,輸出層2個(gè)單元
nn=NN([2,2,1],'tanh')
x=np.array([[0,0],[0,1],[1,0],[1,1]])
y=np.array([0,1,1,0])
nn.fit(x,y)
for i in [[0,0],[0,1],[1,0],[1,1]]:
print(i,nn.predict(i))
使用該神經(jīng)網(wǎng)絡(luò)預(yù)測(cè)手寫數(shù)字:
from sklearn.datasets import load_digits
from matplotlib import pylab as pl
"""
查看datasets中提供的數(shù)字圖片
"""
digits=load_digits()
print(digits.data.shape)
# pl.gray()
pl.matshow(digits.images[1])
pl.show()
import numpy as np
from sklearn.datasets import load_digits
from sklearn.metrics import confusion_matrix,classification_report
from NerualNetWorks import NN
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
digits=load_digits()
x=digits.data
y=digits.target
#數(shù)據(jù)處理成到(0察纯,1)范圍內(nèi)
x-=x.min()
x/=x.max()
#圖片為8x8數(shù)據(jù)源帕棉,設(shè)置100個(gè)單元的隱藏層,10個(gè)單元[0-9]輸出層
nn=NN([64,100,10],'logistic')
x_train,x_test,y_train,y_test=train_test_split(x,y)
labels_train=LabelBinarizer().fit_transform(y_train)
labels_test=LabelBinarizer().fit_transform(y_test)
nn.fit(x_train,labels_train,epochs=3000)
predictions=[]
for i in range(x_test.shape[0]):
o=nn.predict(x_test[i])
predictions.append(np.argmax(o))
print(confusion_matrix(y_test,predictions))
print(classification_report(y_test,predictions))
線性回歸
1.簡(jiǎn)單的線性回歸
0.原理解析
對(duì)于一個(gè)特征向量x和一個(gè)目標(biāo)值y的情況饼记。
目的是找一條直線方程y=b0+b1*x香伴,即根據(jù)數(shù)據(jù)x,y找到b0,b1的值。
對(duì)于一個(gè)假設(shè)的數(shù)據(jù)
那么具则,b0,b1要滿足什么條件呢即纲?
滿足 ∑(y實(shí)際值-y估算值)^2最小。直觀講就是最接近每一個(gè)點(diǎn)的直線方程博肋。
那么低斋,如何確定b0,b1的值呢?
【省略原理匪凡,直接給結(jié)論】
那么膊畴,根據(jù)公式,給出算法推導(dǎo)過程:
1.代碼實(shí)現(xiàn)[不使用sklearn包病游,自定義方法實(shí)現(xiàn)]
import numpy as np
#簡(jiǎn)單線性回歸的模型建立
def fitSLR(x,y):
n=len(x)
dinominator=0
numerator=0
for i in range(0,n):
numerator+=(x[i]-np.mean(x))*(y[i]-np.mean(y))
dinominator+=(x[i]-np.mean(x))**2
b1=numerator/float(dinominator)
b0=np.mean(y)/float(np.mean(x))
return b0,b1
#簡(jiǎn)單線性回歸的模型預(yù)測(cè)
def predict(x,b0,b1):
return b0+x*b1
x=[1,3,2,1,3]
y=[14,24,18,17,27]
b0,b1=fitSLR(x,y)
print("b0=",b0,"b1=",b1)
pred=predict(6,b0,b1)
print("pred=",pred)
2.簡(jiǎn)單的線性回歸[N個(gè)特征向量]
0.原理
同1個(gè)特征向量和1個(gè)目標(biāo)一樣唇跨。
目標(biāo)是尋找
滿足 ∑(y實(shí)際值-y估算值)^2最小。直觀講就是最接近每一個(gè)點(diǎn)的直線方程衬衬。
只不過目標(biāo)方程是:
y=b0+b1 * x1+b2 * x2+b3 * x3...买猖,即根據(jù)數(shù)據(jù)x1,x2,x3...,y找到b0,b1,b2,b3...的值。
基于以下數(shù)據(jù)滋尉,我們要預(yù)測(cè)外賣騎手送貨時(shí)間:
特別的玉控,如果自變量是分類數(shù)據(jù),需要進(jìn)行一步處理
處理完的csv文件
1.代碼實(shí)現(xiàn)[使用sklearn包]
from numpy import genfromtxt
import numpy as np
from sklearn import datasets,linear_model
#使用處理好的csv文件
dataPath="timedata.csv"
deliverData=genfromtxt(dataPath,delimiter=",")
print(deliverData)
#拆分為特征值和目標(biāo)值
x=deliverData[:,:-1]
y=deliverData[:,-1]
print("x=",x)
print("y=",y)
#使用sklearn中線性回歸類處理數(shù)據(jù)集
regr=linear_model.LinearRegression()
regr.fit(x,y)
print("regr=",regr.coef_,"intercept=",regr.intercept_)
#進(jìn)行預(yù)測(cè)
xPred=[[200,6,1,0,0]]
yPred=regr.predict(xPred)
print("yPred=",yPred)
3.非線性回歸[邏輯回歸]
0.原理分析
對(duì)于有一些目標(biāo)值是[0,1]的情況狮惜,使用線性回歸并不能完全契合該目標(biāo)值高诺。
比如既棺,根據(jù)腫瘤尺寸,預(yù)測(cè)是否患有癌癥懒叛。
如果建立線性回歸模型丸冕,預(yù)測(cè)目標(biāo)值很可能超出[0,1]范圍,且受到個(gè)別數(shù)據(jù)影響薛窥。
我們想出一個(gè)辦法胖烛,讓目標(biāo)值范圍落到[0,1],就引入了邏輯回歸诅迷。
那么如何讓預(yù)測(cè)的目標(biāo)值落到[0,1]中呢佩番?
我們引入sigmoid函數(shù):
把線性回歸預(yù)測(cè)模型y=wx+b代入其中,得到
那么罢杉,和線性回歸一樣趟畏,我們依然要找到(y實(shí)際值-y估算值)^2最小時(shí),參數(shù)w,b的值滩租。因?yàn)楹瘮?shù)并不是線性的赋秀,所以借用對(duì)數(shù)函數(shù),變形一下【省略原理】律想,用損失函數(shù)cost表示該預(yù)測(cè)值和目標(biāo)值差最小值猎莲。
這個(gè)式子中,m是樣本數(shù)技即,y是標(biāo)簽著洼,取值0或1,i表示第i個(gè)樣本而叼,f(x)表示預(yù)測(cè)的輸出身笤。
那么,如何求出該函數(shù)最小值呢葵陵?
這里引入梯度下降的概念液荸。
首先來看看梯度下降的一個(gè)直觀的解釋。比如我們?cè)谝蛔笊缴系哪程幬恢冒D眩捎谖覀儾恢涝趺聪律接ū祝谑菦Q定走一步算一步,也就是在每走到一個(gè)位置的時(shí)候涡尘,求解當(dāng)前位置的梯度忍弛,沿著梯度的負(fù)方向,也就是當(dāng)前最陡峭的位置向下走一步考抄,然后繼續(xù)求解當(dāng)前位置梯度细疚,向這一步所在位置沿著最陡峭最易下山的位置走一步。這樣一步步的走下去川梅,一直走到覺得我們已經(jīng)到了山腳疯兼。當(dāng)然這樣走下去然遏,有可能我們不能走到山腳,而是到了某一個(gè)局部的山峰低處吧彪。
大概思路就是待侵,在一個(gè)點(diǎn)按照一定區(qū)間[步長(zhǎng)/學(xué)習(xí)率],對(duì)函數(shù)求偏導(dǎo)姨裸,找到下降速率最快的方向秧倾,然后走一步,再不斷循環(huán)該步驟傀缩。每次走步的長(zhǎng)度逐漸減小那先,使得計(jì)算的結(jié)果更加精確。
那么赡艰,經(jīng)過梯度下降算法售淡,求出損失函數(shù)最小,以此推出模型中參數(shù)的值慷垮,代入新特征值進(jìn)行預(yù)測(cè)揖闸。
1.代碼實(shí)現(xiàn)
自定義梯度下降函數(shù)實(shí)現(xiàn)
import numpy as np
import random
#theta-模型訓(xùn)練參數(shù) alpha-學(xué)習(xí)率 m-數(shù)據(jù)個(gè)數(shù) numIterations-梯度下降次數(shù)
def gradientDescent(x,y,theta,alpha,m,numIterations):
xTrans=x.transpose()
for i in range(0,numIterations):
#利用點(diǎn)積進(jìn)行梯度下降算法實(shí)現(xiàn)
hypothesis=np.dot(x,theta)
loss=hypothesis-y
#定義簡(jiǎn)單線性回歸的損失函數(shù)
cost=np.sum(loss**2)/(2*m)
print("numIterations",i,"cost=",cost)
gradient=np.dot(xTrans,loss)/m
theta=theta-alpha*gradient
return theta
def genData(numPoints,bias,variance):
#初始化100行2列的100*[0,0]數(shù)據(jù)
x=np.zeros(shape=(numPoints,2))
#初始化100行1列的100*[0]數(shù)據(jù)
y=np.zeros(shape=numPoints)
for i in range(0,numPoints):
x[i][0]=1
x[i][1]=i
y[i]=(i+bias)+random.uniform(0,1)*variance
return x,y
#生成100行,偏差25换帜,隨機(jī)變量*10的隨機(jī)數(shù)據(jù)
x,y=genData(100,25,10)
print("x=",x)
print("y=",y)
m,n=np.shape(x)
print("m=",m,"n=",n)
numIterations=100
alpha=0.0005
theta=np.ones(n)
print("---",theta)
theta=gradientDescent(x,y,theta,alpha,m,numIterations)
print("***",theta)
4.回歸算法中相關(guān)性和R平方值
0.基礎(chǔ)概念
線性相關(guān)性:衡量?jī)蓚€(gè)數(shù)據(jù)相關(guān)性強(qiáng)度的量楔壤。
正相關(guān):>0 負(fù)相關(guān):<0 無相關(guān):=0
比如一組數(shù)據(jù):
X Y
1 10
3 12
8 24
7 21
9 34
28 101
經(jīng)過公式計(jì)算求出 correlation=0.94 正相關(guān)鹤啡。
R2值:范圍(0,1)惯驼,如果=80%,表示回歸關(guān)系可以解釋因變量80%的變異递瑰。
簡(jiǎn)單回歸中:R2=r*r
參數(shù)分別是:y估計(jì)值祟牲,y平均值,y真實(shí)值
5.總結(jié)
使用sklearn實(shí)現(xiàn)線性回歸和邏輯回歸
import numpy as np
from sklearn.linear_model import LinearRegression,SGDRegressor
from sklearn.linear_model import Ridge
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
def linear():
lbdata=load_boston()
xtrain, xtest, ytrain, ytest = train_test_split(lbdata.data, lbdata.target, test_size=0.25)
#特征值和目標(biāo)值都進(jìn)行標(biāo)準(zhǔn)化處理
#因?yàn)榫S度不同抖部,所以需要初始化兩個(gè)StandardScaler
std_x=StandardScaler()
xtrain=std_x.fit_transform(xtrain)
xtest=std_x.transform(xtest)
print(xtrain)
print(xtest)
std_y=StandardScaler()
ytrain=std_y.fit_transform(ytrain.reshape(-1,1))
ytest=std_y.transform(ytest.reshape(-1,1))
print(ytrain)
print(ytest)
"""
利用矩陣計(jì)算说贝,求得最符合的線性函數(shù)權(quán)重值
"""
#正規(guī)方程
lr=LinearRegression()
lr.fit(xtrain,ytrain)
print("回歸系數(shù):",lr.coef_)
y_predict=lr.predict(xtest)
print("預(yù)測(cè)標(biāo)準(zhǔn)化后價(jià)格:",y_predict)
print("預(yù)測(cè)價(jià)格:", std_y.inverse_transform(y_predict))
print("均方誤差",mean_squared_error(std_y.inverse_transform(ytest),std_y.inverse_transform(y_predict)))
"""
損失函數(shù)記錄偏差值,通過不斷學(xué)習(xí)減低偏差值優(yōu)化線性函數(shù)權(quán)重的方式
"""
#梯度下降
sgd=SGDRegressor()
sgd.fit(xtrain, ytrain)
print("回歸系數(shù):", sgd.coef_)
sgd_y_predict = sgd.predict(xtest)
print("預(yù)測(cè)標(biāo)準(zhǔn)化后價(jià)格:",sgd_y_predict)
print("預(yù)測(cè)價(jià)格:", std_y.inverse_transform(sgd_y_predict))
print("均方誤差", mean_squared_error(std_y.inverse_transform(ytest), std_y.inverse_transform(sgd_y_predict)))
"""
使用正則化方式優(yōu)化過擬合和欠擬合的問題
"""
#嶺回歸
rd = Ridge(alpha=1.0)
rd.fit(xtrain, ytrain)
print("回歸系數(shù):", rd.coef_)
rd_y_predict = rd.predict(xtest)
print("預(yù)測(cè)標(biāo)準(zhǔn)化后價(jià)格:", rd_y_predict)
print("預(yù)測(cè)價(jià)格:", std_y.inverse_transform(rd_y_predict))
print("均方誤差", mean_squared_error(std_y.inverse_transform(ytest), std_y.inverse_transform(rd_y_predict)))
個(gè)人理解:
根據(jù)訓(xùn)練數(shù)據(jù)的特征值和目標(biāo)值慎颗,以線性代數(shù)為基礎(chǔ)乡恕,進(jìn)行矩陣計(jì)算,推測(cè)線性函數(shù)參數(shù)俯萎。線性函數(shù):y=k1x1+k2x2+k3x3...+b傲宜。
邏輯回歸
目標(biāo)值是二分類數(shù)值(結(jié)果是是否的問題)
from sklearn.linear_model import LinearRegression,SGDRegressor,LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics.classification import classification_report
def logic():
"""
可以使用正則化優(yōu)化
"""
# 正規(guī)方程
lr = LogisticRegression()
lr.fit(xtrain, ytrain)
print("回歸系數(shù):",lr.coef_)
y_predict = lr.predict(xtest)
#因?yàn)槟繕?biāo)值是分類定值,所以可以使用準(zhǔn)確率和召回率表示結(jié)果
print("準(zhǔn)確率:",lr.score(xtest,ytest))
print("召回率:",classification_report(ytest,y_predict,target_names=lbdata.target_names))
個(gè)人理解:
以線性回歸算法為基礎(chǔ)夫啊,利用signomid函數(shù)做處理函卒,使得預(yù)測(cè)結(jié)果為二分類數(shù)值。
參考:https://blog.csdn.net/ustbbsy/article/details/80423294
保存估算模型和使用模型API
from sklearn.externals import joblib
lr=LinearRegression()
lr.fit(xtrain,ytrain)
#保存模型
joblib.dump(lr,"./linemodel.pkl")
#獲取模型
linemodel=joblib.load("./linemodel.pkl")
y_predict = linemodel.predict(xtest)
K-Means算法
0.基礎(chǔ)概念
非監(jiān)督算法撇眯,沒有明確的目標(biāo)值报嵌,把數(shù)據(jù)分為指定數(shù)目的類別虱咧。
算法接受參數(shù)K,然后將事先輸入的n個(gè)數(shù)據(jù)對(duì)象劃分為K個(gè)聚類以便使得所獲得的的聚類滿足同一聚類中的對(duì)象相似度最高锚国,而不同聚類中的對(duì)象相似度較小腕巡。
參考:https://www.cnblogs.com/bourneli/p/3645049.html
那么,如何做到呢血筑,算法思想是什么逸雹?
以空間中K個(gè)點(diǎn)為中心進(jìn)行聚類,對(duì)最靠近他們的對(duì)象歸類云挟。通過迭代的方法梆砸,逐次更新各聚類中心的值,直到得到最好的聚類結(jié)果园欣。
具體過程如下:
假定有4個(gè)二維特征數(shù)據(jù)帖世,表示在平面直角坐標(biāo)系上,使用K=2進(jìn)行聚合沸枯。
步驟一:初始化指定兩個(gè)中心點(diǎn)日矫,比如圖中紅色的點(diǎn),把其他所有點(diǎn)分別算出距離兩個(gè)中心點(diǎn)的距離绑榴,距離更近劃分在該中心點(diǎn)的聚合空間內(nèi)哪轿。【省略計(jì)算過程】翔怎,劃分之后的2個(gè)聚合空間中窃诉,第一個(gè)紅色點(diǎn)為一組,其他點(diǎn)為第二組赤套。
步驟二:利用點(diǎn)的均值飘痛,重新計(jì)算每一組聚合空間的中心點(diǎn),再次計(jì)算每個(gè)點(diǎn)到兩個(gè)新的中心點(diǎn)的距離容握,距離更近的劃分在該中心點(diǎn)所在聚合空間內(nèi)宣脉。調(diào)整之后,左邊兩個(gè)點(diǎn)聚合到左邊中心點(diǎn)區(qū)域剔氏,右邊兩個(gè)點(diǎn)聚合再右邊中心點(diǎn)區(qū)域塑猖。
步驟三:利用點(diǎn)的均值,再次重新計(jì)算每一組聚合空間的中心點(diǎn)谈跛,再次劃分聚合區(qū)域羊苟,得到結(jié)果和上一步一致,則停止算法币旧,得到最終結(jié)果践险。
1.代碼實(shí)現(xiàn)
import numpy as np
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
def kmeans():
#假定6個(gè)3特征數(shù)據(jù)
data=np.array([[15,23,35],[123,213,123],[12,321,321],[876,6,678],[93,56,37],[213,3,5]])
print(data.shape)
print(data)
#使用K-means聚合這6個(gè)數(shù)據(jù)為3類
km=KMeans(n_clusters=3)
km.fit(data)
predict=km.predict(data)
print(predict)
#使用輪廓系數(shù)評(píng)估該模型的準(zhǔn)確率[-1,1]
res=silhouette_score(data,predict)
print("聚類評(píng)估結(jié)果:",res)
個(gè)人理解:
給定一個(gè)沒有目標(biāo)值的特征數(shù)據(jù)集和分類數(shù)目K,從隨機(jī)K個(gè)中心點(diǎn)開始,利用距離和平均值公式巍虫,不斷優(yōu)化中心點(diǎn)位置彭则,直到耿更好的滿足輪廓系數(shù)評(píng)估的結(jié)果。
層次聚類算法
0.基礎(chǔ)介紹
假設(shè)有N個(gè)待聚類的樣本占遥,對(duì)于層次聚類來說俯抖,步驟:
a.(初始化)每個(gè)樣本歸為一類,計(jì)算每?jī)蓚€(gè)之間的距離瓦胎,也就是樣本與樣本之間的相似度芬萍。
b.尋找各個(gè)類之間最近的兩個(gè)類,把他們歸為一類【這樣總數(shù)就少了一個(gè)】
c.重新計(jì)算這個(gè)類和舊的各個(gè)類之間的相似度搔啊。
d.重復(fù)bc步驟直至所有樣本歸為一類柬祠,結(jié)束。
那么负芋,其中有一個(gè)細(xì)節(jié)是新類的【多點(diǎn)聚類】如何和其他點(diǎn)進(jìn)行距離計(jì)算漫蛔。
可以按照最近的點(diǎn)位置為基準(zhǔn),也可以按照最遠(yuǎn)的點(diǎn)的位置為基準(zhǔn)旧蛾,同樣可以按照平均中心點(diǎn)位置為基準(zhǔn)莽龟。不同基準(zhǔn),不同結(jié)果锨天。
和K-Means的區(qū)別在于毯盈,分層之后,可以按照任意分類數(shù)目進(jìn)行樹的切分病袄。
1.代碼實(shí)現(xiàn)
from sklearn import datasets
import numpy as np
import matplotlib.pyplot as plt
from sklearn import preprocessing
from sklearn.cluster import AgglomerativeClustering
from scipy.cluster.hierarchy import linkage,dendrogram
#導(dǎo)入數(shù)據(jù)集搂赋,進(jìn)行拆分,歸一化
iris = datasets.load_iris()
iris_data = iris.data
print(iris_data.shape)
print(iris_data)
data = np.array(iris_data[:50,1:-1])
print(data.shape)
min_max_scaler = preprocessing.MinMaxScaler()
data_M = min_max_scaler.fit_transform(data)
print(data_M)
#繪制樹狀圖
plt.figure(figsize=(20,6))
Z = linkage(data_M, method='ward', metric='euclidean')
p = dendrogram(Z, 0)
plt.show()
#使用分層聚類算法陪拘,進(jìn)行數(shù)據(jù)分類
ac = AgglomerativeClustering(n_clusters=5, affinity='euclidean', linkage='ward')
ac.fit(data_M)
labels = ac.fit_predict(data_M)
print(labels)
plt.scatter(data_M[:,0], data_M[:,1], c=labels)
plt.show()
七.深度學(xué)習(xí)
使用深度學(xué)習(xí)框架TensorFlow進(jìn)行
TensorFlow屬于計(jì)算密集型框架
涉及到大量數(shù)據(jù)計(jì)算屬于計(jì)算密集型(CPU/GPU密集)
涉及到多網(wǎng)絡(luò)厂镇,磁盤操作屬于I/O密集型
1.TensorFlow基本介紹
- Graph(圖)
【Tensor(TensorFlow中數(shù)據(jù)格式)+Operation(TensorFlow中函數(shù)統(tǒng)稱)】集合體 - Session(會(huì)話)
運(yùn)行圖的結(jié)構(gòu),掌握資源左刽,分配資源;默認(rèn)只能運(yùn)行一個(gè)圖(默認(rèn)圖)酌媒,使用run方法運(yùn)行圖的結(jié)構(gòu) - Tensor(張量)
TensorFlow中基本數(shù)據(jù)結(jié)構(gòu)欠痴,對(duì)numpy(ndarray)的封裝,包含【名字,形狀秒咨,數(shù)據(jù)類型】
import tensorflow as tf
"""使用TensorFlow進(jìn)行加法運(yùn)算"""
def add():
a=tf.constant(3)
b=tf.constant(5)
#a,b,sum均為Tensor類型數(shù)據(jù)
print("a:%s b:%s"%(a,b))
sum=tf.add(a,b)
print("sum:",sum)
#指定不定shape
plt=tf.placeholder(dtype=tf.float32,shape=[None,3])
"""
fetches-列表參數(shù)喇辽,指定獲取圖中哪些Tensor
feed_dict-字典參數(shù),結(jié)合placeholder使用
"""
with tf.Session() as session:
res=session.run(fetches=[a,sum,plt],feed_dict={plt:[[3,2,3],[1,2,3]]})
print(res)
print("a.shape:%s a.name:%s a.op:%s"%(a.shape,a.name,a.op))
print("plt.shape:%s plt.name:%s plt.op:%s"%(plt.shape, plt.name, plt.op))
"""圖"""
def graph():
#默認(rèn)圖
print("tf-default-graph:", tf.get_default_graph())
#創(chuàng)建圖,不創(chuàng)建圖雨席,默認(rèn)是在默認(rèn)圖中執(zhí)行tensor和operation
gr=tf.Graph()
with gr.as_default():
a = tf.constant(7)
b = tf.constant(10)
sum = tf.add(a, b)
#該Graph的Tensor都可以訪問到該圖
print("a.graph:",a.graph)
print("sum.graph:", sum.graph)
"""張量"""
def tensor():
#創(chuàng)建一個(gè)符合正態(tài)分布的隨機(jī)Tensor mean-均值 stddev-方差 shape-數(shù)據(jù)形狀
ts = tf.random_normal(mean=0.0, stddev=0.5, shape=[50, 3])
print(ts)
plt=tf.placeholder(dtype=tf.float32,shape=[None,3])
print(plt)
#對(duì)不定形狀可以使用set_shape設(shè)置具體shape
plt.set_shape([4,3])
print(plt)
#設(shè)置[4,3]之后不能再次設(shè)置
#plt.set_shape([5,3])
#print(plt)
#改變數(shù)據(jù)形狀,reshape()需要保證數(shù)據(jù)元素個(gè)數(shù)相同
plt_reshape=tf.reshape(plt,shape=[3,4])
print(plt_reshape)
#修改Tensor數(shù)據(jù)類型
plt=tf.cast(plt,dtype=tf.int32)
print(plt)
- 變量(tf.Variable)
def vari():
a=tf.constant(5)
#定義tensorflow變量
b=tf.Variable(tf.random_normal(shape=[3,2],mean=0.0,stddev=1.0,name="b"))
print("a:%s,b:%s"%(a,b))
#定義tf.Variables類型需要進(jìn)行初始化操作
variinit=tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(variinit)
res=sess.run(fetches=[a,b])
print(res)
"""可視化操作"""
#把圖寫入文件菩咨,運(yùn)行tensorboard命令可以通過瀏覽器直接訪問可視圖
tf.summary.FileWriter("./tmp/testgraph",graph=sess.graph)
2.TensorFlow線性回歸
import tensorflow as tf
import os
"""
模擬線性回歸
tf.matmul()-矩陣相乘
tf.square()-平方計(jì)算
eval()-獲取Tensor中具體數(shù)值
with tf.variable_scope()-變量作用域(優(yōu)化graph顯示)
tf.summary-graph可視化圖形統(tǒng)計(jì)類
tf.train.Saver-模型保存/恢復(fù)類
"""
def linner():
with tf.variable_scope("data"):
#1.假定一條y=3x+5.2b的線性回歸函數(shù),并準(zhǔn)備數(shù)據(jù)
x=tf.random_normal(shape=[100,1],mean=0.0,stddev=1.0,name="x")
y_true=tf.matmul(x,[[3.0]])+5.2
with tf.variable_scope("model"):
#2.定義權(quán)重值w和偏移量b(需要定義為變量才能不斷訓(xùn)練) trainable-True 可訓(xùn)練,不斷變化
weight=tf.Variable(tf.random_normal(shape=[1,1],mean=0.0,stddev=1.0,name="w"))
b=tf.Variable(0.0,name="b")
y_predict=tf.matmul(x,weight)+b
with tf.variable_scope("loss"):
#3.計(jì)算損失值
loss=tf.reduce_mean(tf.square(y_true-y_predict))
with tf.variable_scope("gradientOptimizer"):
#4.利用梯度下降獲取訓(xùn)練op learning_rate-學(xué)習(xí)率抽米,太大導(dǎo)致梯度爆炸特占,太小導(dǎo)致學(xué)習(xí)次數(shù)激增才能更更好預(yù)測(cè)
train_op=tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(loss)
#5.初始化全局變量
init_op=tf.global_variables_initializer()
#6.統(tǒng)計(jì)損失值和權(quán)重值 scalar()-統(tǒng)計(jì)Tensor histogram()-統(tǒng)計(jì)變量值
tf.summary.scalar("loss",loss)
tf.summary.histogram("weight",weight)
mergeall=tf.summary.merge_all()
with tf.Session() as sess:
sess.run(init_op)
#讀取模型
if os.path.exists("./tmp/model"):
print("存在該模型")
tf.train.Saver().restore(sess,"./tmp/model/linnermodel")
print("init weight:%s b:%s"%(weight.eval(),b.eval()))
fileWriter = tf.summary.FileWriter("./tmp/linnergraph", graph=sess.graph)
#7.進(jìn)行100次訓(xùn)練并記錄統(tǒng)計(jì)信息到graph中
for i in range(100):
sess.run(train_op)
summary=sess.run(mergeall)
fileWriter.add_summary(summary,i)
print("train %d weight:%s b:%s" % (i,weight.eval(), b.eval()))
#保存模型
tf.train.Saver().save(sess,"./tmp/model/linnermodel")
3.TensorFlow文本,圖片云茸,二進(jìn)制文件子線程讀取處理
import tensorflow as tf
import os
"""
實(shí)現(xiàn)一個(gè)簡(jiǎn)單的隊(duì)列出入操作
"""
def testQueue():
# 創(chuàng)建隊(duì)列
q=tf.FIFOQueue(capacity=3,dtypes=tf.float32)
# 初始化隊(duì)列op
en_q_many=q.enqueue_many([[1,2,3],])
# +1入隊(duì)列op(en_q依賴性是目,執(zhí)行op會(huì)自動(dòng)執(zhí)行取出+1兩步操作)
de_q=q.dequeue()
data=de_q+1
en_q=q.enqueue(data)
with tf.Session() as sess:
#執(zhí)行初始化op
sess.run(en_q_many)
#執(zhí)行入隊(duì)列op
for i in range(100):
sess.run(en_q)
#執(zhí)行出隊(duì)列op
for i in range(q.size().eval()):
print(sess.run(q.dequeue()))
"""
模擬子線程入隊(duì)列,主線程出隊(duì)列操作
"""
def testQueueRunner():
# 創(chuàng)建隊(duì)列
q = tf.FIFOQueue(capacity=1000, dtypes=tf.float32)
# 創(chuàng)建自增隊(duì)列op
var = tf.Variable(0.0)
data = tf.assign_add(var,tf.constant(1.0))
en_q = q.enqueue(data)
qr = tf.train.QueueRunner(queue=q,enqueue_ops=[en_q]*2)
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init_op)
coord=tf.train.Coordinator()
threads=qr.create_threads(sess,coord=coord,start=True)
for i in range(300):
print(i,sess.run(q.dequeue()))
coord.request_stop()
coord.join(threads)
"""
子線程讀取CSV文件标捺,主線程處理
"""
def testReadCSV():
filedir = os.listdir("./csv/")
filelist = [os.path.join("./csv/", file) for file in filedir]
# 1.構(gòu)建數(shù)據(jù)目錄列表
filequeue = tf.train.input_producer(filelist)
# 2.構(gòu)建閱讀器讀取數(shù)據(jù)
reader = tf.TextLineReader()
key, value = reader.read(filequeue)
# 指定每一個(gè)樣本的每一列的類型,默認(rèn)值
record_defaults = [["name1"], ["name2"]]
# 3.指定編碼格式
text1, text2 = tf.decode_csv(value, record_defaults=record_defaults)
# 4.批處理文件數(shù)據(jù) batch-size-批處理大小(決定每次取數(shù)據(jù)容量) num-threads-開啟線程數(shù)(決定取幾次) capacity-隊(duì)列容量
text1s, text2s = tf.train.batch(tensors=[text1, text2], batch_size=10, num_threads=3, capacity=6)
with tf.Session() as sess:
coord = tf.train.Coordinator()
# 開啟子線程讀取數(shù)據(jù)
thread = tf.train.start_queue_runners(sess=sess, coord=coord)
print(sess.run(fetches=[text1s, text2s]))
coord.request_stop()
coord.join(thread)
"""
子線程讀取JPEG圖片文件懊纳,主線程處理
"""
def testReadImage():
filedir=os.listdir("./tmp/imagedata/")
filelist=[os.path.join("./tmp/imagedata/",file) for file in filedir]
#1.構(gòu)建數(shù)據(jù)目錄列表
filequeue=tf.train.input_producer(filelist)
#2.構(gòu)建閱讀器讀取數(shù)據(jù)
reader=tf.WholeFileReader()
key,value=reader.read(filequeue)
#3.指定編碼格式
image=tf.image.decode_jpeg(value)
resize_image=tf.image.resize_images(images=image,size=[200,200])
#如果進(jìn)行批處理,需要指定形狀
resize_image.set_shape(shape=[200,200,3])
print(resize_image)
#4.批處理文件數(shù)據(jù) batch-size-批處理大小 num-threads-開啟線程數(shù) capacity-隊(duì)列容量
image_batch=tf.train.batch(tensors=[resize_image],batch_size=10,num_threads=2,capacity=6)
with tf.Session() as sess:
coord=tf.train.Coordinator()
#開啟子線程讀取數(shù)據(jù)
thread=tf.train.start_queue_runners(sess=sess,coord=coord)
print(sess.run(fetches=[image_batch]))
coord.request_stop()
coord.join(thread)
"""
子線程讀取二進(jìn)制文件亡容,主線程處理
"""
def readbin():
height=32
width=32
channels=3
lablebytes=1
imagebytes=height*width*channels
lable_imagebytes=imagebytes+lablebytes
filedir=os.listdir("./tmp/bindata/")
filelist=[os.path.join("./tmp/bindata/",file) for file in filedir]
#1.構(gòu)建數(shù)據(jù)目錄列表
filequeue=tf.train.input_producer(filelist)
#2.構(gòu)建閱讀器讀取數(shù)據(jù)
reader=tf.FixedLengthRecordReader(lable_imagebytes)
key,value=reader.read(filequeue)
#3.指定編碼格式
lable_image=tf.decode_raw(value,tf.uint8)
lable=tf.slice(lable_image,[0],[lablebytes])
image=tf.slice(lable_image,[lablebytes],[imagebytes])
image_reshape=tf.reshape(tensor=image,shape=[height,width,channels])
#4.批處理文件數(shù)據(jù) batch-size-批處理大小 num-threads-開啟線程數(shù) capacity-隊(duì)列容量
image_batch,lable_batch=tf.train.batch(tensors=[image_reshape,lable],batch_size=10,num_threads=2,capacity=6)
with tf.Session() as sess:
coord=tf.train.Coordinator()
#開啟子線程讀取數(shù)據(jù)
thread=tf.train.start_queue_runners(sess=sess,coord=coord)
print(sess.run(fetches=[image_batch,lable_batch]))
#存儲(chǔ)為TFRecord
writetorecord(image_batch,lable_batch)
coord.request_stop()
coord.join(thread)
"tfrecords快速讀取數(shù)據(jù)類型"
def writetorecord(image_batch,lable_batch):
# 建立TFRecordWriter存儲(chǔ)器
writer = tf.python_io.TFRecordWriter(path="./tmp/tfrecorddata/tfrecord")
# 循環(huán)寫入文件嗤疯,構(gòu)造example協(xié)議(包含eval()必須在session中執(zhí)行)
print("開始存儲(chǔ)")
for i in range(10):
image = image_batch[i].eval().tostring()
lable = int(lable_batch[i].eval()[0])
example = tf.train.Example(features=tf.train.Features(feature={
"image": tf.train.Feature(bytes_list=tf.train.BytesList(value=[image])),
"lable": tf.train.Feature(int64_list=tf.train.Int64List(value=[lable])),
}))
writer.write(example.SerializeToString())
writer.close()
print("存儲(chǔ)完成")
def readrecord():
filedir = os.listdir("./tmp/tfrecorddata/")
filelist = [os.path.join("./tmp/tfrecorddata/", file) for file in filedir]
filequeue=tf.train.input_producer(filelist)
reader=tf.TFRecordReader()
key,value=reader.read(filequeue)
features=tf.parse_single_example(value,features={
"image":tf.FixedLenFeature([],tf.string),
"lable":tf.FixedLenFeature([],tf.int64),
})
image=tf.decode_raw(bytes=features["image"],out_type=tf.uint8)
image_reshape=tf.reshape(image,shape=[32,32,3])
lable=tf.cast(features["lable"],tf.int32)
image_batch, lable_batch = tf.train.batch(tensors=[image_reshape,lable], batch_size=10, num_threads=2, capacity=6)
return image_batch,lable_batch
def testTFRecord():
# 從TFRecord中讀取
image_batch, lable_batch = readrecord()
with tf.Session() as sess:
print(sess.run(fetches=[image_batch,lable_batch]))
4.簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò)模型
感知機(jī)模型
感知機(jī)模型是為了解決多分類問題。
通過多個(gè)特征值x1,x2..建立超平面函數(shù)w1x1+w2x2+....+b闺兢,把目標(biāo)值進(jìn)行softmax分類
感知機(jī)-神經(jīng)元(單個(gè)感知機(jī))-神經(jīng)網(wǎng)絡(luò)(多神經(jīng)元)
神經(jīng)網(wǎng)絡(luò)
N個(gè)特征值->M個(gè)目標(biāo)值(輸出)
全連接狀態(tài)的權(quán)重?cái)?shù)就是NM身弊,偏置數(shù)是M,對(duì)輸出的M個(gè)目標(biāo)值進(jìn)行softmax取概率列敲,概率大的就是預(yù)測(cè)的結(jié)果阱佛。
[None,N]->[None,M]就是一個(gè)矩陣相乘的結(jié)果 [None,N][N,M]=[None,M]
eg: 3個(gè)特征值 3個(gè)預(yù)測(cè)目標(biāo)值 真實(shí)目標(biāo)值
x1 ---w1/w1'---> Y1(3) 0.3 [0
x2 ---w2/w2'---> (對(duì)2個(gè)隱層)---> Y2(4) ---softmax--> 0.4 -交叉熵計(jì)算損失--> 1
x3 ---w3/w3'---> Y3(3) 0.3 0]
...
對(duì)比
算法 策略 優(yōu)化
線性回歸 均方誤差 梯度下降
邏輯回歸 對(duì)數(shù)似然損失 梯度下降
神經(jīng)網(wǎng)絡(luò) 交叉熵?fù)p失 梯度下降
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
"""使用神經(jīng)網(wǎng)絡(luò)進(jìn)行數(shù)字圖片的預(yù)測(cè)"""
def mnist(is_train):
# 0.準(zhǔn)備數(shù)據(jù)
mnistdata=input_data.read_data_sets("~/Desktop/PythonTest/TestTF/data/mnist/input_data/",one_hot=True)
# 1.建立占位符數(shù)據(jù) x[None,784] y_true[None,10]
with tf.variable_scope("data"):
x=tf.placeholder(dtype=tf.float32,shape=[None,784])
y_true=tf.placeholder(dtype=tf.float32,shape=[None,10])
# 2.建立全連接神經(jīng)網(wǎng)絡(luò) w[784,10] b[10]
with tf.variable_scope("model"):
# 隨機(jī)初始化權(quán)重和偏置
weight=tf.Variable(tf.random_normal(shape=[784,10],mean=0.0,stddev=1.0),name="weight")
bias=tf.Variable(tf.constant(0.0,shape=[10]))
# 預(yù)測(cè)None個(gè)樣本的輸出結(jié)果 [None,784]*[784,10]+[10]=[None,10]
y_predict=tf.matmul(x,weight)+bias
# 3.求出所有樣本的損失,求平均值
with tf.variable_scope("soft_cross"):
# 求平均交叉熵?fù)p失
loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true,logits=y_predict))
# 4.梯度下降求出損失
with tf.variable_scope("optimizer"):
train_op=tf.train.GradientDescentOptimizer(0.1).minimize(loss)
# 5.計(jì)算準(zhǔn)確率
with tf.variable_scope("accuracy"):
# None個(gè)樣本[1,0,0,1,1,1,1,0...1,0]
#argmax函數(shù):返回的是輸入列表中最大值的位置
equal_list=tf.equal(tf.argmax(y_true,1),tf.argmax(y_predict,1))
# 求出1的占有率即準(zhǔn)確率
accuarcy=tf.reduce_mean(tf.cast(equal_list,tf.float32))
saver=tf.train.Saver()
init_op=tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init_op)
if is_train==True:
for i in range(2000):
mnist_x,mnist_y=mnistdata.train.next_batch(50)
sess.run(train_op,feed_dict={x:mnist_x,y_true:mnist_y})
print("訓(xùn)練第%d步戴而,準(zhǔn)確率:%f"%(i,sess.run(accuarcy,feed_dict={x:mnist_x,y_true:mnist_y})))
# 保存模型
saver.save(sess=sess,save_path="./tmp/mnist_model")
else:
# 預(yù)測(cè)
saver=saver.restore(sess=sess,save_path="./tmp/mnist_model")
for i in range(100):
x_test,y_test=mnistdata.test.next_batch(1)
print("第%d張圖片凑术,目標(biāo)是%d,預(yù)測(cè)結(jié)果是%d"
%(i,
tf.argmax(y_test,1).eval(),
tf.argmax(sess.run(y_predict,feed_dict={x:x_test,y_true:y_test}),1).eval()
))
5.卷積神經(jīng)網(wǎng)絡(luò)模型
卷積神經(jīng)網(wǎng)絡(luò)模型就是在神經(jīng)網(wǎng)絡(luò)模型中加入卷積層所意。
卷積層進(jìn)行特征提取淮逊,去掉不重要的樣本,減少參數(shù)數(shù)量扶踊。
第一步進(jìn)行過濾器Filter的選擇泄鹏,相當(dāng)于用N個(gè)帶權(quán)重偏置一個(gè)小窗口去看數(shù)據(jù),然后移動(dòng)一定的步長(zhǎng)秧耗,把所有的數(shù)據(jù)都看一遍备籽。
eg:
1 4 5 7
2 4 3 8 --->用1個(gè)22Filter,step=2觀察 -> (第一個(gè)點(diǎn):10.1+0.44+20.3+4*0.2)--> 3.1 5.8
6 2 3 5 0.1,0.4 2.9 4.1
3 3 6 0 0.3,0.2
假如step=3,那么面臨觀察不全或者觀察越界的問題分井,那么就需要填充層Padding->
0 0 0 0 0 0
0 1 4 5 7 0
0 2 4 3 8 0
0 6 2 3 5 0
0 3 3 6 0 0
0 0 0 0 0 0
計(jì)算公式:
H2=(H1-F+2P)/S+1 H1-源數(shù)據(jù)高车猬,F(xiàn)-FilterH,P-Padding S-Step步長(zhǎng)
W2=(W1-F+2P)/S+1 W1-源數(shù)據(jù)寬尺锚,F(xiàn)-FilterW珠闰,P-Padding S-Step步長(zhǎng)
指定Padding="SAME" 那么H1=H2。
第二步進(jìn)行激活函數(shù)過濾(eg:relu)瘫辩。
第三步進(jìn)行池化層伏嗜,真正減少數(shù)據(jù)量坛悉。
eg:Filter 2*2 step=1
3.1 5.8 --->(3.1+5.8+2.9+4.1) 15.9
2.9 4.1
第四步進(jìn)行全連接層,預(yù)測(cè)目標(biāo)值承绸。
def cnn_mnist(is_train):
# 0.準(zhǔn)備數(shù)據(jù)
mnistdata = input_data.read_data_sets("~/Desktop/PythonTest/TestTF/data/mnist/input_data/", one_hot=True)
# 1.建立占位符數(shù)據(jù) x[None,784] y_true[None,10]
with tf.variable_scope("data"):
x = tf.placeholder(dtype=tf.float32, shape=[None, 784])
y_true = tf.placeholder(dtype=tf.float32, shape=[None, 10])
# 2.第一層卷積層 卷積 32個(gè)Filter=5*5*32,strides(步長(zhǎng))=1,padding="SAME"
with tf.variable_scope("cnn1"):
# a.修改原數(shù)據(jù)結(jié)構(gòu) [None,28,28,1]
x_reshape = tf.reshape(x, [-1, 28, 28, 1])
# b.隨機(jī)初始化權(quán)重和偏置
w_cnn1 = tf.Variable(tf.random_normal(shape=[5,5,1,32], mean=0.0, stddev=1.0))
b_cnn1 = tf.Variable(tf.constant(0.0, shape=[32]))
# c.卷積+relu激活
x_relu1=tf.nn.relu(tf.nn.conv2d(x_reshape,w_cnn1,strides=[1,1,1,1],padding="SAME")+b_cnn1)
# d.池化 2*2,strides=2,padding="SAME" [None,28,28,32]->[None,14,14,32]
x_pool1=tf.nn.max_pool(x_relu1,ksize=[1,2,2,1],strides=[1,2,2,1],padding="SAME")
# 3.第二層卷積層 卷積 64個(gè)Filter=5*5*64,strides(步長(zhǎng))=1,padding="SAME"
with tf.variable_scope("cnn2"):
# 原第一層卷積后數(shù)據(jù)結(jié)構(gòu) [None,14,14,32]
# a.隨機(jī)初始化權(quán)重和偏置
w_cnn2 = tf.Variable(tf.random_normal(shape=[5,5,32,64], mean=0.0, stddev=1.0))
b_cnn2 = tf.Variable(tf.constant(0.0, shape=[64]))
# b.卷積+relu激活
x_relu2 = tf.nn.relu(tf.nn.conv2d(x_pool1, w_cnn2, strides=[1, 1, 1, 1], padding="SAME") + b_cnn2)
# c.池化 2*2,strides=2,padding="SAME" [None,14,14,64]->[None,7,7,64]
x_pool2 = tf.nn.max_pool(x_relu2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")
# 4.全連接層 [None,7,7,64]=[None,7*7*64]*[7*7*64,10]+[10]->[None,10]
with tf.variable_scope("connect"):
# 隨機(jī)初始化權(quán)重和偏置
weight = tf.Variable(tf.random_normal(shape=[7*7*64,10], mean=0.0, stddev=1.0), name="weight")
bias = tf.Variable(tf.constant(0.0, shape=[10]))
# 修改shape
x_cnn_reshape=tf.reshape(x_pool2,[-1,7*7*64])
y_predict = tf.matmul(x_cnn_reshape, weight) + bias
# 5.求出所有樣本的損失裸影,求平均值
with tf.variable_scope("soft_cross"):
# 求平均交叉熵?fù)p失
loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true,logits=y_predict))
# 6.梯度下降求出損失
with tf.variable_scope("optimizer"):
train_op=tf.train.GradientDescentOptimizer(0.0001).minimize(loss)
# 7.計(jì)算準(zhǔn)確率
with tf.variable_scope("accuracy"):
# None個(gè)樣本[1,0,0,1,1,1,1,0...1,0]
#argmax函數(shù):返回的是輸入列表中最大值的位置
equal_list=tf.equal(tf.argmax(y_true,1),tf.argmax(y_predict,1))
# 求出1的占有率即準(zhǔn)確率
accuarcy=tf.reduce_mean(tf.cast(equal_list,tf.float32))
saver=tf.train.Saver()
init_op=tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init_op)
if is_train==True:
for i in range(1000):
mnist_x,mnist_y=mnistdata.train.next_batch(50)
sess.run(train_op,feed_dict={x:mnist_x,y_true:mnist_y})
print("訓(xùn)練第%d步,準(zhǔn)確率:%f"%(i,sess.run(accuarcy,feed_dict={x:mnist_x,y_true:mnist_y})))
# 保存模型
saver.save(sess=sess,save_path="./tmp/cnn_mnist_model")
else:
# 預(yù)測(cè)
saver=saver.restore(sess=sess,save_path="./tmp/cnn_mnist_model")
for i in range(100):
x_test,y_test=mnistdata.test.next_batch(1)
print("第%d張圖片八酒,目標(biāo)是%d空民,預(yù)測(cè)結(jié)果是%d"
%(i,
tf.argmax(y_test,1).eval(),
tf.argmax(sess.run(y_predict,feed_dict={x:x_test,y_true:y_test}),1).eval()
))
識(shí)別驗(yàn)證碼過程分析
先來分析一下mnist識(shí)別數(shù)據(jù)的過程:
特征值:源數(shù)據(jù)圖片格式[None,28,28,1] ,為了進(jìn)行矩陣計(jì)算展成二維數(shù)據(jù)[None,28281]=[None,784]羞迷。
目標(biāo)值:需要one-hot編碼界轩。 [None,10](eg:用[0,0,1,0,0,0,0,0,0,0]表示 3)
全連接過程:[None,784]*[784,10]+[10]=[None,10]
w: [784,10]
b: [10]那么識(shí)別4位純字母驗(yàn)證碼的數(shù)據(jù)過程:
特征值:源數(shù)據(jù)圖片格式[None,20,80,3] ,為了進(jìn)行矩陣計(jì)算展成二維數(shù)據(jù)[None,20803]=[None,4800]衔瓮。
目標(biāo)值:需要one-hot編碼浊猾。 [None,426](eg:用[[0,0,1,0,0,0,0,0,0,0....][0,0...1,0..],[0,0...1,0..],[0,0...1,0..]]表示 CNPQ)
全連接過程:[None,4800][4800,104]+[104]=[None,104]
w: [4800,104]
b: [104]