1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > K-近邻算法预测电影类型

K-近邻算法预测电影类型

时间:2022-11-11 09:44:21

相关推荐

K-近邻算法预测电影类型

K-近邻算法预测电影类型

k-近邻算法是一种比较简单,但是在一些方面又有很多作用的算法,比较常用的就是推荐入住位置,或者推荐入住酒店等等。

K-近邻算法的原理:就是根据特征值,计算出离自己最近的那个分类,自己也属于那个类别,K-近邻是一种分类的算法模型。

K-近邻算法的公式:(a1-b1)2 + (a2-b2)2 + (a3-b3)2 A(a1,a2,a3) B (b1,b2,b3)

A代表了已知的数据,B代表未知的数据,得出的结果就是未知的数据与已知的距离,也称为欧式距离

获取数据

在机器学习中数据是非常重要的,是取决你的模型是否能够成功的建立起来的重要因素。在这里我的数据是自己在豆瓣上面爬取出来的,如果不懂的爬虫的朋友可以自行百度,或者向我拿数据也是可以的。

|

这些就是数据,有演员、导演、票房等等。

处理数据

在机器学习中,机器只会识别数字,不能识别字符,所以我们要把这些数据都转换为数字,首先是转换票房,因为这里的票房是有亿、万这些字眼的,所以我们把他转化为数字。

mobie_box_list = []for i in all_data["mobie_box"]:if "亿" in i:mobie_box_list.append(float(re.match(r"\d.*\d+",i).group()) * 100000000)if "万" in i:mobie_box_list.append(float(re.match(r"\d.*\d+", i).group()) * 10000)all_data["mobie_box"] = mobie_box_listall_data["mobie_box"] = all_data["mobie_box"].astype("int")

因为这里的每部电影的电影类型都不止一个,所以我们只提取一个类型来预测比较好。

all_data["type"] = [ "".join(i[1:2]) if len(i) > 1 else "".join(i[:1]) for i in all_data["type"].str.split("、")]print(all_data["type"])

这里有些电影的导演不止一个人,所以我们要把导演给分隔出来,就是有些电影有两个导演,那我们就把导演给分隔出来,然后复制电影信息,然后把分隔出来的导演放进去。

all_data=all_data.drop('director', axis=1).join(all_data['director'].str.split(' / ', expand=True).stack().reset_index(level=1, drop=True).rename('director'))

对地区进行分类处理

n = 0dict_10 = {}country_list = list(set(all_data["country"].tolist()))for z in country_list:dict_10[z] = nn +=1print(dict_10)all_data["country"] = all_data["country"].map(dict_10)

因为暂时没想到比较好的办法来处理演员数据,所以在模型建立的时候,把演员从特征值中删除掉。

数据处理源代码

