數(shù)據(jù)提取
在我之前的文章Scrapy自動爬取商品數(shù)據(jù)爬蟲里實現(xiàn)了爬蟲爬取商品網(wǎng)站搜索關(guān)鍵詞為python的書籍商品,爬取到了60多頁網(wǎng)頁的1260本python書籍商品的書名承耿,價格,評論數(shù)和商品鏈接攒读,并將所有商品數(shù)據(jù)存儲到本地的.json文件中。
數(shù)據(jù)存儲格式如下:
接下來對爬取到的商品數(shù)據(jù)作預(yù)處理及可視化分析辛友,使用工具為Anaconda的Jupyter notebook和python3.6環(huán)境薄扁。
首先用python將爬取到的數(shù)據(jù)輸出為.csv文件,方便觀察和保存再利用。觀察第1260個數(shù)據(jù)可以發(fā)現(xiàn)價格格式為“¥46.60”邓梅,評論數(shù)格式為“301條評論”脱盲,都為字符串格式,要先分別轉(zhuǎn)換為數(shù)字格式“46.60”和“301”以方便處理震放。
import json
import csv
import numpy as npy
import pandas as pda
#讀取.json文件
dic=[]
f = open("D:/python/.../getdata.json", 'r',encoding='utf-8')#這里為.json文件路徑
for line in f.readlines():
dic.append(json.loads(line))
#對爬取到的數(shù)據(jù)作處理宾毒,將價格和評論數(shù)由字符串處理為數(shù)字
tmp=''
name,price,comnum,link=[]
for i in range(0,1260):
dic[i]['price']=tmp + dic[i]['price'][1:]
dic[i]['comnum']=dic[i]['comnum'][:-3]+tmp
price.append(float(dic[i]['price']))
comnum.append(int(dic[i]['comnum']))
name.append(dic[i]['name'])
link.append(dic[i]['link'])
data = numpy.array([name,price,comnum,link]).T
print (data)
這里將爬取的數(shù)據(jù)都作處理后,轉(zhuǎn)換為python科學(xué)計算庫的numpy.array格式,data輸出結(jié)果如下:
然后將data存儲為.csv文件
#要存儲.csv文件的路徑
csvFile = open('D:/python/.../csvFile.csv','w')
writer = csv.writer(csvFile)
writer.writerow(['name', 'price', 'comnum','link'])
for i in range(0,1260):
writer.writerow(data[i])
csvFile.close()
現(xiàn)在可以打開該路徑下的.csv文件殿遂,已存儲為如下格式:
當(dāng)然可以在Scrapy爬蟲項目中修改pipelines.py文件诈铛,爬取到數(shù)據(jù)后直接輸出為.csv文件保存至本地,以相同方式改動添加上面的代碼即可墨礁,這里因為爬取到的數(shù)據(jù)并不直接可用幢竹,為方便分析處理先輸出到了.json文件。
數(shù)據(jù)清洗
缺失值處理
首先用數(shù)據(jù)分析處理庫pandas讀取.csv文件中的數(shù)據(jù)恩静,存儲為數(shù)據(jù)框格式焕毫。可以發(fā)現(xiàn)該數(shù)據(jù)中有許多書的評論數(shù)為0驶乾,所以首先要做數(shù)據(jù)清洗邑飒,找到這些缺失值,這也是數(shù)據(jù)分析過程中很重要的一環(huán)级乐。在數(shù)據(jù)分析過程中疙咸,對這些缺失數(shù)據(jù)有兩種處理方式,可以用評論數(shù)的均值來填補风科,也可以直接刪除缺失數(shù)據(jù)撒轮,針對相應(yīng)情況選擇處理方式。
#讀取.csv文件數(shù)據(jù)
data = pda.read_csv("D:/python/.../csvFile.csv")
#發(fā)現(xiàn)缺失值贼穆,將評論數(shù)為0的值轉(zhuǎn)為None
data["comnum"][(data["comnum"]==0)]=None
#均值填充處理
#data.fillna(value=data["comnum"].mean(),inplace=True)
#刪除處理,data1為缺失值處理后的數(shù)據(jù)
data1=data.dropna(axis=0,subset=["comnum"])
缺失數(shù)據(jù)過多题山,這里采取刪除處理方式。
異常值處理
在做異常值處理時首先要找到異常值故痊,先畫數(shù)據(jù)的散點圖觀察一下數(shù)據(jù)分布情況顶瞳,這里用python的數(shù)據(jù)可視化庫Matplotlib作圖。
import matplotlib.pyplot as plt
#畫散點圖(橫軸:價格愕秫,縱軸:評論數(shù))
#設(shè)置圖框大小
fig = plt.figure(figsize=(10,6))
plt.plot(data1['price'],data1['comnum'],"o")
#展示x浊仆,y軸標簽
plt.xlabel('price')
plt.ylabel('comnum')
plt.show()
可以看到有部分數(shù)據(jù)評論數(shù)過高,或許為熱銷商品或者存在刷評論豫领,還有一部分數(shù)據(jù)價格過高,甚至高達700舔琅,而一般書籍價格不會高過¥150等恐。對于這些異常值我們在作數(shù)據(jù)分析時一般不會考慮,刪除或者改動這些異常值即可。
再看看數(shù)據(jù)的箱型圖觀察分布情況:
fig = plt.figure(figsize=(10,6))
#初始化兩個子圖课蔬,分布為一行兩列
ax1 = fig.add_subplot(1,2,1)
ax2 = fig.add_subplot(1,2,2)
#繪制箱型圖
ax1.boxplot(data1['price'].values)
ax1.set_xlabel('price')
ax2.boxplot(data1['comnum'].values)
ax2.set_xlabel('comnum')
#設(shè)置x囱稽,y軸取值范圍
ax1.set_ylim(0,150)
ax2.set_ylim(0,1000)
plt.show()
價格的箱型圖中黃線表示中位數(shù),大概為¥50二跋,箱型圖上下分別為上四分位和下四分位战惊,分別為¥40到¥70,上下界分別為¥110和¥0扎即,最上方的圓點都是離群點吞获。可以看到評論數(shù)中位數(shù)分布點較低谚鄙。
離群點的數(shù)值明顯偏離其余觀測值各拷,會對分析結(jié)果產(chǎn)生不良影響,所以我們將價格¥120以上闷营,評論數(shù)700以上的離群點刪除烤黍,不作考慮,代碼如下:
#刪除價格¥120以上傻盟,評論數(shù)700以上的數(shù)據(jù)
data2=data[data['price']<120]
data3=data2[data2['comnum']<700]
#data3為異常值處理后的數(shù)據(jù)
fig = plt.figure(figsize=(10,6))
plt.plot(data3['price'],data3['comnum'],"o")
plt.xlabel('price')
plt.ylabel('comnum')
plt.show()
處理后數(shù)據(jù)剩余約500個速蕊,新數(shù)據(jù)分布如下圖:
數(shù)據(jù)可視化分析
直方圖可視化分析
最后可以對數(shù)據(jù)做可視化分析了,可以對價格及評論數(shù)做直方圖娘赴,分析數(shù)據(jù)分布情況规哲。
#求最值
pricemax=da2[1].max()
pricemin=da2[1].min()
commentmax=da2[2].max()
commentmin=da2[2].min()
##計算極差
pricerg=pricemax-pricemin
commentrg=commentmax-commentmin
#組距=極差/組數(shù)
pricedst=pricerg/13
commentdst=commentrg/13
fig = plt.figure(figsize=(12,5))
ax1 = fig.add_subplot(1,2,1)
ax2 = fig.add_subplot(1,2,2)
#繪制價格直方圖
#numpy.arrange(最小,最大,組距)
pricesty=numpy.arange(pricemin,pricemax,pricedst)
ax1.hist(da2[1],pricesty,rwidth=0.8)
ax1.set_title('price')
#繪制評論數(shù)直方圖
commentsty=numpy.arange(commentmin,commentmax,commentdst)
ax2.hist(da2[2],commentsty,rwidth=0.8)
ax2.set_title('comnum')
plt.show()
從直方圖中可以觀察到:
1、書的價格大致呈正態(tài)分布筝闹,¥40左右的書籍比較多媳叨,說明python書籍基本定價在¥40左右
2、評論數(shù)在50條以下的書籍商品最多(200多本)关顷,隨著評論數(shù)遞增糊秆,商品數(shù)量逐漸減少,說明大部分商品銷量一般议双,銷量較好的書就是那幾本經(jīng)典作品痘番。
K-Means聚類可視化分析
最后對數(shù)據(jù)作聚類分析,這里采用了機器學(xué)習(xí)算法——K-Means聚類算法平痰,K-Means聚類算法是機器學(xué)習(xí)中的一個無監(jiān)督學(xué)習(xí)算法汞舱,簡單,快速宗雇,適合常規(guī)數(shù)據(jù)集昂芜,具體的算法執(zhí)行步驟如下:
1、初始化聚類中心
2赔蒲、計算樣本點到各個聚類中心的距離泌神,選擇距離小的良漱,進行聚類
3、計算新的聚類中心欢际,改變新的聚類中心
4母市、重復(fù)2-3步,直到聚類中心不發(fā)生改變
通過調(diào)用Python的機器學(xué)習(xí)庫sklearn损趋,可利用此算法實現(xiàn)對商品的分類:
#轉(zhuǎn)換數(shù)據(jù)格式
tmp=numpy.array([data3['price'],data3['comnum']]).T
#調(diào)用python關(guān)于機器學(xué)習(xí)sklearn庫中的KMeans
from sklearn.cluster import KMeans
#設(shè)置分為3類患久,并訓(xùn)練數(shù)據(jù)
kms=KMeans(n_clusters=3)
y=kms.fit_predict(tmp)
#將分類結(jié)果以散點圖形式展示
fig = plt.figure(figsize=(10,6))
plt.xlabel('price')
plt.ylabel('comnum')
for i in range(0,len(y)):
if(y[i]==0):
plt.plot(tmp[i,0],tmp[i,1],"*r")
elif(y[i]==1):
plt.plot(tmp[i,0],tmp[i,1],"sy")
elif(y[i]==2):
plt.plot(tmp[i,0],tmp[i,1],"pb")
plt.show()
從聚類結(jié)果中可以看到,K-Means聚類算法將評論數(shù)100以下的分為了一類浑槽,評論數(shù)大致從100到350的分為一類蒋失,評論數(shù)大致在350以上的分為了一類,基本按照書籍是否暢銷分成了三類括荡,從圖中可明顯看出聚類效果高镐。
總結(jié)
本文總結(jié)了拿到一份初始的爬蟲數(shù)據(jù)后,從數(shù)據(jù)提取成文件畸冲,到數(shù)據(jù)缺失值和異常值處理嫉髓,再到商品的直方圖分布和K-Means聚類可視化分析的全部過程。以上過程就是利用python進行簡單的數(shù)據(jù)分析的大致過程邑闲,讀者在拿到一份數(shù)據(jù)后算行,也可參考本文代碼按照此過程自己進行數(shù)據(jù)分析,自己玩轉(zhuǎn)數(shù)據(jù)啦苫耸。
之后我還會繼續(xù)總結(jié)其他python爬蟲和數(shù)據(jù)分析技巧州邢,邊學(xué)習(xí)邊輸出哈,一些內(nèi)容也會發(fā)布在我的博客|巧不巧克力里褪子,歡迎參觀啦O(∩_∩)O