python亲和性分析法推荐电影论文_数据挖掘-MovieLens数据集_电影推荐_亲和性分析_Aprioro算法...
#!/usr/bin/env?python2
#?-*-?coding:?utf-8?-*-
"""
Created?on?Tue?Feb??7?14:38:33?2017
電影推薦分析:
使用?親和性分析方法?基于?Apriori算法?推薦電影
@author:?yingzhang
"""
#讀取數據集:?http://grouplens.org/datasets/movielens/
import?os
#使用pandas加載數據
import?pandas?as?pd
'''''
1m數據集讀取方法
'''
#data_folder=os.path.join(?os.path.expanduser("~"),"ml-1m")
#ratings_filename=os.path.join(?data_folder,"ratings.dat")
#all_ratings=pd.read_csv(?ratings_filename,?delimiter="::",header=None,?names=["UserID","MovieID","Rating","Datetime"])
'''''
100k數據集讀取方法
'''
data_folder=os.path.join(?os.path.expanduser("~"),"ml-100k")
#獲取用戶評分數據
ratings_filename=os.path.join(?data_folder,"u.data")
all_ratings=pd.read_csv(?ratings_filename,?delimiter="\t",header=None,?names=["UserID","MovieID","Rating","Datetime"])
all_ratings[:1]
#輸出的數據格式如下
'''''
UserID??MovieID??Rating???Datetime
0???????1?????1193???????5??978300760
'''
#時間格式要轉換一下
all_ratings["Datetime"]=pd.to_datetime(all_ratings["Datetime"],unit='s')
all_ratings[:1]
#新增一列,用來存用戶對某個電影是否喜歡?(?如果評分大于3)
all_ratings["Favorable"]=all_ratings["Rating"]>3
all_ratings[:10]
#輸出的數據格式如下:?Favorable這一列的數據表明用戶是否喜歡這部電影
'''''
UserID??MovieID??Rating????????????Datetime?Favorable
0???????1?????1193???????5?2000-12-31?22:12:40??????True
1???????1??????661???????3?2000-12-31?22:35:09?????False
'''
#從數據集中取前200名用戶的打分數據作訓練集
ratings=all_ratings[??all_ratings['UserID'].isin(range(200))]
#過濾一次數據,只保留用戶喜歡的電影(即?Favorable為True值的)
favorable_ratings=ratings[ratings["Favorable"]]
favorable_ratings[:5]
#因為要生成頻繁項集,所以我們只對打分超過一次的用戶感興趣,所以按照UserID分組,并遍歷每個用戶看過的每一部電影,存到一個字典中
from?collections?import?defaultdict
favorable_reviews_by_users=dict((k,frozenset(v.values))
for?k,v?in?favorable_ratings.groupby("UserID")["MovieID"])
print("length:?{0}".format(?len(favorable_reviews_by_users)?)?)
#再創建一個數據框,存入每部電影評價分為3分以上的人數(?即?Favorable為True)的數量
num_favorable_by_movie=ratings[["MovieID","Favorable"]].groupby("MovieID").sum()
#查看結果
num_favorable_by_movie
#排序輸出前五名
num_favorable_by_movie.sort(?"Favorable",ascending=False)[:5]
#創建一個函數,它接收新發現的頻繁項集,創建超集,檢測頻繁程度
'''''
favorable_reviews_by_users:?用戶打分情況的集合
k_1_itemsets:?上一個頻繁項集
min_support:最小支持度
返回值格式:
dict(?頻繁項集????支持度?)
'''
def?find_frequent_itemsets(?favorable_reviews_by_users,?k_1_itemsets,?min_support):
counts=defaultdict(?int?)
#循環用戶和他們的打分數據
for?user,reviews?in?favorable_reviews_by_users.items():
#再循環前一次找出的頻繁項集,判斷它們是否為?reviews的子集,
for?itemset?in?k_1_itemsets:
if?itemset.issubset(?reviews):??#如果是,表明用戶已經為子集中的電影打過分了
#那么接下來,就要遍歷用戶打過分卻沒有出現在項集reviews中的電影了,因為這樣可以用它來生成超集,更新該項集的計數
for?other_reviewed_movie?in?reviews-itemset:?#other_reviewed_movie?用戶打過分,但還不在頻繁項集中
current_superset=itemset|frozenset(?(other_reviewed_movie,))
counts[current_superset]+=1????#這個頻繁項集的數量支持度+1
#函數最后檢測達到支持度要求的項集,只返回頻繁度夠的頻繁項集
return?dict(??[(itemset,frequency)?for?itemset,frequency?in?counts.items()??if?frequency>=min_support???]???????????)
import?sys
#創建一個字典,存不同長度的頻繁項集
#數據格式:
#頻繁項集長度???對應的頻繁項集
frequent_itemsets={}
min_support=50???#要求的最小支持度
#從頻繁項集長度為1的開始,并且支持度要大于50
frequent_itemsets[1]=?dict((frozenset((movie_id,)),row["Favorable"])?for?movie_id,row?in?num_favorable_by_movie.iterrows()?if?row["Favorable"]>min_support)
#輸出頻繁集長度為1,支持度大于50的所有的電影信息
frequent_itemsets[1]
print("there?are?{0}?movie?with?more?than?{1}?favorable?reviews".format(?len(frequent_itemsets[1]),?min_support))
sys.stdout.flush()???#將緩沖區的內容輸出到終端
#定義要找的頻繁集的最大長度
max_length=20
#循環頻繁集長度從2到?max_length
for?k?in?range(2,?max_length):
cur_frequent_itemsets=find_frequent_itemsets(??favorable_reviews_by_users,??frequent_itemsets[k-1],?min_support???)
if?len(cur_frequent_itemsets)==0:
print("can?not?find?any?frequent?itemsets?of?length?{0}".format(?k?))
sys.stdout.flush()
break
else:
print("?find?{0}?frequent?itemsets?of?length?{1}".format(len(cur_frequent_itemsets),?k))
print("\t?data?as?following:")
#print(?cur_frequent_itemsets?)
sys.stdout.flush()
frequent_itemsets[k]=cur_frequent_itemsets
#?del?itemsets?of?length?1
#del?frequent_itemsets[1]
#######################################################################
#以上Apriori算法結束后,得到了一系列的頻繁項集,但它還不是關聯規則。頻繁項集是一組達到最小支持度的項目,而關聯規則是由前提和結論組成
#從頻繁項集中抽取關聯規則,把其中幾部電影作為前提,另一部電影作為結論組成規則:?如果用戶喜歡xx,yy,zz,那么他們也會喜歡ttt
#遍歷頻繁項集,為每個項集生成規則
candidate_rules=[]
#itemset_length?頻繁項集長度
#?itemset_counts?:??(itemset,frequency)
for?itemset_length,itemset_counts?in?frequent_itemsets.items():
#取出itemset_counts中的每個鍵,{電影1,電影2,...}
for?itemset?in?itemset_counts.keys():
#循環頻繁項集中的每部電影,生成條件和結論
for?conclusion?in?itemset:
premise=itemset-set((conclusion,))
candidate_rules.append((premise,conclusion))
print("there?are?{0}?candidate?rules".format(?len(candidate_rules)))
#print("the?rules?as?following:")
#print(?candidate_rules)
#######################################################################
#計算每條規則的置信度:
#先用兩個字典存規則應驗,?規則不適用數量
correct_counts=defaultdict(int)???#規則應驗
incorrect_counts=defaultdict(int)????#規則不適用
#循環所有的用戶及他們喜歡的電影
for?user,?reviews?in?favorable_reviews_by_users.items():
#循環所有的規則
for?candidate_rule?in?candidate_rules:
premise,conclusion=candidate_rule
#判斷前提是否是?reviews中的一個子集,?并且結論也在?reviews中,說明這條規則應驗,否則不適用
if?premise.issubset(reviews):
if?conclusion?in?reviews:
correct_counts[candidate_rule]+=1
else:
incorrect_counts[candidate_rule]+=1
#計算置信度
rule_confidence={candidate_rule:?correct_counts[candidate_rule]/?float(correct_counts[candidate_rule]+incorrect_counts[candidate_rule])?for?candidate_rule?in?candidate_rules}
#設定最低置信度
min_confidence=0.9
#過濾掉小于最低置信度的規則
rule_confidence={candidate_rule:??confidence?for????candidate_rule,confidence?in?rule_confidence.items()?if?confidence>min_confidence}
print(?"the?total?of?rules?which?bigger?than?min_confidence?is?{}".format(?len(rule_confidence?))?)
#排序輸出前五條置信度最高的規則
from?operator?import?itemgetter
sorted_confidence=sorted(?rule_confidence.items(),key=itemgetter(1),reverse=True)
for?index?in?range(5):
print("Rule?#{0}".format(index+1))
(premise,conclusion)=sorted_confidence[index][0]
print("Rule:?if?a?person?recommends?{0}?they?will?also?recommend?{1}".format(?premise,?conclusion))
print(?"?-?Confidence:?{0:.3f}".format(?rule_confidence[(premise,conclusion)]))
print("")
#######################################################################
#加載電影的名字
#100k數據集取法
movie_name_filename=os.path.join(?data_folder,"u.item")
movie_name_data=pd.read_csv(movie_name_filename,delimiter="|",header=None,encoding="mac-roman")
movie_name_data.columns=["MovieID",?"Title",?"Release?Date",?"Video?Release",?"IMDB",?"",?"Action",?"Adventure",
"Animation",?"Children's",?"Comedy",?"Crime",?"Documentary",?"Drama",?"Fantasy",?"Film-Noir",
"Horror",?"Musical",?"Mystery",?"Romance",?"Sci-Fi",?"Thriller",?"War",?"Western"]
#定義一個查找電影名的函數
def?get_movie_name(movie_id):
title_object=movie_name_data[movie_name_data["MovieID"]==movie_id]["Title"]
title=title_object.values[0]
return?title
#測試這個函數
get_movie_name(4)
#重新排序輸出前五條置信度最高的規則
for?index?in?range(5):
print("Rule?#{0}".format(index+1))
(premise,conclusion)=sorted_confidence[index][0]
premise_names=",".join(?get_movie_name(idx)?for?idx?in?premise??)
conclusion_name=get_movie_name(?conclusion)
print("Rule:?if?a?person?recommends?{0}?they?will?also?recommend?{1}".format(?premise_names,?conclusion_name))
print(?"?-?Confidence:?{0:.3f}".format(?rule_confidence[(premise,conclusion)]))
print("")
#######################################################################
#評估:?尋找最好的規則.
#抽取所有沒有用于訓練的數據作為測試集,?訓練集數據用了前200名用戶的打分數據,測試集用其它的數據即可
test_dataset=??all_ratings[~all_ratings['UserID'].isin(range(200))]
test_favorable_ratings=test_dataset[test_dataset["Favorable"]]
test_favorable_reviews_by_users=dict((k,frozenset(v.values))
for?k,v?in?test_favorable_ratings.groupby("UserID")["MovieID"])
#計算規則應驗的數量
test_correct_counts=defaultdict(int)???#規則應驗
test_incorrect_counts=defaultdict(int)????#規則不適用
#循環所有的用戶及他們喜歡的電影
for?user,?reviews?in?test_favorable_reviews_by_users.items():
#循環所有的規則
for?candidate_rule?in?candidate_rules:
premise,conclusion=candidate_rule
#判斷前提是否是?reviews中的一個子集,?并且結論也在?reviews中,說明這條規則應驗,否則不適用
if?premise.issubset(reviews):
if?conclusion?in?reviews:
test_correct_counts[candidate_rule]+=1
else:
test_incorrect_counts[candidate_rule]+=1
#計算置信度
test_rule_confidence={candidate_rule:?test_correct_counts[candidate_rule]/?float(test_correct_counts[candidate_rule]+test_incorrect_counts[candidate_rule])?for?candidate_rule?in?candidate_rules}
print(?len(test_rule_confidence))
#最后排序輸出前五名
sorted_test_confidence=sorted(??test_rule_confidence.items(),key=itemgetter(1),reverse=True?)
print(?sorted_test_confidence[:5])
#輸出規則信息
for?index?in?range(10):
print("Rule?#{0}".format(index+1))
(premise,conclusion)=sorted_confidence[index][0]
premise_names=",".join(?get_movie_name(idx)?for?idx?in?premise??)
conclusion_name=get_movie_name(?conclusion)
print("Rule:?if?a?person?recommends?{0}?they?will?also?recommend?{1}".format(?premise_names,?conclusion_name))
print(?"?-?Train?Confidence:?{0:.3f}".format(?rule_confidence[(premise,conclusion)]))
print(?"?-?Test?Confidence:?{0:.3f}".format(?test_rule_confidence[(premise,conclusion)]))
print("")
總結
以上是生活随笔為你收集整理的python亲和性分析法推荐电影论文_数据挖掘-MovieLens数据集_电影推荐_亲和性分析_Aprioro算法...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: winform combobox第123
- 下一篇: jsp实现mysql存储过程_JSP调用