第五章案例代碼總結與修改分析
【有問題或錯誤,請私信我将及時改正;借鑒文章标明出處,謝謝】
每個案例代碼全部為書中源代碼,出現錯誤按照每個案例下面給出的代碼錯誤,原因,及怎樣修改進行修改即可解決每個案例錯誤
5-1
import pandas as pd
filename = 'F:/大二下合集/Python資料分析與挖掘/bankloan.xls'
data = pd.read_excel(filename)
x = data.iloc[:,:8].as_matrix()
y = data.iloc[:,8].as_matrix()
from sklearn.linear_model import LogisticRegression as LR
from sklearn.linear_model import RandomizedLogisticRegression as RLR
rlr = RLR() #建立随機邏輯回歸模型,篩選變量
rlr.fit(x, y) #訓練模型
rlr.get_support() #擷取特征篩選結果,也可以通過.scores_方法擷取各個特征的分數
print(u'通過随機邏輯回歸模型篩選特征結束。')
print(u'有效特征為:%s' % ','.join(data.columns[rlr.get_support(8)]))
x = data[data.columns[rlr.get_support()]].as_matrix() #篩選好特征
lr = LR() #建立邏輯回歸模型
lr.fit(x, y) #用篩選後的特征資料來訓練模型
print(u'邏輯回歸模型訓練結束。')
print(u'模型的平均正确率為:%s' % lr.score(x, y)) #給出模型的平均正确率,本例為81.4%
報錯1:
AttributeError: 'DataFrame' object has no attribute 'as_matrix'
報錯原因:屬性錯誤:“DataFrame”對象沒有屬性“reshape”
解決方法:“DataFrame”對象沒有,但是DataFrame.values有該方法
将.as_matrix()改為.values
第一次改為了.values() 出錯:
TypeError: 'numpy.ndarray' object is not callable
報錯原因:.values,它是dataframe類對象的一個屬性,不是方法
第二次改為.values沒報錯了
報錯2:
ImportError: cannot import name 'RandomizedLogisticRegression'
問題語句:
from sklearn.linear_model import RandomizedLogisticRegression
查找原因:
一個部落格中寫道了這個問題RandomizedLogisticRegression ImportError解決辦法
查得sklearn(版本0.21.3)的linear_model檔案夾下面已經沒有randomized_l1.py檔案,而RandomizedLogisticRegression就在該檔案内。RandomizedLogisticRegression已經被移出sklearn包,移到了 scikit-learn-contrib/stability-selection中,提取的stability-selection安裝過程(後兩步需要cd到對應檔案的路徑下面運作):
git clone https://github.com/scikit-learn-contrib/stability-selection.git
pip install -r requirements.txt
python setup.py install
在執行第三個指令有報錯:
error: [WinError 32] 另一個程式正在使用此檔案,程序無法通路。: 'd:\\python\\miniconda3_py3.6_x64_jb51\\lib\\site-packages\\stability_selection-0.0.1-py3.6.egg'
這個問題找到你的這個目錄下的這個檔案“tability_selection-0.0.1-py3.6.egg”發現他是一個壓縮包,把他解壓後删除這個壓縮包,一般解壓後就沒有字尾了即檔案名字就是:“tability_selection-0.0.1-py3.6”給他修改名字最後添加上”.egg”,再次運作沒有錯誤了
安裝後運作将剛報錯的代碼改為下面代碼:
from stability_selection.randomized_lasso import RandomizedLogisticRegression
沒有報錯,import正常。
确實按照這個部落格寫完沒報錯出現了第三個問題
報錯3:
AttributeError: 'RandomizedLogisticRegression' object has no attribute 'get_support'
解決問題到了這裡我開始了迷茫,經過幾天的百度與版本更替實驗還是未能成功解決。那麼換個思路,想把例子整體了解吃透,之後慢慢了解了這個各個版本不管是sklearn或是panda、tensorflow等等,它們在更新之後做了什麼改動,那麼再回過頭來看這個例子錯誤就容易解決了。是以5-1這個例子暫時沒有得到解決,等我解決會進行添加解決的步驟。
5-2
#-*- coding: utf-8 -*-
import pandas as pd
inputfile = 'F:/大二下合集/Python資料分析與挖掘/sales_data.xls'
data = pd.read_excel(inputfile, index_col=u'序号')
data[data == u'好'] = 1
data[data == u'是'] = 1
data[data == u'高'] = 1
data[data != 1] = -1
x = data.iloc[:, :3].as_matrix().astype(int)
y = data.iloc[:, 3].as_matrix().astype(int)
from sklearn.tree import DecisionTreeClassifier as DTC
dtc = DTC(criterion='entropy')
dtc.fit(x, y)
from sklearn.tree import export_graphviz
from sklearn.externals.six import StringIO
with open("tree.dot", 'w') as f:
f = export_graphviz(dtc, feature_names=x.columns, out_file=f)
代碼報錯:

