1. 程式人生 > >spark機器學習筆記:(二)用Spark Python進行資料處理和特徵提取

spark機器學習筆記:(二)用Spark Python進行資料處理和特徵提取

下面用“|”字元來分隔各行資料。這將生成一個RDD,其中每一個記錄對應一個Python列表,各列表由使用者ID(user ID)、年齡(age)、性別(gender)、職業(occupation)和郵編(ZIP code)五個屬性構成。4之後再統計使用者、性別、職業和郵編的數目。這可通過如下程式碼實現。該資料集不大,故這裡並未快取它。

user_fields = user_data.map(lambda line: line.split('|'))
num_users = user_fields.map(lambda fields: fields[0]).count
() #統計使用者數 num_genders = user_fields.map(lambda fields : fields[2]).distinct().count() #統計性別個數 num_occupations = user_fields.map(lambda fields: fields[3]).distinct().count() #統計職業個數 num_zipcodes = user_fields.map(lambda fields: fields[4]).distinct().count() #統計郵編個數 print "Users: %d, genders:
%d, occupations: %d, ZIP codes: %d"%(num_users,num_genders,num_occupations,num_zipcodes)

輸出結果:Users: 943, genders: 2, occupations: 21, ZIP codes: 795

畫出使用者的年齡分佈圖:

%matplotlib inline
import matplotlib.pyplot as plt
from matplotlib.pyplot import hist
ages = user_fields.map(lambda
x: int(x[1])).collect() hist(ages, bins=20, color='lightblue',normed=True) fig = plt.gcf() fig.set_size_inches(12,6) plt.show()


畫出使用者的職業的分佈圖:

#畫出使用者的職業的分佈圖:

import numpy as np
count_by_occupation = user_fields.map(lambda fields: (fields[3],1)).reduceByKey(lambda x,y:x+y).collect()
print count_by_occupation
x_axis1 = np.array([c[0] for c in count_by_occupation])
y_axis1 = np.array([c[1] for c in count_by_occupation])
x_axis = x_axis1[np.argsort(y_axis1)]
y_axis = y_axis1[np.argsort(y_axis1)]
pos = np.arange(len(x_axis))
width = 1.0
ax = plt.axes()
ax.set_xticks(pos+(width)/2)
ax.set_xticklabels(x_axis)

plt.bar(pos, y_axis, width, color='lightblue')
plt.xticks(rotation=30)
fig = plt.gcf()
fig.set_size_inches(12,6)
plt.show()

輸出結果:

[(u'administrator', 79), (u'retired', 14), (u'lawyer', 12), (u'none', 9), (u'student', 196), (u'technician', 27), (u'programmer', 66), (u'salesman', 12), (u'homemaker', 7), (u'executive', 32), (u'doctor', 7), (u'entertainment', 18), (u'marketing', 26), (u'writer', 45), (u'scientist', 31), (u'educator', 95), (u'healthcare', 16), (u'librarian', 51), (u'artist', 28), (u'other', 105), (u'engineer', 67)]

SparkRDD提供了一個名為countByValue的便捷函式。它會計算RDD裡各不同值所分別出現的次數,並將其以Pythondict函式的形式(或是ScalaJava下的Map函式)返回給驅動程式:

count_by_occupation2 = user_fields.map(lambda fields: fields[3]).countByValue()
print "Map-reduce approach:"
print dict(count_by_occupation2)
print "========================" 
print "countByValue approach:"
print dict(count_by_occupation)
輸出結果:
Map-reduce approach:
{u'administrator': 79, u'retired': 14, u'lawyer': 12, u'healthcare': 16, u'marketing': 26, u'executive': 32, u'scientist': 31, u'student': 196, u'technician': 27, u'librarian': 51, u'programmer': 66, u'salesman': 12, u'homemaker': 7, u'engineer': 67, u'none': 9, u'doctor': 7, u'writer': 45, u'entertainment': 18, u'other': 105, u'educator': 95, u'artist': 28}
========================
countByValue approach:
{u'administrator': 79, u'writer': 45, u'retired': 14, u'lawyer': 12, u'doctor': 7, u'marketing': 26, u'executive': 32, u'none': 9, u'entertainment': 18, u'healthcare': 16, u'scientist': 31, u'student': 196, u'educator': 95, u'technician': 27, u'librarian': 51, u'programmer': 66, u'artist': 28, u'salesman': 12, u'other': 105, u'homemaker': 7, u'engineer': 67}