'''K-近邻预测电影类型creat on July 21,@Author 小明''''''1、处理数据2、特征工程3、数据集划分4、建立模型5、调整模型'''import pandas as pdfrom matplotlib.pylab import date2numfrom sklearn.preprocessing import StandardScalerfrom sklearn.neighbors import KNeighborsClassifierfrom sklearn.feature_extraction import DictVectorizerfrom sklearn.preprocessing import FunctionTransformerimport datetimeimport repd.set_option("display.max_columns",1000)pd.set_option("display.width",500)pd.set_option("display.max_colwidth",10000)#处理数据data_1 = pd.read_csv("I:/crack/DATA/movie_datadouban.csv")data_1.index.name = "id"data_2 = pd.read_csv("I:/crack/DATA/movie_datadouban_2.csv")data_3 = pd.read_csv("I:/crack/DATA/movie_datadouban_3.csv")data = pd.merge(data_3,data_2,how="outer")all_data = pd.merge(data,data_1,how="outer")data_4 = pd.read_csv("I:/crack/DATA/movie_data.csv")data_5 = pd.read_csv("I:/crack/DATA/movie_data.csv")data_6 = pd.read_csv("I:/crack/DATA/movie_data.csv")data_7 = pd.read_csv("I:/crack/DATA/movie_data.csv")data_8 = pd.read_csv("I:/crack/DATA/movie_data.csv")data_9 = pd.read_csv("I:/crack/DATA/movie_data.csv")data_10 = pd.read_csv("I:/crack/DATA/movie_data.csv")data_11 = pd.read_csv("I:/crack/DATA/movie_data.csv")data_12 = pd.read_csv("I:/crack/DATA/movie_data.csv")data_13 = pd.read_csv("I:/crack/DATA/movie_data.csv")d_1 = pd.merge(data_4,data_5,how="outer")d_2 = pd.merge(d_1,data_6,how="outer")d_3 = pd.merge(d_2,data_7,how="outer")d_4 = pd.merge(d_1,data_8,how="outer")d_5 = pd.merge(data_9,data_10,how="outer")d_6 = pd.merge(data_11,data_12,how="outer")d_7 = pd.merge(d_4,d_5,how="outer")d_8 = pd.merge(d_7,d_6,how="outer")d_9 = pd.merge(d_8,data_13,how="outer")all_d = d_9.loc[:,["title","mobie_box","history_rank"]]all_data = pd.merge(all_data,all_d,on=["title","title"])pd.DataFrame.to_csv(all_data,"I:/crack/DATA/all_movies.csv",encoding="utf_8_sig")#转换票房数据mobie_box_list = []for i in all_data["mobie_box"]:if "亿" in i:mobie_box_list.append(float(re.match(r"\d.*\d+",i).group()) * 100000000)if "万" in i:mobie_box_list.append(float(re.match(r"\d.*\d+", i).group()) * 10000)all_data["mobie_box"] = mobie_box_listall_data["mobie_box"] = all_data["mobie_box"].astype("int")#截取电影类型all_data["type"] = [ "".join(i[1:2]) if len(i) > 1 else "".join(i[:1]) for i in all_data["type"].str.split("、")]print(all_data["type"])#把导演分开出来all_data=all_data.drop('director', axis=1).join(all_data['director'].str.split(' / ', expand=True).stack().reset_index(level=1, drop=True).rename('director'))print(all_data)#把演员转换成列表形式# all_data = all_data.drop('actor', axis=1).join(all_data['actor'].str.split(' / ', expand=True).stack().reset_index(level=1, drop=True).rename('actor'))# print(all_data)#时间戳处理# time = pd.DatetimeIndex(all_data["release_time"])# all_data["year"] = time.year# all_data["month"] = time.month# all_data["day"] = time.day# all_data = all_data.drop(["release_time"],axis = 1)# all_data = all_data.drop(["actor"],axis = 1)all_data["release_time"] = pd.to_datetime(all_data["release_time"])all_data["release_time"] = date2num(all_data["release_time"])all_data["release_time"] = all_data["release_time"].astype("int")#特征工程vector = DictVectorizer(sparse=False)director_list = []# for z in all_data["director"]:#dict = {}#dict["director"] = z#director_list.append(dict)# director = vector.fit_transform(director_list)# all_data["director"] = director#将地区进行分类n = 0dict_10 = {}country_list = list(set(all_data["country"].tolist()))for z in country_list:dict_10[z] = nn +=1print(dict_10)all_data["country"] = all_data["country"].map(dict_10)#对电影类型进行分类处理# j = 0# dict_9 = {}# country_list = list(set(all_data["type"].tolist()))# for z in country_list:#dict_9[z] = j#j +=1# print(dict_9)# all_data["type"] = all_data["type"].map(dict_9)d = 0dict_8 = {}country_list = list(set(all_data["director"].tolist()))for z in country_list:dict_8[z] = dd +=1print(dict_8)all_data["director"] = all_data["director"].map(dict_8)pd.DataFrame.to_csv(all_data,"I:/crack/DATA/K-movie.csv",encoding="utf_8_sig")

模型建立

模型建立的步骤

1、读取数据

2、划分特征值和目标值

3、标准化处理

4、划分数据集

5、建立模型

6、模型评估

读取数据和划分特征值和目标值

import pandas as pdfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerfrom sklearn.neighbors import KNeighborsClassifierfrom sklearn.model_selection import train_test_splitfrom sklearn.decomposition import PCAdata = pd.read_csv("I:crack/DATA/K-movie.csv")#划分数据集target = data["type"]featrue = data.loc[:,["comment_number","country","play_time","release_time","score","mobie_box","history_rank","director"]]

标准化处理

因为防止某一特征值的数据对目标值的影响过大,所以要进行标准化处理

st = StandardScaler()featrue = st.fit_transform(featrue)

划分测试集和训练集

train_x,test_x,train_y,test_y = train_test_split(featrue,target,test_size=0.25)

train_x就是训练集的特征值

test_x就是测试集的特征值

train_y就是训练集的目标值

test_y就是测试集的目标值

test_size就是代表测试集占的比例

建立模型

kn = KNeighborsClassifier(n_neighbors=6,algorithm="auto")kn.fit(train_x,train_y)predict_y = kn.predict(test_x)score = kn.score(test_x,test_y)print(score)

n_neighbors代表提取分数最下的几个来预测,algorithm是用来对数据结构进行调优的,默认都是auto的

运行得出来的结果

得出来的准确率只有0.365,而且每次运行的准确率都是不一样的,那是因为每次测试集和训练集都是随机分隔的,所以结果不一样。

交叉验证

上面得出准确率这么低,难道这个项目就失败了吗?模型就失败了吗?不一定,因为还有一个K值的调优,只有我们把K值调到最优才能看到模型的准确率

交叉验证的原理:交叉验证就是先把训练集分为n等份,然后提取一部分当做验证集,然后对验证集进行预测,每次预测的结果都保留下来,然后把这些结果进行取平均值,因为有些模型是需要传递超参数的,比如K-近邻算法的K值,然后把每个可能的K-值放进去一一验证,就会得出最好的超参数的值,

网格搜索:网格搜索就是,有一些模型的超参数不知一个,然后网格搜索就会把这些参数都一一验证,得出最好的超参数

