Advertisement

推荐系统-机器学习

阅读量:

推荐系统学习笔记

同类相融:提供与你喜欢物类相近的商品;同类相益:帮助人们找到与你兴趣相同的商品

数据分析:

image-20210424202939114
image-20210424204021125

推荐系统的分类:

image-20210424204637451

基于协同过滤的推荐算法

协同过滤(Collaborative Filtering CF)

image-20210424215241383
image-20210424221052392
image-20210424221932704

推荐准确度预测

image-20210425185942734
image-20210425191407819
重要的概率公式
image-20210425194923913

机器学习相关知识

机器学习的分类

image-20210425200237287
无监督学习

对样本点的分组或聚类

image-20210425200737171
监督学习

分类和回归

image-20210425201320945

损失函数

image-20210425204113071

训练误差和测试误差

image-20210425204618033
image-20210425205319534

欠拟合与过拟合

  • 欠拟合(Model Underfitting):在训练过程中模型未能充分捕捉到数据中的模式和关系。
    • 过拟合(Model Overfitting)现象发生在训练过程过于专注细节阶段,在此情况下模型不仅捕捉了训练数据中的有用模式还过度适应了噪声特征。
image-20210425205149663
正则化
image-20210425205458812
留意交叉验证
image-20210425205734647

分类和回归

image-20210426084144604

模型求解算法

梯度下降算法
image-20210426092839569
牛顿法和拟牛顿法
image-20210426094738860

监督学习

线性回归模型
一元线性回归
image-20210426103340925
多元线性回归
image-20210426103354716
最小二乘法
image-20210426111138030
梯度下降和最小二乘法区别
image-20210429184532281

分类器

K紧邻(KNN)
image-20210502085540730

KNN的效果很大程度上取决于K的选择

image-20210502090726369

K近邻算法计算过程:

image-20210502091501548

代码实现:

复制代码
    import numpy as  np
    import pandas as pd
    from sklearn.datasets import  load_iris #引入鸢尾花的数据集
    from sklearn.model_selection import train_test_split  #把数据集分为训练集测试集
    from sklearn.metrics import accuracy_score  #用来计算分分类预测的准确率 
    
    iris = load_iris()
    
    df = pd.DataFrame(data=iris.data,columns=iris.feature_names)  #加载数据集
    df['class'] = iris.target
    df['class'] = df['class'].map({0:iris.target_names[0],1:iris.target_names[1],2:iris.target_names[2]})
    
    x = iris.data
    y = iris.target.reshape(-1,1)  #-1 代表的是这个维度不知道分为几个,就哦耶那个-1表示  ,第二维用1表示1个分量
    # print(y)
    
    # print(x.shape,y.shape)
    
    # 划分训练集和测试集                                        #测试集比例       #随即划分使用的种子 #保持比例,按照y的分布等比例分割
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=35, stratify=y)
    # print(x_train,y_train)
    
    # print(x_train.shape,y_train.shape)
    # print(x_test.shape,y_test.shape)
    # print(df)
    # df.head(10)
    # print(df.describe())#//打印对应的数据的相关的信息 50%中位数   25% 1/4位数  75% 3/4位数
    # print(iris.data)
    
    # print(x_test[0].reshape(1,-1))
    #核心算法的实现
    def l1_distance(a,b): #要求前边是一个矩阵后边是一个向量,就相当于前边的一个矩阵每一行减去b这个向量
    return np.sum(np.abs(a-b),axis=1)  #把结果保存成一列,相当于对每一行求和,如果给了一个维度,就相当于把所有的加到一起.
    
    def l2_distance(a,b): #要求前边是一个矩阵后边是一个向量,就相当于前边的一个矩阵每一行减去b这个向量
    return np.sqrt(np.sum((a-b)**2,axis=1))  #把结果保存成一列,相当于对每一行求和,如果给了一个维度,就相当于把所有的加到一起.
    
    #分类器的实现
    class KNN(object):
    def __init__(self,n_neighbors=1,dist_func=l1_distance):
        super(KNN, self).__init__()
        self.n_neighbors = n_neighbors
        self.dist_func = dist_func
    
       #训练模型和方法
    def fit(self,x,y):
        self.x_train = x
        self.y_train = y
    
    #模型预测
    def predict(self,x):
        #初始化预测数组
        y_pred = np.zeros((x.shape[0],1),dtype=self.y_train.dtype)
        for i,x_test in enumerate(x):
            #x_test跟所有训练数据计算距离
            distances = self.dist_func(self.x_train,x_test)
            # 得到的距离按照有近到远排序,取出索引值
            nn_index = np.argsort(distances)  #argsort(np.array[13,12,15,14])  排序后是返回的对应的下标 这个返回的[1,0,2,3]
    
            #取出n个索引对应的分类是什么
            nn_y = self.y_train[ nn_index[:self.n_neighbors] ].ravel()#ravel把多维转化为一维
    
            y_pred[i] = np.argmax( np.bincount(nn_y))
        return y_pred
    #测试
    knn = KNN()
    knn.fit(x_train,y_train)#训练
    resultlist=[]
    for p in [1,2]:
    knn.dist_func = l1_distance if p==1 else l2_distance
    for k in range(1,10,2):
        knn.n_neighbors = k
        y_pred = knn.predict(x_test)
        #求出预测准确率
        accuracy = accuracy_score(y_test,y_pred)
        resultlist.append([k,'l1_distance' if p==1 else 'l2_distance',accuracy])
    print(resultlist)
    df = pd.DataFrame(resultlist,columns=['k','距离函数','准确率'])
    print(df)
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读
逻辑斯蒂回归