2.2 探索電影資料

接下來了解下電影分類資料的特徵。如之前那樣,我們可以先簡單看一下某行記錄,然後再統計電影總數。

movie_data = sc.textFile("/Users/youwei.tan/ml-100k//u.item")
print movie_data.first()
num_movies = movie_data.count()
print 'Movies: %d' % num_movies
輸出結果:
1|Toy Story (1995)|01-Jan-1995||http://us.imdb.com/M/title-exact?Toy%20Story%20(1995)|0|0|0|1|1|1|0|0|0|0|0|0|0|0|0|0|0|0|0
Movies: 1682

繪製電影的age分佈圖:

繪製電影年齡的分佈圖的方法和之前對使用者年齡和職業分佈的處理類似。電影年齡即其發行年份相對於現在過了多少年(在本資料中現在是1998年)。從下面的程式碼可以看到,電影資料中有些資料不規整,故需要一個函式來處理解析releasedate時可能的解析錯誤。這裡命名該函式為convert_year

#畫出電影的age分佈圖:

def convert_year(x):
    try:
        return int(x[-4:])
    except:
        return 1900

movie_fields = movie_data.map(lambda lines:lines.split('|'))
years = movie_fields.map(lambda fields: fields[2]).map(lambda x: convert_year(x))
years_filtered = years.filter(lambda x: x!=1900)
print years_filtered.count()
movie_ages = years_filtered.map(lambda yr:1998-yr).countByValue()
values = movie_ages.values()
bins = movie_ages.keys()
hist(values, bins=bins, color='lightblue',normed=True)
fig = plt.gcf()
fig.set_size_inches(12,6)
plt.show()

輸出結果:

1681


2.3 探索評分資料

檢視評級資料記錄數量:
#檢視資料記錄數量:

rating_data = sc.textFile('/Users/youwei.tan/ml-100k/u.data')
print rating_data.first()
num_ratings = rating_data.count()
print 'Ratings: %d'% num_ratings

輸出結果:

196	242	3	881250949
Ratings: 100000

接下來,我們做一些資料的基本統計,以及繪製評級值分佈的直方圖。動手吧 

#對資料進行一些基本的統計:

rating_data = rating_data.map(lambda line: line.split('\t'))
ratings = rating_data.map(lambda fields: int(fields[2]))
max_rating = ratings.reduce(lambda x,y:max(x,y))
min_rating = ratings.reduce(lambda x,y:min(x,y))
mean_rating = ratings.reduce(lambda x,y:x+y)/num_ratings
median_rating = np.median(ratings.collect())
ratings_per_user = num_ratings/num_users;
ratings_per_movie = num_ratings/ num_movies
print 'Min rating: %d' %min_rating
print 'max rating: %d' % max_rating
print 'Average rating: %2.2f' %mean_rating
print 'Median rating: %d '%median_rating
print 'Average # of ratings per user: %2.2f'%ratings_per_user
print 'Average # of ratings per movie: %2.2f' % ratings_per_movie

輸出結果:

Min rating: 1
max rating: 5
Average rating: 3.00
Median rating: 4 
Average # of ratings per user: 106.00
Average # of ratings per movie: 59.00

從上述結果可以看到,最低的評級為1,而最大的評級為5。這並不意外,因為評級的範圍便是從15。 

SparkRDD也提供一個名為states的函式。該函式包含一個數值變數用於做類似的統計:

ratings.stats() 

輸出結果:

(count: 100000, mean: 3.52986, stdev: 1.12566797076, max: 5.0, min: 1.0)

可以看出,使用者對電影的平均評級(mean)是3.5左右,而評級中位數(median)為4。這就能期待說評級的分佈稍傾向高點的得分。要驗證這點,可以建立一個評級值分佈的條形圖。具體做法和之前的類似:

count_by_rating = ratings.countByValue()
x_axis = np.array(count_by_rating.keys())
y_axis = np.array([float(c) for c in count_by_rating.values()])
y_axis_normed = y_axis/y_axis.sum()
pos = np.arange(len(x_axis))
width = 1.0
ax = plt.axes()
ax.set_xticks(pos+(width/2))
ax.set_xticklabels(x_axis)

plt.bar(pos, y_axis_normed, width, color='lightblue')
plt.xticks(rotation=30)
fig = plt.gcf()
fig.set_size_inches(12,6)
plt.show()

輸出結果:


其特徵和我們之前所期待的相同,即評級的分佈的確偏向中等以上。 


接下來,計算每個使用者和其對應的評價次數:

#計算每個使用者和其對應的評價次數:

user_ratings_grouped = rating_data.map(lambda fields:(int(fields[0]),int(fields[2]))).groupByKey()
user_rating_byuser = user_ratings_grouped.map(lambda (k,v):(k,len(v)))
user_rating_byuser.take(5)
輸出結果:
[(2, 62), (4, 24), (6, 211), (8, 59), (10, 184)]

繪製每個使用者的總共評價次數的分佈圖:

相關推薦

spark機器學習筆記Spark Python進行資料處理特徵提取

下面用“|”字元來分隔各行資料。這將生成一個RDD,其中每一個記錄對應一個Python列表,各列表由使用者ID(user ID)、年齡(age)、性別(gender)、職業(occupation)和郵編(ZIP code)五個屬性構成。4之後再統計使用者、性別、職業和郵編的數目。這可通過如下程式碼

spark機器學習筆記Spark Python構建推薦系統