注意:交叉验证也可以得出测试集的预测值,和预测结果

import pandas as pdfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerfrom sklearn.neighbors import KNeighborsClassifierfrom sklearn.model_selection import train_test_splitfrom sklearn.decomposition import PCAfrom sklearn.model_selection import GridSearchCVdata = pd.read_csv("I:crack/DATA/K-movie.csv")#划分数据集target = data["type"]featrue = data.loc[:,["comment_number","country","play_time","score","mobie_box","history_rank","director"]]print(target)#标准化st = StandardScaler()featrue = st.fit_transform(featrue)#划分数据集train_x,test_x,train_y,test_y = train_test_split(featrue,target,test_size=0.25)#特征工程标准化sta = StandardScaler()train_x = sta.fit_transform(train_x)test_x = sta.fit_transform(test_x)#建立模型kn = KNeighborsClassifier()# kn.fit(train_x,train_y)## predict_y = kn.predict(test_x)## score = kn.score(test_x,test_y)# print(score)#建立交叉验证的对象gri = GridSearchCV(kn,param_grid={"n_neighbors":[1,2,3,4,5,6,7,8,9],"algorithm":["auto","ball_tree","kd_tree"]},cv=10)#这里把全部数据都当做训练集,因为数据量不多gri.fit(featrue,target)#打印测试集的准确率,这个值是所有结果中最好的结果,就是每个参数10次运行结果的最好结果print(gri.score(test_x,test_y))#打印最好的验证结果,就是最好的准确率平均值print(gri.best_score_)#打印最好的参数print(gri.best_estimator_)# 打印每个参数的每次预测的结果print(gri.cv_results_)

打印最好结果的平均值

打印最好的参数值

KNeighborsClassifier(algorithm=‘auto’, leaf_size=30, metric=‘minkowski’,

metric_params=None, n_jobs=None, n_neighbors=3, p=2,

weights=‘uniform’)

召回率和精准率和F1值

上面看到最好的平均值结果才0.31,难道这个模型就彻底没救了吗?也不是,我可以来看来每个分类的召回率和精准率和F1值

import pandas as pdfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerfrom sklearn.neighbors import KNeighborsClassifierfrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import classification_reportfrom sklearn.decomposition import PCAdata = pd.read_csv("I:crack/DATA/K-movie.csv")#划分数据集target = data["type"]featrue = data.loc[:,["comment_number","country","play_time","score","mobie_box","history_rank","director"]]#标准化st = StandardScaler()featrue = st.fit_transform(featrue)#划分数据集train_x,test_x,train_y,test_y = train_test_split(featrue,target,test_size=0.25)#特征工程标准化sta = StandardScaler()train_x = sta.fit_transform(train_x)test_x = sta.fit_transform(test_x)#建立模型kn = KNeighborsClassifier(n_neighbors=5,algorithm="auto")kn.fit(train_x,train_y)predict_y = kn.predict(test_x)score = kn.score(test_x,test_y)class_data = list(set(test_y.tolist()))print(class_data)all_class = list(set(target.tolist()))#传递的参数,y_true传递的是测试集的目标值,y_pred传递的是预测结果,target_names传递的是测试集的目标值的分类数据,labels传递的是分类索引的索引列表,也就是说target_names上面显示的名称都是从labels里面得来的。print(classification_report(y_true=test_y,y_pred=predict_y,target_names=class_data,labels=class_data))#返回的结果就是精确值、召回率、F1值、和每个类别在测试集中的真实数量

动作 0.24 0.36 0.29 11

歌舞 0.00 0.00 0.00 2

灾难 0.00 0.00 0.00 1

爱情 0.50 0.14 0.22 7

悬疑 0.00 0.00 0.00 5

喜剧 0.67 0.33 0.44 6

犯罪 0.00 0.00 0.00 3

同性 0.00 0.00 0.00 1

科幻 0.29 0.25 0.27 8

动画 0.50 0.92 0.65 12

剧情 0.29 0.50 0.36 4

音乐 0.00 0.00 0.00 1

西部 0.00 0.00 0.00 1

武侠 0.00 0.00 0.00 1

传记 0.17 0.25 0.20 4

奇幻 0.00 0.00 0.00 4

冒险 0.17 1.00 0.29 1

家庭 0.00 0.00 0.00 4

惊悚 0.00 0.00 0.00 4

这里可以看到这个模型对动画和冒险者这两个分类还是效果的,所以也证明了这个模型也不是一文不值的。

总结

这个模型的准确率这么低,不外乎几个原因:

1、数据量太小,不足以用来预测和分析

2、数据的价值太低,预测的结果不理想

3、数据处理的方法太差,没能发挥数据的价值,就像演员数据不能发挥作用

4、特征工程的处理方法不好,所以导致模型结果不理想。

我相信只要解决掉上面的问题,模型的准确率也会大大提高的。

有什么不懂的地方可以加我的QQ 1693490575 问我,或者有什么好的建议或者模型方法,也欢迎跟我探讨一下。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。