python訓練的模型做預測:
創新互聯公司是一家專業提供藤縣企業網站建設,專注與成都網站制作、網站設計、H5場景定制、小程序制作等業務。10年已為藤縣眾多企業、政府機構等服務。創新互聯專業網站建設公司優惠進行中。
如下:
1、 先要按照scikit-learn包,先安裝下面三個依賴包:
Python (= 2.6 or = 3.3),
NumPy (= 1.6.1),
SciPy (= 0.9).
然后在cmd命令行中輸入:
pip install -U scikit-learn
擴展資料
應用
系統編程:提供API(Application Programming Interface應用程序編程接口),能方便進行系統維護和管理,Linux下標志性語言之一,是很多系統管理員理想的編程工具。
圖形處理:有PIL、Tkinter等圖形庫支持,能方便進行圖形處理。
數學處理:NumPy擴展提供大量與許多標準數學庫的接口。
文本處理:python提供的re模塊能支持正則表達式,還提供SGML,XML分析模塊,許多程序員利用python進行XML程序的開發。
數據庫編程:程序員可通過遵循Python DB-API(數據庫應用程序編程接口)規范的模塊與Microsoft SQL Server,Oracle,Sybase,DB2,MySQL、SQLite等數據庫通信。python自帶有一個Gadfly模塊,提供了一個完整的SQL環境。
網絡編程:提供豐富的模塊支持sockets編程,能方便快速地開發分布式應用程序。很多大規模軟件開發計劃例如Zope,Mnet 及BitTorrent. Google都在廣泛地使用它。
Web編程:應用的開發語言,支持最新的XML技術。
參考資料來源:百度百科-計算機程序設計語言
建議你用面向對象的方式去畫圖,一個圖作為一個對象,這樣每次調用一個對象的保存圖片方法就可以只保存當前圖片。
你這種用法第三張圖會有三個子圖是因為三個子圖都畫在同一個對象上。
為了將面向對象的繪圖庫包裝成只使用函數的調用接口,pyplot模塊的內部保存了當前圖表以及當前子圖等信息。當前的圖表和子圖可以使用gcf()和gca()獲得,它們分別是“Get?Current?Figure”和“Get?Current?Axis”的開頭字母縮寫。gcf()獲得的是表示圖表的Figure對象,而gca()則獲得的是表示子圖的Axes對象。下面我們在IPython中運行上節的“matplotlib_simple_plot.py”程序,然后調用gcf()和gca()查看當前的Figure和Axes對象。
給你個例子
import?numpy?as?np
import?matplotlib.pyplot?as?plt
plt.figure(1)?#?創建圖表1
plt.figure(2)?#?創建圖表2
ax1?=?plt.subplot(211)?#?在圖表2中創建子圖1
ax2?=?plt.subplot(212)?#?在圖表2中創建子圖2
x?=?np.linspace(0,?3,?100)
for?i?in?xrange(5):
plt.figure(1)????#?選擇圖表1
plt.plot(x,?np.exp(i*x/3))
plt.sca(ax1)?????#?選擇圖表2的子圖1
plt.plot(x,?np.sin(i*x))
plt.sca(ax2)??#?選擇圖表2的子圖2
plt.plot(x,?np.cos(i*x))
plt.show()
preface:做著最近的任務,對數據處理,做些簡單的提特征,用機器學習算法跑下程序得出結果,看看哪些特征的組合較好,這一系列流程必然要用到很多函數,故將自己常用函數記錄上。應該說這些函數基本上都會用到,像是數據預處理,處理完了后特征提取、降維、訓練預測、通過混淆矩陣看分類效果,得出報告。
1.輸入
從數據集開始,提取特征轉化為有標簽的數據集,轉為向量。拆分成訓練集和測試集,這里不多講,在上一篇博客中談到用StratifiedKFold()函數即可。在訓練集中有data和target開始。
2.處理
[python]?view plain?copy
def?my_preprocessing(train_data):
from?sklearn?import?preprocessing
X_normalized?=?preprocessing.normalize(train_data?,norm?=?"l2",axis=0)#使用l2范式,對特征列進行正則
return?X_normalized
def?my_feature_selection(data,?target):
from?sklearn.feature_selection?import?SelectKBest
from?sklearn.feature_selection?import?chi2
data_new?=?SelectKBest(chi2,?k=?50).fit_transform(data,target)
return?data_new
def?my_PCA(data):#data?without?target,?just?train?data,?withou?train?target.
from?sklearn?import?decomposition
pca_sklearn?=?decomposition.PCA()
pca_sklearn.fit(data)
main_var?=?pca_sklearn.explained_variance_
print?sum(main_var)*0.9
import?matplotlib.pyplot?as?plt
n?=?15
plt.plot(main_var[:n])
plt.show()
def?clf_train(data,target):
from?sklearn?import?svm
#from?sklearn.linear_model?import?LogisticRegression
clf?=?svm.SVC(C=100,kernel="rbf",gamma=0.001)
clf.fit(data,target)
#clf_LR?=?LogisticRegression()
#clf_LR.fit(x_train,?y_train)
#y_pred_LR?=?clf_LR.predict(x_test)
return?clf
def?my_confusion_matrix(y_true,?y_pred):
from?sklearn.metrics?import?confusion_matrix
labels?=?list(set(y_true))
conf_mat?=?confusion_matrix(y_true,?y_pred,?labels?=?labels)
print?"confusion_matrix(left?labels:?y_true,?up?labels:?y_pred):"
print?"labels\t",
for?i?in?range(len(labels)):
print?labels[i],"\t",
for?i?in?range(len(conf_mat)):
print?i,"\t",
for?j?in?range(len(conf_mat[i])):
print?conf_mat[i][j],'\t',
def?my_classification_report(y_true,?y_pred):
from?sklearn.metrics?import?classification_report
print?"classification_report(left:?labels):"
print?classification_report(y_true,?y_pred)
my_preprocess()函數:
主要使用sklearn的preprocessing函數中的normalize()函數,默認參數為l2范式,對特征列進行正則處理。即每一個樣例,處理標簽,每行的平方和為1.
my_feature_selection()函數:
使用sklearn的feature_selection函數中SelectKBest()函數和chi2()函數,若是用詞袋提取了很多維的稀疏特征,有必要使用卡方選取前k個有效的特征。
my_PCA()函數:
主要用來觀察前多少個特征是主要特征,并且畫圖。看看前多少個特征占據主要部分。
clf_train()函數:
可用多種機器學習算法,如SVM, LR, RF, GBDT等等很多,其中像SVM需要調參數的,有專門調試參數的函數如StratifiedKFold()(見前幾篇博客)。以達到最優。
my_confusion_matrix()函數:
主要是針對預測出來的結果,和原來的結果對比,算出混淆矩陣,不必自己計算。其對每個類別的混淆矩陣都計算出來了,并且labels參數默認是排序了的。
my_classification_report()函數:
主要通過sklearn.metrics函數中的classification_report()函數,針對每個類別給出詳細的準確率、召回率和F-值這三個參數和宏平均值,用來評價算法好壞。另外ROC曲線的話,需要是對二分類才可以。多類別似乎不行。
主要參考sklearn官網
ID3算法介紹
ID3算法全稱為迭代二叉樹3代算法(Iterative Dichotomiser 3)
該算法要先進行特征選擇,再生成決策樹,其中特征選擇是基于“信息增益”最大的原則進行的。
但由于決策樹完全基于訓練集生成的,有可能對訓練集過于“依賴”,即產生過擬合現象。因此在生成決策樹后,需要對決策樹進行剪枝。剪枝有兩種形式,分別為前剪枝(Pre-Pruning)和后剪枝(Post-Pruning),一般采用后剪枝。
信息熵、條件熵和信息增益
信息熵:來自于香農定理,表示信息集合所含信息的平均不確定性。信息熵越大,表示不確定性越大,所含的信息量也就越大。
設x 1 , x 2 , x 3 , . . . x n {x_1, x_2, x_3, ...x_n}x
1
,x
2
,x
3
,...x
n
為信息集合X的n個取值,則x i x_ix
i
的概率:
P ( X = i ) = p i , i = 1 , 2 , 3 , . . . , n P(X=i) = p_i, i=1,2,3,...,n
P(X=i)=p
i
,i=1,2,3,...,n
信息集合X的信息熵為:
H ( X ) = ? ∑ i = 1 n p i log ? p i H(X) =- \sum_{i=1}^{n}{p_i}\log{p_i}
H(X)=?
i=1
∑
n
p
i
logp
i
條件熵:指已知某個隨機變量的情況下,信息集合的信息熵。
設信息集合X中有y 1 , y 2 , y 3 , . . . y m {y_1, y_2, y_3, ...y_m}y
1
,y
2
,y
3
,...y
m
組成的隨機變量集合Y,則隨機變量(X,Y)的聯合概率分布為
P ( x = i , y = j ) = p i j P(x=i,y=j) = p_{ij}
P(x=i,y=j)=p
ij
條件熵:
H ( X ∣ Y ) = ∑ j = 1 m p ( y j ) H ( X ∣ y j ) H(X|Y) = \sum_{j=1}^m{p(y_j)H(X|y_j)}
H(X∣Y)=
j=1
∑
m
p(y
j
)H(X∣y
j
)
由
H ( X ∣ y j ) = ? ∑ j = 1 m p ( y j ) ∑ i = 1 n p ( x i ∣ y j ) log ? p ( x i ∣ y j ) H(X|y_j) = - \sum_{j=1}^m{p(y_j)}\sum_{i=1}^n{p(x_i|y_j)}\log{p(x_i|y_j)}
H(X∣y
j
)=?
j=1
∑
m
p(y
j
)
i=1
∑
n
p(x
i
∣y
j
)logp(x
i
∣y
j
)
和貝葉斯公式:
p ( x i y j ) = p ( x i ∣ y j ) p ( y j ) p(x_iy_j) = p(x_i|y_j)p(y_j)
p(x
i
y
j
)=p(x
i
∣y
j
)p(y
j
)
可以化簡條件熵的計算公式為:
H ( X ∣ Y ) = ∑ j = 1 m ∑ i = 1 n p ( x i , y j ) log ? p ( x i ) p ( x i , y j ) H(X|Y) = \sum_{j=1}^m \sum_{i=1}^n{p(x_i, y_j)\log\frac{p(x_i)}{p(x_i, y_j)}}
H(X∣Y)=
j=1
∑
m
i=1
∑
n
p(x
i
,y
j
)log
p(x
i
,y
j
)
p(x
i
)
信息增益:信息熵-條件熵,用于衡量在知道已知隨機變量后,信息不確定性減小越大。
d ( X , Y ) = H ( X ) ? H ( X ∣ Y ) d(X,Y) = H(X) - H(X|Y)
d(X,Y)=H(X)?H(X∣Y)
python代碼實現
import numpy as np
import math
def calShannonEnt(dataSet):
""" 計算信息熵 """
labelCountDict = {}
for d in dataSet:
label = d[-1]
if label not in labelCountDict.keys():
labelCountDict[label] = 1
else:
labelCountDict[label] += 1
entropy = 0.0
for l, c in labelCountDict.items():
p = 1.0 * c / len(dataSet)
entropy -= p * math.log(p, 2)
return entropy
def filterSubDataSet(dataSet, colIndex, value):
"""返回colIndex特征列label等于value,并且過濾掉改特征列的數據集"""
subDataSetList = []
for r in dataSet:
if r[colIndex] == value:
newR = r[:colIndex]
newR = np.append(newR, (r[colIndex + 1:]))
subDataSetList.append(newR)
return np.array(subDataSetList)
def chooseFeature(dataSet):
""" 通過計算信息增益選擇最合適的特征"""
featureNum = dataSet.shape[1] - 1
entropy = calShannonEnt(dataSet)
bestInfoGain = 0.0
bestFeatureIndex = -1
for i in range(featureNum):
uniqueValues = np.unique(dataSet[:, i])
condition_entropy = 0.0
for v in uniqueValues: #計算條件熵
subDataSet = filterSubDataSet(dataSet, i, v)
p = 1.0 * len(subDataSet) / len(dataSet)
condition_entropy += p * calShannonEnt(subDataSet)
infoGain = entropy - condition_entropy #計算信息增益
if infoGain = bestInfoGain: #選擇最大信息增益
bestInfoGain = infoGain
bestFeatureIndex = i
return bestFeatureIndex
def creatDecisionTree(dataSet, featNames):
""" 通過訓練集生成決策樹 """
featureName = featNames[:] # 拷貝featNames,此處不能直接用賦值操作,否則新變量會指向舊變量的地址
classList = list(dataSet[:, -1])
if len(set(classList)) == 1: # 只有一個類別
return classList[0]
if dataSet.shape[1] == 1: #當所有特征屬性都利用完仍然無法判斷樣本屬于哪一類,此時歸為該數據集中數量最多的那一類
return max(set(classList), key=classList.count)
bestFeatureIndex = chooseFeature(dataSet) #選擇特征
bestFeatureName = featNames[bestFeatureIndex]
del featureName[bestFeatureIndex] #移除已選特征列
decisionTree = {bestFeatureName: {}}
featureValueUnique = sorted(set(dataSet[:, bestFeatureIndex])) #已選特征列所包含的類別, 通過遞歸生成決策樹
for v in featureValueUnique:
copyFeatureName = featureName[:]
subDataSet = filterSubDataSet(dataSet, bestFeatureIndex, v)
decisionTree[bestFeatureName][v] = creatDecisionTree(subDataSet, copyFeatureName)
return decisionTree
def classify(decisionTree, featnames, featList):
""" 使用訓練所得的決策樹進行分類 """
classLabel = None
root = decisionTree.keys()[0]
firstGenDict = decisionTree[root]
featIndex = featnames.index(root)
for k in firstGenDict.keys():
if featList[featIndex] == k:
if isinstance(firstGenDict[k], dict): #若子節點仍是樹,則遞歸查找
classLabel = classify(firstGenDict[k], featnames, featList)
else:
classLabel = firstGenDict[k]
return classLabel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
下面用鳶尾花數據集對該算法進行測試。由于ID3算法只能用于標稱型數據,因此用在對連續型的數值數據上時,還需要對數據進行離散化,離散化的方法稍后說明,此處為了簡化,先使用每一種特征所有連續性數值的中值作為分界點,小于中值的標記為1,大于中值的標記為0。訓練1000次,統計準確率均值。
from sklearn import datasets
from sklearn.model_selection import train_test_split
iris = datasets.load_iris()
data = np.c_[iris.data, iris.target]
scoreL = []
for i in range(1000): #對該過程進行10000次
trainData, testData = train_test_split(data) #區分測試集和訓練集
featNames = iris.feature_names[:]
for i in range(trainData.shape[1] - 1): #對訓練集每個特征,以中值為分界點進行離散化
splitPoint = np.mean(trainData[:, i])
featNames[i] = featNames[i]+'='+'{:.3f}'.format(splitPoint)
trainData[:, i] = [1 if x = splitPoint else 0 for x in trainData[:, i]]
testData[:, i] = [1 if x = splitPoint else 0 for x in testData[:, i]]
decisionTree = creatDecisionTree(trainData, featNames)
classifyLable = [classify(decisionTree, featNames, td) for td in testData]
scoreL.append(1.0 * sum(classifyLable == testData[:, -1]) / len(classifyLable))
print 'score: ', np.mean(scoreL)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
輸出結果為:score: 0.7335,即準確率有73%。每次訓練和預測的準確率分布如下:
數據離散化
然而,在上例中對特征值離散化的劃分點實際上過于“野蠻”,此處介紹一種通過信息增益最大的標準來對數據進行離散化。原理很簡單,當信息增益最大時,說明用該點劃分能最大程度降低數據集的不確定性。
具體步驟如下:
對每個特征所包含的數值型特征值排序
對相鄰兩個特征值取均值,這些均值就是待選的劃分點
用每一個待選點把該特征的特征值劃分成兩類,小于該特征點置為1, 大于該特征點置為0,計算此時的條件熵,并計算出信息增益
選擇信息使信息增益最大的劃分點進行特征離散化
實現代碼如下:
def filterRawData(dataSet, colIndex, value, tag):
""" 用于把每個特征的連續值按照區分點分成兩類,加入tag參數,可用于標記篩選的是哪一部分數據"""
filterDataList = []
for r in dataSet:
if (tag and r[colIndex] = value) or ((not tag) and r[colIndex] value):
newR = r[:colIndex]
newR = np.append(newR, (r[colIndex + 1:]))
filterDataList.append(newR)
return np.array(filterDataList)
def dataDiscretization(dataSet, featName):
""" 對數據每個特征的數值型特征值進行離散化 """
featureNum = dataSet.shape[1] - 1
entropy = calShannonEnt(dataSet)
for featIndex in range(featureNum): #對于每一個特征
uniqueValues = sorted(np.unique(dataSet[:, featIndex]))
meanPoint = []
for i in range(len(uniqueValues) - 1): # 求出相鄰兩個值的平均值
meanPoint.append(float(uniqueValues[i+1] + uniqueValues[i]) / 2.0)
bestInfoGain = 0.0
bestMeanPoint = -1
for mp in meanPoint: #對于每個劃分點
subEntropy = 0.0 #計算該劃分點的信息熵
for tag in range(2): #分別劃分為兩類
subDataSet = filterRawData(dataSet, featIndex, mp, tag)
p = 1.0 * len(subDataSet) / len(dataSet)
subEntropy += p * calShannonEnt(subDataSet)
## 計算信息增益
infoGain = entropy - subEntropy
## 選擇最大信息增益
if infoGain = bestInfoGain:
bestInfoGain = infoGain
bestMeanPoint = mp
featName[featIndex] = featName[featIndex] + "=" + "{:.3f}".format(bestMeanPoint)
dataSet[:, featIndex] = [1 if x = bestMeanPoint else 0 for x in dataSet[:, featIndex]]
return dataSet, featName
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
重新對數據進行離散化,并重復該步驟1000次,同時用sklearn中的DecisionTreeClassifier對相同數據進行分類,分別統計平均準確率。運行代碼如下:
from sklearn.tree import DecisionTreeClassifier
import matplotlib.pyplot as plt
scoreL = []
scoreL_sk = []
for i in range(1000): #對該過程進行1000次
featNames = iris.feature_names[:]
trainData, testData = train_test_split(data) #區分測試集和訓練集
trainData_tmp = copy.copy(trainData)
testData_tmp = copy.copy(testData)
discritizationData, discritizationFeatName= dataDiscretization(trainData, featNames) #根據信息增益離散化
for i in range(testData.shape[1]-1): #根據測試集的區分點離散化訓練集
splitPoint = float(discritizationFeatName[i].split('=')[-1])
testData[:, i] = [1 if x=splitPoint else 0 for x in testData[:, i]]
decisionTree = creatDecisionTree(trainData, featNames)
classifyLable = [classify(decisionTree, featNames, td) for td in testData]
scoreL.append(1.0 * sum(classifyLable == testData[:, -1]) / len(classifyLable))
clf = DecisionTreeClassifier('entropy')
clf.fit(trainData[:, :-1], trainData[:, -1])
clf.predict(testData[:, :-1])
scoreL_sk.append(clf.score(testData[:, :-1], testData[:, -1]))
print 'score: ', np.mean(scoreL)
print 'score-sk: ', np.mean(scoreL_sk)
fig = plt.figure(figsize=(10, 4))
plt.subplot(1,2,1)
pd.Series(scoreL).hist(grid=False, bins=10)
plt.subplot(1,2,2)
pd.Series(scoreL_sk).hist(grid=False, bins=10)
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
兩者準確率分別為:
score: 0.7037894736842105
score-sk: 0.7044736842105263
準確率分布如下:
兩者的結果非常一樣。
(但是。。為什么根據信息熵離散化得到的準確率比直接用均值離散化的準確率還要低啊??哇的哭出聲。。)
最后一次決策樹圖形如下:
決策樹剪枝
由于決策樹是完全依照訓練集生成的,有可能會有過擬合現象,因此一般會對生成的決策樹進行剪枝。常用的是通過決策樹損失函數剪枝,決策樹損失函數表示為:
C a ( T ) = ∑ t = 1 T N t H t ( T ) + α ∣ T ∣ C_a(T) = \sum_{t=1}^TN_tH_t(T) +\alpha|T|
C
a
(T)=
t=1
∑
T
N
t
H
t
(T)+α∣T∣
其中,H t ( T ) H_t(T)H
t
(T)表示葉子節點t的熵值,T表示決策樹的深度。前項∑ t = 1 T N t H t ( T ) \sum_{t=1}^TN_tH_t(T)∑
t=1
T
N
t
H
t
(T)是決策樹的經驗損失函數當隨著T的增加,該節點被不停的劃分的時候,熵值可以達到最小,然而T的增加會使后項的值增大。決策樹損失函數要做的就是在兩者之間進行平衡,使得該值最小。
對于決策樹損失函數的理解,如何理解決策樹的損失函數? - 陶輕松的回答 - 知乎這個回答寫得挺好,可以按照答主的思路理解一下
C4.5算法
ID3算法通過信息增益來進行特征選擇會有一個比較明顯的缺點:即在選擇的過程中該算法會優先選擇類別較多的屬性(這些屬性的不確定性小,條件熵小,因此信息增益會大),另外,ID3算法無法解決當每個特征屬性中每個分類都只有一個樣本的情況(此時每個屬性的條件熵都為0)。
C4.5算法ID3算法的改進,它不是依據信息增益進行特征選擇,而是依據信息增益率,它添加了特征分裂信息作為懲罰項。定義分裂信息:
S p l i t I n f o ( X , Y ) = ? ∑ i n ∣ X i ∣ ∣ X ∣ log ? ∣ X i ∣ ∣ X ∣ SplitInfo(X, Y) =-\sum_i^n\frac{|X_i|}{|X|}\log\frac{|X_i|}{|X|}
SplitInfo(X,Y)=?
i
∑
n
∣X∣
∣X
i
∣
log
∣X∣
∣X
i
∣
則信息增益率為:
G a i n R a t i o ( X , Y ) = d ( X , Y ) S p l i t I n f o ( X , Y ) GainRatio(X,Y)=\frac{d(X,Y)}{SplitInfo(X, Y)}
GainRatio(X,Y)=
SplitInfo(X,Y)
d(X,Y)
關于ID3和C4.5算法
在學習分類回歸決策樹算法時,看了不少的資料和博客。關于這兩個算法,ID3算法是最早的分類算法,這個算法剛出生的時候其實帶有很多缺陷:
無法處理連續性特征數據
特征選取會傾向于分類較多的特征
沒有解決過擬合的問題
沒有解決缺失值的問題
即該算法出生時是沒有帶有連續特征離散化、剪枝等步驟的。C4.5作為ID3的改進版本彌補列ID3算法不少的缺陷:
通過信息最大增益的標準離散化連續的特征數據
在選擇特征是標準從“最大信息增益”改為“最大信息增益率”
通過加入正則項系數對決策樹進行剪枝
對缺失值的處理體現在兩個方面:特征選擇和生成決策樹。初始條件下對每個樣本的權重置為1。
特征選擇:在選取最優特征時,計算出每個特征的信息增益后,需要乘以一個**“非缺失值樣本權重占總樣本權重的比例”**作為系數來對比每個特征信息增益的大小
生成決策樹:在生成決策樹時,對于缺失的樣本我們按照一定比例把它歸屬到每個特征值中,比例為該特征每一個特征值占非缺失數據的比重
關于C4.5和CART回歸樹
作為ID3的改進版本,C4.5克服了許多缺陷,但是它自身還是存在不少問題:
C4.5的熵運算中涉及了對數運算,在數據量大的時候效率非常低。
C4.5的剪枝過于簡單
C4.5只能用于分類運算不能用于回歸
當特征有多個特征值是C4.5生成多叉樹會使樹的深度加深
————————————————
版權聲明:本文為CSDN博主「Sarah Huang」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:
我在學習時也遇到了同樣的問題,我是這樣解決的clf.fit(list(xy_normalized), labels)
主要原因是Python2和Python3中對zip函數做了一些修改,Python2中的zip函數返回的是一個list,而Python3的zip函數返回的是一個對象。
我目前也在學習Python+ML,大家可以共同學習,共同探討。
先是獲取驗證碼樣本。。。我存了大概500個。
用dia測了測每個字之間的間距,直接用PIL開始切。
from PIL import Image
for j in range(0,500):
f=Image.open("../test{}.jpg".format(j))
for i in range(0,4):
f.crop((20+20*i,0,40+20*i,40)).save("test{0}-{1}.jpg".format(j,i+1))
上面一段腳本的意思是把jpg切成四個小塊然后保存
之后就是二值化啦。
def TotallyShit(im):
x,y=im.size
mmltilist=list()
for i in range(x):
for j in range(y):
if im.getpixel((i,j))200:
mmltilist.append(1)
else:
mmltilist.append(0)
return mmltilist
咳咳,不要在意函數的名字。上面的一段代碼的意思是遍歷圖片的每個像素點,顏色數值小于200的用1表示,其他的用0表示。
其中的im代表的是Image.open()類型。
切好的圖片長這樣的。
只能說這樣切的圖片還是很粗糙,很僵硬。
下面就是分類啦。
把0-9,“+”,”-“的圖片挑好并放在不同的文件夾里面,這里就是純體力活了。
再之后就是模型建立了。
這里我試了自己寫的還有sklearn svm和sklearn neural_network。發現最后一個的識別正確率高的多。不知道是不是我樣本問題QAQ。
下面是模型建立的代碼
from sklearn.neural_network import MLPClassifier
import numpy as np
def clf():
clf=MLPClassifier()
mmltilist=list()
X=list()
for i in range(0,12):
for j in os.listdir("douplings/douplings-{}".format(i)):
mmltilist.append(TotallyShit(Image.open("douplings/douplings-{0}/{1}".format(i,j)).convert("L")))
X.append(i)
clf.fit(mmltilist,X)
return clf
大概的意思是從圖片源中讀取圖片和label然后放到模型中去跑吧。
之后便是圖像匹配啦。
def get_captcha(self):
with open("test.jpg","wb") as f:
f.write(self.session.get(self.live_captcha_url).content)
gim=Image.open("test.jpg").convert("L")
recognize_list=list()
for i in range(0,4):
part=TotallyShit(gim.crop((20+20*i,0,40+20*i,40)))
np_part_array=np.array(part).reshape(1,-1)
predict_num=int(self.clf.predict(np_part_array)[0])
if predict_num==11:
recognize_list.append("+")
elif predict_num==10:
recognize_list.append("-")
else:
recognize_list.append(str(predict_num))
return ''.join(recognize_list)
最后eval一下識別出來的字符串就得出結果了。。
順便提一句現在的bilibili登陸改成rsa加密了,麻蛋,以前的腳本全部作廢,心好痛。
登陸的代碼。
import time
import requests
import rsa
r=requests.session()
data=r.get("act=getkey_="+str(int(time.time()*1000))).json()
pub_key=rsa.PublicKey.load_pkcs1_openssl_pem(data['key'])
payload = {
'keep': 1,
'captcha': '',
'userid': "youruserid",
'pwd': b64encode(rsa.encrypt((data['hash'] +"yourpassword").encode(), pub_key)).decode(),
}
r.post("",data=payload)
分享文章:pythonclf函數,python clf
網頁路徑:http://vcdvsql.cn/article14/hsppge.html
成都網站建設公司_創新互聯,為您提供搜索引擎優化、網站策劃、移動網站建設、全網營銷推廣、品牌網站設計、品牌網站制作
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