sigmoid函数:

image-20210507235429292

损失函数:

image-20210509234609074
image-20210509235025761
image-20210509235323496
决策树
image-20210509235534190
image-20210516122826585

无监督学习

image-20210516130528509

聚类K均值

image-20210516221853411

首先需要确定将数据划分为多少个(K)类别,
其中一个思路是利用K-近邻方法寻找与某一点距离较近的k个点,
另一个观点在于通过迭代计算各组数据的平均值

image-20210516222326888
K均值代码的实现:
复制代码
    # 0.引入依赖
    import numpy as np
    import matplotlib.pyplot as plt
    # 从sklearn中直接生成聚类数据
    from sklearn.datasets._samples_generator import make_blobs
    from scipy.spatial.distance import cdist
    
    # 1.数据加载进来
    x,y = make_blobs(n_samples=100,centers=6,random_state=1234,cluster_std=0.6) #n_samples表示样本点的个数  centers 表示6个中心点,按照6个中心点生成聚类数据 random_state随机种子,cluster_std 表示聚类的标准差
    # x 表示每个点  y表示对应的属于的类别(暂无用)
    # plt.figure(figsize=(6,6))
    # plt.scatter(x[:,0],x[:,1],c=y)  #每行的第一列表示一个坐标点的x坐标 第二列表示对用的y坐标 c= y 是颜色取不同的值会有不同的颜色显示
    # plt.show()
    
    # 2.算法实现
    #引入scipy中的距离函数  默认计算的是欧氏距离
    
    class K_Means(object):
    # 初始化 参数 n_clusters(K),max_iter,初始质心点 centroids
    def __init__(self, n_clusters=6, max_iter=300, centroids=[]):
        self.n_clusters = n_clusters
        self.max_iter = max_iter
        self.centroids = np.array(centroids,dtype=np.float32)
    
    #训练模型的过程,k-means聚类过程,传入原始数据
    def fit(self,data):
        #假如没有指定初试质心,就随机选取data中的点作为初始质心
        if (self.centroids.shape == (0,)):
            self.centroids = data[ np.random.randint(0,data.shape[0],self.n_clusters),: ] #从data中随机选取n_clusters 个作为质心
        #开始迭代
        for i in range(self.max_iter):
            # 1.第一步计算距离矩阵,得到的是100*6的矩阵 每一行表示一个点到所有质心点的距离
            distances = cdist(data,self.centroids)
    
            # 2.对距离按照由近到远排序,选取最近的质心点的类别,作为当前点的分类
            c_ind= np.argmin(distances,axis=1) #最后保存一列,每行表示当前点属于哪一类
    
            # 3.对每一类的数据进行均值计算,更新指点坐标
            for i in range(self.n_clusters):
                #排除掉没有出现在c_ind里的类别
                if i in c_ind:
                    #选出所有类别是i的点,取data里面坐标的均值,更新第i个质心 axis=0表示的是比较第一维的最小值 axi=1表示的是比较每一个一维的最小值
                    self.centroids[i] = np.mean(data[c_ind==i],axis=0) #选择对应行的列索引等于i的把每列求均值得到一行值
    
    
    def predic(self,samples):
        #先计算距离矩阵,然后选取距离最近的那个知悉你的类别
        distances = cdist(samples, self.centroids)
        c_ind = np.argmin(distances, axis=1)
        return c_ind #返回的是一组类别
    
    
    
    def plotKMeans(x,y,centroids,subplot,title):
    #分配子图
    plt.figure()
    plt.subplot(subplot)
    plt.scatter(x[:,0],x[:,1],c='r')
    #画出质心点
    plt.scatter(centroids[:,0],centroids[:,1],c=np.array(range(6)),s=100) #s表示质心点画图的大小
    plt.title(title)
    
    x_new = np.array([[0, 0], [10, 7]])
    y_pred = kmeans.predic(x_new)
    print(y_pred)
    plt.scatter(x_new[:, 0], x_new[:, 1], s=100, c='black')
    plt.show()
    
    kmeans = K_Means(max_iter=200,centroids=np.array([[2,1],[2,2],[2,3],[2,4],[2,5],[2,6]]))
    # plt.figure(figsize=(16,6))
    # plotKMeans(x,y,kmeans.centroids,121,title='Initial State') #121表示的一行两列中的第一个子图
    
    #开始聚类
    kmeans.fit(x)
    plotKMeans(x,y,kmeans.centroids,121,title='Solution State')
    #预测新数据点的类别
    
    
    # def main():
    #     dist = np.array([[123,12,32,43],
    #                     [14,123,32,43],
    #                     [23,12,32,43],
    #                     [109,190,232,93]])
    #     c_ind = np.argmin(dist,axis=1)
    #     x_new = x[0:5]
    #     # print(x_new)
    #     t = np.mean(x_new,axis=0) #保存第0维结果,就是
    #     print(t)
    #
    # if __name__ == '__main__':
    #     main()
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