第一個錯誤原因:
x = data.iloc[:, :3].as_matrix().astype(int)
y = data.iloc[:, 3].as_matrix().astype(int)
修改為:
x = data.iloc[:, :3].values.astype(int)
y = data.iloc[:, 3].values.astype(int)
第二個錯誤原因:
f = export_graphviz(dtc, feature_names=x.columns, out_file=f)
修改為:
應該在with open(“tree.dot”, ‘w’) as f:這行之前添加下面這句
x = pd.DataFrame(x)
在目錄下會有tree.dot文本檔案
我們需要下載下傳Graphviz(跨平台的、基于指令行的繪圖工具),然後在指令行進行編譯
5-3
#-*- coding: utf-8 -*-
#使用神經網絡算法預測銷量高低
import pandas as pd
#參數初始化
inputfile = 'F:/大二下合集/Python資料分析與挖掘/sales_data.xls'
data = pd.read_excel(inputfile, index_col = u'序号') #導入資料
#資料是類别标簽,要将它轉換為資料
#用1來表示“好”、“是”、“高”這三個屬性,用0來表示“壞”、“否”、“低”
data[data == u'好'] = 1
data[data == u'是'] = 1
data[data == u'高'] = 1
data[data != 1] = 0
x = data.iloc[:,:3].as_matrix().astype(int)
y = data.iloc[:,3].as_matrix().astype(int)
from keras.models import Sequential
from keras.layers.core import Dense, Activation
model = Sequential() #建立模型
model.add(Dense(input_dim = 3, output_dim = 10))
model.add(Activation('relu')) #用relu函數作為激活函數,能夠大幅提供準确度
model.add(Dense(input_dim = 10, output_dim = 1))
model.add(Activation('sigmoid')) #由于是0-1輸出,用sigmoid函數作為激活函數
model.compile(loss = 'binary_crossentropy', optimizer = 'adam', class_mode = 'binary')
#編譯模型。由于我們做的是二進制分類,是以我們指定損失函數為binary_crossentropy,以及模式為binary
#另外常見的損失函數還有mean_squared_error、categorical_crossentropy等,請閱讀幫助檔案。
#求解方法我們指定用adam,還有sgd、rmsprop等可選
model.fit(x, y, nb_epoch = 1000, batch_size = 10) #訓練模型,學習一千次
yp = model.predict_classes(x).reshape(len(y)) #分類預測
from cm_plot import * #導入自行編寫的混淆矩陣可視化函數
cm_plot(y,yp).show() #顯示混淆矩陣可視化結果
代碼錯誤:
原因:
model.compile(loss = 'binary_crossentropy', optimizer = 'adam', class_mode = 'binary')
解決:
删除這行中的參數class_mode=“binary”
即:
model.compile(loss = 'binary_crossentropy', optimizer = 'adam')
之後還有一個錯誤這裡的錯誤圖沒了,聽我口述即可,他會報錯找不到cm_plot
原因:
cm_plot是個自定義函數,你還沒有這個函數
解決:
添加自定義cm_plot函數,函數内容如下:
#-*- coding: utf-8 -*-
def cm_plot(y, yp):
from sklearn.metrics import confusion_matrix #導入混淆矩陣函數
cm = confusion_matrix(y, yp) #混淆矩陣
import matplotlib.pyplot as plt #導入作圖庫
plt.matshow(cm, cmap=plt.cm.Greens) #畫混淆矩陣圖,配色風格使用cm.Greens,更多風格請參考官網。
plt.colorbar() #顔色标簽
for x in range(len(cm)): #資料标簽
for y in range(len(cm)):
plt.annotate(cm[x,y], xy=(x, y), horizontalalignment='center', verticalalignment='center')
plt.ylabel('True label') #坐标軸标簽
plt.xlabel('Predicted label') #坐标軸标簽
return plt
将自定義好的函數放入到你python環境下site-packages中,如下圖
5-4
#-*- coding: utf-8 -*-
#使用K-Means算法聚類消費行為特征資料
import pandas as pd
#參數初始化
inputfile = 'F:/大二下合集/Python資料分析與挖掘/consumption_data.xls' #銷量及其他屬性資料
outputfile = 'F:/大二下合集/Python資料分析與挖掘/data_type.xls' #儲存結果的檔案名
k = 3 #聚類的類别
iteration = 500 #聚類最大循環次數
data = pd.read_excel(inputfile, index_col = 'Id') #讀取資料
data_zs = 1.0*(data - data.mean())/data.std() #資料标準化
from sklearn.cluster import KMeans
model = KMeans(n_clusters = k, n_jobs = 4, max_iter = iteration) #分為k類,并發數4
model.fit(data_zs) #開始聚類
#簡單列印結果
r1 = pd.Series(model.labels_).value_counts() #統計各個類别的數目
r2 = pd.DataFrame(model.cluster_centers_) #找出聚類中心
r = pd.concat([r2, r1], axis = 1) #橫向連接配接(0是縱向),得到聚類中心對應的類别下的數目
r.columns = list(data.columns) + [u'類别數目'] #重命名表頭
print(r)
#詳細輸出原始資料及其類别
r = pd.concat([data, pd.Series(model.labels_, index = data.index)], axis = 1) #詳細輸出每個樣本對應的類别
r.columns = list(data.columns) + [u'聚類類别'] #重命名表頭
r.to_excel(outputfile) #儲存結果
def density_plot(data): #自定義作圖函數
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用來正常顯示中文标簽
plt.rcParams['axes.unicode_minus'] = False #用來正常顯示負号
p = data.plot(kind='kde', linewidth = 2, subplots = True, sharex = False)
[p[i].set_ylabel(u'密度') for i in range(k)]
plt.legend()
return plt
pic_output = 'F:/大二下合集/Python資料分析與挖掘/pd_' #機率密度圖檔案名字首
for i in range(k):
density_plot(data[r[u'聚類類别']==i]).savefig(u'%s%s.png' %(pic_output, i))
運作結果:
在你所輸出的目錄下會有圖檔:
這個案例代碼沒問題
5-5
#-*- coding: utf-8 -*-
#接k_means.py
from sklearn.manifold import TSNE
tsne = TSNE()
tsne.fit_transform(data_zs) #進行資料降維
tsne = pd.DataFrame(tsne.embedding_, index = data_zs.index) #轉換資料格式
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用來正常顯示中文标簽
plt.rcParams['axes.unicode_minus'] = False #用來正常顯示負号
#不同類别用不同顔色和樣式繪圖
d = tsne[r[u'聚類類别'] == 0]
plt.plot(d[0], d[1], 'r.')
d = tsne[r[u'聚類類别'] == 1]
plt.plot(d[0], d[1], 'go')
d = tsne[r[u'聚類類别'] == 2]
plt.plot(d[0], d[1], 'b*')
plt.show()
代碼錯誤:
原因:
需要與5-4案例結合
解決:
在5-5代碼之前添加,如下代碼
#-*- coding: utf-8 -*-
#接k_means.py
import pandas as pd
inputfile = 'F:/大二下合集/Python資料分析與挖掘/consumption_data.xls'
outputfile = 'F:/大二下合集/Python資料分析與挖掘/data_type.xls'
k = 3
iteration = 500
data = pd.read_excel(inputfile, index_col = 'Id')
data_zs = 1.0*(data - data.mean())/data.std()
from sklearn.cluster import KMeans
model = KMeans(n_clusters = k, n_jobs = 4, max_iter = iteration)
model.fit(data_zs)
r1 = pd.Series(model.labels_).value_counts()
r2 = pd.DataFrame(model.cluster_centers_)
r = pd.concat([r2, r1], axis = 1)
r.columns = list(data.columns) + [u'類别數目']
print(r)
r = pd.concat([data, pd.Series(model.labels_, index = data.index)], axis = 1)
r.columns = list(data.columns) + [u'聚類類别']
r.to_excel(outputfile)
5-6
import pandas as pd
from apriori import * #導入自行編寫的apriori函數
inputfile = 'F:/大二下合集/Python資料分析與挖掘/menu_orders.xls'
outputfile = 'F:/大二下合集/Python資料分析與挖掘/apriori_rules.xls' #結果檔案
data = pd.read_excel(inputfile, header = None)
print(u'\n轉換原始資料至0-1矩陣...')
ct = lambda x : pd.Series(1, index = x[pd.notnull(x)]) #轉換0-1矩陣的過渡函數,非空值轉換成‘1’
b = map(ct, data.values) #用map方式執行
data = pd.DataFrame(list(b)).fillna(0) #實作矩陣轉換,空值用0填充
print(u'\n轉換完畢。')
del b #删除中間變量b,節省記憶體
support = 0.2 #最小支援度
confidence = 0.5 #最小置信度
ms = '---' #連接配接符,預設'--',用來區分不同元素,如A--B。需要保證原始表格中不含有該字元
find_rule(data, support, confidence, ms).to_excel(outputfile) #儲存結果
代碼錯誤:
這裡錯誤圖檔沒了,我來口述這個錯誤,就是會報錯找不到apriori
原因:
cm_plot是個自定義函數,你還沒有這個函數
解決:
添加自定義apriori函數,函數内容如下:
#-*- coding: utf-8 -*-
from __future__ import print_function
import pandas as pd
#自定義連接配接函數,用于實作L_{k-1}到C_k的連接配接
def connect_string(x, ms):
x = list(map(lambda i:sorted(i.split(ms)), x))
l = len(x[0])
r = []
for i in range(len(x)):
for j in range(i,len(x)):
if x[i][:l-1] == x[j][:l-1] and x[i][l-1] != x[j][l-1]:
r.append(x[i][:l-1]+sorted([x[j][l-1],x[i][l-1]]))
return r
#尋找關聯規則的函數
def find_rule(d, support, confidence, ms = u'--'):
result = pd.DataFrame(index=['support', 'confidence']) #定義輸出結果
support_series = 1.0*d.sum()/len(d) #支援度序列
column = list(support_series[support_series > support].index) #初步根據支援度篩選
k = 0
while len(column) > 1:
k = k+1
print(u'\n正在進行第%s次搜尋...' %k)
column = connect_string(column, ms)
print(u'數目:%s...' %len(column))
sf = lambda i: d[i].prod(axis=1, numeric_only = True) #新一批支援度的計算函數
#建立連接配接資料,這一步耗時、耗記憶體最嚴重。當資料集較大時,可以考慮并行運算優化。
d_2 = pd.DataFrame(list(map(sf,column)), index = [ms.join(i) for i in column]).T
support_series_2 = 1.0*d_2[[ms.join(i) for i in column]].sum()/len(d) #計算連接配接後的支援度
column = list(support_series_2[support_series_2 > support].index) #新一輪支援度篩選
support_series = support_series.append(support_series_2)
column2 = []
for i in column: #周遊可能的推理,如{A,B,C}究竟是A+B-->C還是B+C-->A還是C+A-->B?
i = i.split(ms)
for j in range(len(i)):
column2.append(i[:j]+i[j+1:]+i[j:j+1])
cofidence_series = pd.Series(index=[ms.join(i) for i in column2]) #定義置信度序列
for i in column2: #計算置信度序列
cofidence_series[ms.join(i)] = support_series[ms.join(sorted(i))]/support_series[ms.join(i[:len(i)-1])]
for i in cofidence_series[cofidence_series > confidence].index: #置信度篩選
result[i] = 0.0
result[i]['confidence'] = cofidence_series[i]
result[i]['support'] = support_series[ms.join(sorted(i.split(ms)))]
result = result.T.sort_values(['confidence','support'], ascending = False) #結果整理,輸出
print(u'\n結果為:')
print(result)
return result
将自定義好的函數放入到你python環境下site-packages中,如下圖
5-7
#-*- coding: utf-8 -*-
#arima時序模型
import pandas as pd
#參數初始化
discfile = 'F:/大二下合集/Python資料分析與挖掘/arima_data.xls'
forecastnum = 5
#讀取資料,指定日期列為名額,Pandas自動将“日期”列識别為Datetime格式
data = pd.read_excel(discfile, index_col = u'日期')
#時序圖
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用來正常顯示中文标簽
plt.rcParams['axes.unicode_minus'] = False #用來正常顯示負号
data.plot()
plt.show()
#自相關圖
from statsmodels.graphics.tsaplots import plot_acf
plot_acf(data).show()
#平穩性檢測
from statsmodels.tsa.stattools import adfuller as ADF
print(u'原始序列的ADF檢驗結果為:', ADF(data[u'銷量']))
#傳回值依次為adf、pvalue、usedlag、nobs、critical values、icbest、regresults、resstore
#差分後的結果
D_data = data.diff().dropna()
D_data.columns = [u'銷量差分']
D_data.plot() #時序圖
plt.show()
plot_acf(D_data).show() #自相關圖
from statsmodels.graphics.tsaplots import plot_pacf
plot_pacf(D_data).show() #偏自相關圖
print(u'差分序列的ADF檢驗結果為:', ADF(D_data[u'銷量差分'])) #平穩性檢測
#白噪聲檢驗
from statsmodels.stats.diagnostic import acorr_ljungbox
print(u'差分序列的白噪聲檢驗結果為:', acorr_ljungbox(D_data, lags=1)) #傳回統計量和p值
from statsmodels.tsa.arima_model import ARIMA
data[u'銷量'] = data[u'銷量'].astype(float)
#定階
pmax = int(len(D_data)/10) #一般階數不超過length/10
qmax = int(len(D_data)/10) #一般階數不超過length/10
bic_matrix = [] #bic矩陣
for p in range(pmax+1):
tmp = []
for q in range(qmax+1):
try: #存在部分報錯,是以用try來跳過報錯。
tmp.append(ARIMA(data, (p,1,q)).fit().bic)
except:
tmp.append(None)
bic_matrix.append(tmp)
bic_matrix = pd.DataFrame(bic_matrix) #從中可以找出最小值
p,q = bic_matrix.stack().idxmin() #先用stack展平,然後用idxmin找出最小值位置。
print(u'BIC最小的p值和q值為:%s、%s' %(p,q))
model = ARIMA(data, (p,1,q)).fit() #建立ARIMA(0, 1, 1)模型
model.summary2() #給出一份模型報告
model.forecast(5) #作為期5天的預測,傳回預測結果、标準誤差、置信區間。
代碼錯誤:
沒有報錯,但是在idea中運作出模型報告、5天的預測,傳回預測結果、标準誤差、置信區間結果
原因:
model.summary2() #給出一份模型報告
model.forecast(5) #作為期5天的預測,傳回預測結果、标準誤差、置信區間。
修改為:(即添加print)
print(model.summary2()) #給出一份模型報告
print(model.forecast(5)) #作為期5天的預測,傳回預測結果、标準誤差、置信區間。
5-8
#-*- coding: utf-8 -*-
#使用K-Means算法聚類消費行為特征資料
import numpy as np
import pandas as pd
#參數初始化
inputfile = 'F:/大二下合集/Python資料分析與挖掘/consumption_data.xls' #銷量及其他屬性資料
k = 3 #聚類的類别
threshold = 2 #離散點門檻值
iteration = 500 #聚類最大循環次數
data = pd.read_excel(inputfile, index_col = 'Id') #讀取資料
data_zs = 1.0*(data - data.mean())/data.std() #資料标準化
from sklearn.cluster import KMeans
model = KMeans(n_clusters = k, n_jobs = 4, max_iter = iteration) #分為k類,并發數4
model.fit(data_zs) #開始聚類
#标準化資料及其類别
r = pd.concat([data_zs, pd.Series(model.labels_, index = data.index)], axis = 1) #每個樣本對應的類别
r.columns = list(data.columns) + [u'聚類類别'] #重命名表頭
norm = []
for i in range(k): #逐一處理
norm_tmp = r[['R', 'F', 'M']][r[u'聚類類别'] == i]-model.cluster_centers_[i]
norm_tmp = norm_tmp.apply(np.linalg.norm, axis = 1) #求出絕對距離
norm.append(norm_tmp/norm_tmp.median()) #求相對距離并添加
norm = pd.concat(norm) #合并
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用來正常顯示中文标簽
plt.rcParams['axes.unicode_minus'] = False #用來正常顯示負号
norm[norm <= threshold].plot(style = 'go') #正常點
discrete_points = norm[norm > threshold] #離群點
discrete_points.plot(style = 'ro')
for i in range(len(discrete_points)): #離群點做标記
id = discrete_points.index[i]
n = discrete_points.iloc[i]
plt.annotate('(%s, %0.2f)'%(id, n), xy = (id, n), xytext = (id, n))
plt.xlabel(u'編号')
plt.ylabel(u'相對距離')
plt.show()
這個案例代碼沒問題
【有問題或錯誤,請私信我将及時改正;借鑒文章标明出處,謝謝】