輸出結果: [[Rating(user=789, product=1012, rating=4.0), Rating(user=789, product=127, rating=5.0), Rating(user=789, product=475, rating=5.0), Rating(us

spark機器學習筆記Spark Python構建迴歸模型

博主簡介:風雪夜歸子(英文名:Allen),機器學習演算法攻城獅,喜愛鑽研Meachine Learning的黑科技,對Deep Learning和Artificial Intelligence充滿興趣,經常關注Kaggle資料探勘競賽平臺,對資料、Machi

spark機器學習筆記Spark Python構建分類模型

因此,當 wTx的估計值大於等於閾值0時,SVM對資料點標記為1,否則標記為0(其中閾值是SVM可以自適應的模型引數)。 SVM的損失函式被稱為合頁損失,定義為:                                                        

吳恩達老師機器學習筆記SVM

今天的部分是利用高斯核函式對分佈稍微複雜一點的資料進行分類 這裡的高斯核函式是構建新的特徵,該特徵是關於到其餘所有樣點的歐式距離。 下面放出程式碼: load('ex6data2.mat'); [m n]=size(X); f=zeros(m,m); a=0.005 for i=

WPF學習筆記資料繫結模式與INotifyPropertyChanged介面

資料繫結模式共有四種:OneTime、OneWay、OneWayToSource和TwoWay,預設是TwoWay。一般來說,完成資料繫結要有三個要點:目標屬性是依賴屬性、繫結設定和實現了INotifyPropertyChanged介面的資料來源(資料上下文)。 One

機器學習基本知識邏輯迴歸

一、分類和迴歸         迴歸(Regression)和分類(Classification)是機器學習中的兩大類問題,迴歸問題的輸出是連續的,而分類的輸出則是代表不同類別的有限個離散數值。        

系統學習機器學習之總結--離散型特徵編碼方式one-hot與啞變數*

在機器學習問題中,我們通過訓練資料集學習得到的其實就是一組模型的引數,然後通過學習得到的引數確定模型的表示,最後用這個模型再去進行我們後續的預測分類等工作。在模型訓練過程中,我們會對訓練資料集進行抽象、抽取大量特徵,這些特徵中有離散型特徵也有連續型特徵。若此時你使用的模型

統計學學習筆記隨機變數、概率密度、項分佈、期望值

隨機變數 Random Variable 隨機變數和一般資料上的變數不一樣,通常用大寫字母表示,如X、Y、Z,不是個引數而是function,即函式。例如,下面表示明天是否下雨的隨機變數X,如下。又例如X=每小時經過路口的車輛,隨機變數是個描述,而不是方程中的變數。 隨機變數有兩種,一種是離散的(disc

機器學習筆記7——聚類演算法

對於監督學習,訓練資料都是事先已知預測結果的,即訓練資料中已提供了資料的類標。無監督學習則是在事先不知道正確結果(即無類標資訊或預期輸出值)的情況下,發現數據本身所蘊含的結構等資訊。 無監督學習通過對無標記訓練樣本的學習來尋找這些資料的內在性質。 聚類的目標是發現數據中自然形成的分組,使得每

吳恩達老師機器學習筆記SVM

時隔好久沒有再拾起機器學習了,今日抽空接著學 今天是從最簡單的二維資料分類開始學習SVM~ (上圖為原始資料) SVM的代價函式 這裡套用以前logistic迴歸的模板改一下下。。 load('ex6data1.mat'); theta=rand(3,1); [

機器學習之旅

吳恩達教授的機器學習課程的第二週相關內容: 1、多變數線性迴歸(Linear Regression with Multiple Variables) 1.1、多維特徵 x

機器學習基礎知識

深度神經網路: 深度學習實際指的是基於深度神經網路( deep neural networks, DNN)的 學習,也就是深度人工神經網路所進行的學習過程,或稱作 Deep Learning。   這個 Deep 指 的是神經網路的深度(層數多)。   T

系統學習機器學習之總結--機器學習演算法比較

轉自:https://blog.csdn.net/bryan__/article/details/52026214 其實這篇文章真正出處來自:csuldw 本文主要回顧下幾個常用演算法的適應場景及其優缺點! 機器學習演算法太多了,分類、迴歸、聚類、推薦、影象識別領域等等,要想找到一個合適演算

機器學習-神經網路

上一篇:機器學習-神經網路(一) 神經網路的代價函式 符號 意義 L

python學習筆記迴圈forwhile

  在python中迴圈包括for和while 1、while迴圈   while 判斷條件:     statements ----表示:判斷條件為真時執行statements,為假不執行 2、for語句   for var in seq:     statements1   else:

機器學習——整合演算法

接著整合演算法講講GBDT和Xgboost,二者的原理其實差不多的,他們都屬於提升演算法。梯度上升(Gradient Boosting)是說,在整合演算法中每個弱決策樹的生成都是依據損失函式的梯度方向。 提升演算法,是找到找到最優解F(x)使得損失函式在訓練集上期望(偏差)

林軒田機器學習基石入門

上一節中我們主要講到機器學習的應用場景,而這一節主要向大家介紹我們身邊機器學習的例子,讓大家對機器學習有更多的直觀瞭解。 機器學習如今已滲透在我們的日行中,這很讓人驚訝,你每天都能夠接觸到它。 對於人們來說“衣食住行”是每天的基礎要求。 當你肚子餓想

spark原始碼閱讀筆記DatasetDataset中Actions、function、transformations

package Dataset import org.apache.spark.sql.functions._ import org.apache.spark.sql.{DataFrame, Dataset, SparkSession} /** * Cr

React 入門學習筆記整理—— JSX簡介與語法

先看下這段程式碼: import React from 'react'; //最終渲染需要呼叫ReactDOM庫,將jsx渲染都頁面中 import ReactDOM from 'react-dom'; import * as serviceWorker from './serviceWorker'; l