リコメンドコンテスト2009で、データを分析する時に使ったプログラムを置いとく。
特異値分解して、ユーザー行列とワード行列、ユーザーベクトル同士のcosをとったものを出力する。
入力ファイルの形式は横にワード、縦にユーザー、中は検索回数
プログラムは
を参考にさせていただいた。感謝!
このプログラム使って何ら不具合起きても、責任取れません。
#-*-coding:utf-8-*- import numpy,codecs from numpy import * from scipy import linalg fin = open('user-word.csv','r') fout = codecs.open('lsi.csv', 'w', 'utf-8') fouta = codecs.open('user.csv', 'w', 'utf-8') foutb = codecs.open('word.csv', 'w', 'utf-8') wordlist = [] userid = [] allcount = [] i = 0 for line in fin: lines = line.split(',') if i == 0: for wordlistword in lines[1:]: wordlist.append(unicode(wordlistword,"utf-8")) else: userid.append(int(lines[0])) allcount.append(map(int,lines[1:])) i = i + 1 allcountg = array(allcount) k = len(userid) # 階数 u, sigma, v = linalg.svd(allcountg) # 特異値分解 u = array(u[:, :k]) s = array(linalg.diagsvd(sigma, k, k)) v = array(v[:k, :]) #次元圧縮 z= 0 while (sum(sigma[:z])/sum(sigma))<0.8: z = z + 1 print z uu = u[:, :z] ss = array(linalg.diagsvd(sigma[:z], z, z)) vv = v[:z, :] assyukuuser = uu assyukuword = transpose(vv) i = 0 for userb in assyukuuser: fout.write(str(userid[i])) for userbb in userb: fout.write(",") fout.write(str(userbb)) fout.write("\n") i = i + 1 i = 0 for wordb in assyukuword: foutb.write(wordlist[i]) for wordbb in wordb: foutb.write(",") foutb.write(str(wordbb)) foutb.write("\n") i = i + 1 for id in userid: fouta.write(",") fouta.write(str(id)) fouta.write("\n") i = 0 for usera in uu: lengtha = numpy.linalg.norm(usera) fouta.write(str(userid[i])) for userb in uu: lengthb = numpy.linalg.norm(userb) cosab = dot(usera,userb)/(lengtha*lengthb) fouta.write(",") fouta.write(str(cosab)) fouta.write("\n") i = i + 1