推荐系统算法

常用的

基于人口统计学的推荐与用户画像

基于人口统计学的人口学推断系统是一种最为简便易行的应用程序设计模式,在这种情况下仅依靠系统数据库中存储的基础信息来识别用户的特性关联性,在此基础之上向当前用户提供与相似群体偏好的其他商品或服务

image-20210521212616216

基于内容的推荐与特征工程

image-20210521214633329

相似度计算:

image-20210521215007005
image-20210521215648859

基于系统过滤的推荐

特征工程

基于输入特征的有效提取与优化过程可实现目标输出的结果生成。
其中:

  • 特征被定义为数据集中能够有效预测结果的关键信息。
  • 特征的数量对应于数据样本所具有的观测维度。
  • 专业化的特征工程方法通过深入的数据分析与处理优化过程,在机器学习算法中展现出更优的表现能力。
    通常涉及三个主要环节:
  1. 首先是对数据进行采样以及异常样本的清理;
  2. 其次是对提取出的原始特征求解标准化或归一化处理;
  3. 最后是对最优特征求解选择。
    根据数据的不同类型(如数值、类别、时间等),对应的处理方法也会有所差异:
  • 数值型变量通常涉及连续且无限的可能性;
  • 类别型变量通常涉及离散且有限的不同取值范围;
  • 时间型变量则侧重于有序性和时间序列特性;
  • 统计型指标则用于衡量变量间的相关性和分布特性。
数值型
image-20210521231427177
image-20210521232030593
类别型特征处理
image-20210521232832924
时间型特征
  • 既可以做连续值,又可以做离散值
image-20210521233447610
统计型特征处理
image-20210521234745280
image-20210521235851293
image-20210529221847390
image-20210531141131109
TF-IDF 简单Demo
复制代码
    import numpy as np
    import pandas as pd
    import math
    
    #定义数据和预处理
    
    docA = "The cat sat on my bed"
    docB = "The dog sat on my knees"
    
    bowA = docA.split(" ")
    bowB = docB.split(" ")
    
    #构建一个完整的词库 set 元素可以自动去重
    wordSet = set(bowA).union(set(bowB)) #把两个集合合到一起
    
    #进行词数统计 用统计字典来保存文档中词出现的次数
    wordDicA = dict.fromkeys(wordSet,0) #用于记录A中每个词出现的个数进行初始化
    wordDicB = dict.fromkeys(wordSet,0)
    
    # 遍历文档统计词数
    for word in bowA:
    wordDicA[word] +=1
    
    for word in bowB:
    wordDicB[word] +=1
    
    # 计算词频
    def computeTF(wordDict, bow):
    # 用一个字典对象记录tf
    tfDict={}
    nbowCount = len(bow)
    for word,count in wordDict.items():
        tfDict[word] = count / nbowCount
    return tfDict  #计算每一个词对应的TF
    
    # 计算逆文档频率
    def computeIDF( wordDictList ):
    # 用一个字典对象保存IDF结果,每个词作为key
    idfDict = dict.fromkeys(wordDictList[0],0)
    N = len(wordDictList)
    for wordDict in wordDictList:
        #遍历词典中的么个词汇
        for word,count in wordDict.items():
            if count>0:
                idfDict[word]+=1
    # 上边处理之后就是每个单词在几个文档中出现过
    for word,count in idfDict.items():
        idfDict[word] = math.log10((N+1)/(count+1))
    return idfDict #返回的是所有词的idf
    
    tfA = computeTF(wordDicA,bowA)
    tfB = computeTF(wordDicB,bowB)
    idfs = computeIDF([wordDicA,wordDicB])
    
    #计算TF-IDF
    
    def computeTFIDF(tf,idfs):
    tfidf = {}
    for word,tfValue in tf.items():
        tfidf[word] = tfValue*idfs[word]
    return tfidf
    tfidfA = computeTFIDF(tfA,idfs)
    tfidfB = computeTFIDF(tfB,idfs)
    print(pd.DataFrame([tfidfA,tfidfB]))
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读
基于协同过滤推荐算法
基于紧邻的推荐算法
user-cf

基于用户的协同过滤:一般采用K-紧邻算法

image-20210531155605667
item-cf

基于物品的协同过滤

image-20210531155916541

两者的比较

image-20210531160112740
基于模型的协同过滤
image-20210531160811710

基于紧邻和基于模型的协同过滤的比较

image-20210531161030694
LFM隐语义模型
image-20210531162454492
image-20210531163000215
image-20210531163228059

模型的求解

损失函数:

image-20210531163538264

由于P与Q始终相互关联,因此必须使用ALS算法来确定P与Q最佳匹配的组合。

image-20210531164514865
image-20220114133226340

全部评论 (0)

还没有任何评论哟~