推荐系统-01-基于协同过滤的图书推荐系统(包括数据和代码)

文章目录

    • 0. 数据下载
    • 1. 背景描述
    • 2. 预测目的
    • 3. 数据总览
    • 4. 开始处理
      • 4.1 图书
        • 4.1.1 yearOfPublication
        • 4.1.2 publisher
      • 4.2 用户数据集
        • 4.2.1 userID
        • 4.2.2 Age
      • 4.3 评级数据集
        • 4.3.1 统计
    • 5. 基于简单流行度的推荐系统
    • 6. 基于协同过滤的推荐系统
      • 6.1 基于用户的协同过滤
      • 6.2 基于项目的协同过滤

0. 数据下载

关注公众号:『AI学习星球
回复:基于协同过滤的图书推荐系统 即可获取数据下载。
论文辅导算法学习可以通过公众号滴滴我
在这里插入图片描述

1. 背景描述

在图书推荐系统中,能够针对用户画像,用户行为及物品特征构建推荐系统。

2. 预测目的

在线推荐系统是许多电子商务网站的事情。推荐系统广泛地向最适合其口味和特征的顾客推荐产品。

3. 数据总览

针对Book Crossing数据集,开始构建图书推荐系统。该数据集包含三个用户,书籍和评级表。显式评级以1-10的等级表示(较高的值表示较高的升值),隐式评级以0表示

图书表字段
在这里插入图片描述
用户数据集
在这里插入图片描述
评级数据集
在这里插入图片描述

4. 开始处理

import pandas as pd
import matplotlib.pyplot as plt
import sklearn.metrics as metrics
# from sklearn.metrics import accuracy_score
import numpy as np
from sklearn.neighbors import NearestNeighbors
from scipy.spatial.distance import correlation
from sklearn.metrics.pairwise import pairwise_distances
import ipywidgets as widgets
from IPython.display import display, clear_output
from contextlib import contextmanager
import warnings
warnings.filterwarnings('ignore')
import numpy as np
import os, sys
import re
import seaborn as sns

首先,我们加载数据集并检查书籍,用户和评级数据集的形状,如下所示:

books = pd.read_csv('dataset/BX-Books.csv', sep=';', error_bad_lines=False, encoding="latin-1")
books.columns = ['ISBN', 'bookTitle', 'bookAuthor', 'yearOfPublication', 'publisher', 'imageUrlS', 'imageUrlM', 'imageUrlL']
users = pd.read_csv('dataset/BX-Users.csv', sep=';', error_bad_lines=False, encoding="latin-1")
users.columns = ['userID', 'Location', 'Age']
ratings = pd.read_csv('dataset/BX-Book-Ratings.csv', sep=';', error_bad_lines=False, encoding="latin-1")
ratings.columns = ['userID', 'ISBN', 'bookRating']
print (books.shape)
print (users.shape)
print (ratings.shape)

(271360, 8)
(278858, 3)
(1149780, 3)

4.1 图书

逐个探索每个数据集并从书籍数据集开始,我们可以看到图像URL列似乎不需要进行分析,因此可以删除这些列。

books.head()

在这里插入图片描述

books.drop(['imageUrlS', 'imageUrlM', 'imageUrlL'],axis=1,inplace=True)
books.head()

在这里插入图片描述
我们现在检查每个列的数据类型,并更正缺失和不一致的条目。我也在调整列宽以显示列的全文。

books.dtypes

在这里插入图片描述

4.1.1 yearOfPublication

现在我们检查此属性的唯一值。

books.yearOfPublication.unique()

在这里插入图片描述
yearOfPublication中有一些不正确的条目。

由于csv文件中的一些错误,发布商名称’DK Publishing Inc’和’Gallimard’在数据集中被错误地加载为yearOfPublication。
此外,某些值是字符串,并且在某些地方已将相同年份作为数字输入。

我们将对这些行进行必要的更正,并将yearOfPublication的数据类型设置为int。

books.loc[books.yearOfPublication == 'DK Publishing Inc',:]

在这里插入图片描述

# ISBN '0789466953'
books.loc[books.ISBN == '0789466953','yearOfPublication'] = 2000
books.loc[books.ISBN == '0789466953','bookAuthor'] = "James Buckley"
books.loc[books.ISBN == '0789466953','publisher'] = "DK Publishing Inc"
books.loc[books.ISBN == '0789466953','bookTitle'] = "DK Readers: Creating the X-Men, How Comic Books Come to Life (Level 4: Proficient Readers)"
#ISBN '078946697X'
books.loc[books.ISBN == '078946697X','yearOfPublication'] = 2000
books.loc[books.ISBN == '078946697X','bookAuthor'] = "Michael Teitelbaum"
books.loc[books.ISBN == '078946697X','publisher'] = "DK Publishing Inc"
books.loc[books.ISBN == '078946697X','bookTitle'] = "DK Readers: Creating the X-Men, How It All Began (Level 4: Proficient Readers)"
books.loc[(books.ISBN == '0789466953') | (books.ISBN == '078946697X'),:]

在这里插入图片描述
继续纠正出版年鉴的类型

books.yearOfPublication=pd.to_numeric(books.yearOfPublication, errors='coerce')
sorted(books['yearOfPublication'].unique())

[0, 1376, 1378, 1806, 1897, 1900, 1901, 1902, 1904, 1906, 1908, 1909, 1910, 1911, 1914, 1917, 1919, 1920, 1921, 1922, 1923, 1924, 1925, 1926, 1927, 1928, 1929, 1930, 1931, 1932, 1933, 1934, 1935, 1936, 1937, 1938, 1939, 1940, 1941, 1942, 1943, 1944, 1945, 1946, 1947, 1948, 1949, 1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2010, 2011, 2012, 2020, 2021, 2024, 2026, 2030, 2037, 2038, 2050]

现在可以看出yearOfPublication的类型为int,其值范围为0-2050。
由于该数据集建于2004年,我假设2006年之后的所有年份都无效,保留两年的保证金,以防数据集可能已更新。
对于所有无效条目(包括0),我将这些条目转换为NaN,然后​​用剩余年份的平均值替换它们。

books.loc[(books.yearOfPublication > 2006) | (books.yearOfPublication == 0),'yearOfPublication'] = np.NAN

用年出版的平均价值代替NaNs在案例数据集被更新的情况下保留一定的空白

books.yearOfPublication.fillna(round(books.yearOfPublication.mean()), inplace=True)
books.yearOfPublication.isnull().sum()

0

将dtype重置为int32

books.yearOfPublication = books.yearOfPublication.astype(np.int32)
4.1.2 publisher

来到“publisher”专栏,我已经处理了两个NaN值,将其替换为“其他”,因为在进行一些调查后无法推断出版商名称(检查jupyter notebook embed)

books.loc[books.publisher.isnull(),:]

在这里插入图片描述
调查有NaNs的行
以“Tyrant Moon”的书名来查看是否能得到任何线索

books.loc[(books.bookTitle == 'Tyrant Moon'),:]

在这里插入图片描述
检查行是否有书签作为查找器,看看我们是否能得到任何线索
与不同的出版商和图书作者的所有行

books.loc[(books.bookTitle == 'Finders Keepers'),:]

在这里插入图片描述
由图书作者检查以找到模式
都有不同的出版商。这里没有线索

books.loc[(books.bookAuthor == 'Elaine Corvidae'),:]

在这里插入图片描述
因为没有什么共同的东西可以推断出NaNs的发布者,将它们替换为“other”

books.loc[(books.ISBN == '193169656X'),'publisher'] = 'other'
books.loc[(books.ISBN == '1931696993'),'publisher'] = 'other'

4.2 用户数据集

现在我们探索用户数据集,首先检查其形状,前几列和数据类型。

print (users.shape)
users.head()

在这里插入图片描述

users.dtypes

在这里插入图片描述

4.2.1 userID
users.userID.values

array([ 1, 2, 3, …, 278856, 278857, 278858])

4.2.2 Age

检查唯一值后,userID看起来正确。但是,Age列具有NaN和一些非常高的值。在我看来,5岁以下和90岁以上的年龄没有多大意义,因此,这些正在被NaN取代。然后将所有NaN替换为Age的平均值,并将其数据类型设置为int。

sorted(users.Age.unique())

[nan, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0, 64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0, 80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0, 96.0, 97.0, 98.0, 99.0, 100.0, 101.0, 102.0, 103.0, 104.0, 105.0, 106.0, 107.0, 108.0, 109.0, 110.0, 111.0, 113.0, 114.0, 115.0, 116.0, 118.0, 119.0, 123.0, 124.0, 127.0, 128.0, 132.0, 133.0, 136.0, 137.0, 138.0, 140.0, 141.0, 143.0, 146.0, 147.0, 148.0, 151.0, 152.0, 156.0, 157.0, 159.0, 162.0, 168.0, 172.0, 175.0, 183.0, 186.0, 189.0, 199.0, 200.0, 201.0, 204.0, 207.0, 208.0, 209.0, 210.0, 212.0, 219.0, 220.0, 223.0, 226.0, 228.0, 229.0, 230.0, 231.0, 237.0, 239.0, 244.0]

年龄栏有一些无效的条目,比如nan,0和非常高的值,比如100和以上
在我看来,低于5和90以上的值对我们的图书评级案例没有多大意义。因此,用NaNs替换这些

users.loc[(users.Age > 90) | (users.Age < 5), 'Age'] = np.nan

用平均值代替NaN

users.Age = users.Age.fillna(users.Age.mean())

将数据类型设置为int

users.Age = users.Age.astype(np.int32)
sorted(users.Age.unique())

[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90]

我这里没有对Location列进行任何处理。但是,如果您希望可以进一步将其拆分为城市,州,国家,并使用文本处理模型进行一些处理

4.3 评级数据集

我们检查评级数据集的形状和前几行。它揭示了我们的用户手册评级矩阵将非常稀疏,因为与评级矩阵的大小(用户数量×书籍数量)相比,实际评级非常低。

ratings.shape

(1149780, 3)

如果每个用户对每个条目进行评级,那么评级数据集将有nusers * nbooks条目,这表明数据集非常稀疏。

n_users = users.shape[0]
n_books = books.shape[0]
print (n_users * n_books)

75670906880

ratings.head(5)

在这里插入图片描述

ratings.bookRating.unique()

array([ 0, 5, 3, 6, 8, 7, 10, 9, 4, 1, 2], dtype=int64)

除非将新书添加到图书数据集中,否则评级数据集应该只存在于我们的图书数据集里的书籍。

ratings_new = ratings[ratings.ISBN.isin(books.ISBN)]
print (ratings.shape)
print (ratings_new.shape)

(1149780, 3)
(1031136, 3)

可以看到,有许多行,有图书ISBN,而不是书籍数据集的一部分被删除了
除非新用户被添加到用户数据集,否则评级数据集应该有来自用户数据集的用户的评级。

ratings = ratings[ratings.userID.isin(users.userID)]
print (ratings.shape)
print (ratings_new.shape)

(1149780, 3)
(1031136, 3)

没有新用户添加,因此我们将使用高于数据集的新用户(1031136,3)

print ("number of users: " + str(n_users))
print ("number of books: " + str(n_books))

number of users: 278858
number of books: 271360

很明显,用户已经评价了一些书籍,这些书籍不是原始书籍数据集的一部分。数据集的稀疏度可以如下计算:

sparsity=1.0-len(ratings_new)/float(n_users*n_books)
print ('图书交叉数据集的稀疏级别是 ' +  str(sparsity*100) + ' %')

图书交叉数据集的稀疏级别是 99.99863734155898 %

由1-10表示的显式评级和由0表示的隐含评级现在必须分开。我们将仅使用明确的评级来构建我们的图书推荐系统。同样,用户也被分为明确评级的人和记录其隐性行为的人。

ratings.bookRating.unique()

array([ 0, 5, 3, 6, 8, 7, 10, 9, 4, 1, 2], dtype=int64)

因此,对隐式和显式的评级数据集进行了划分

ratings_explicit = ratings_new[ratings_new.bookRating != 0]
ratings_implicit = ratings_new[ratings_new.bookRating == 0]
print (ratings_new.shape)
print (ratings_explicit.shape)
print (ratings_implicit.shape)

(1031136, 3)
(383842, 3)
(647294, 3)

4.3.1 统计

bookRating的计数图表示更高的评级在用户中更常见,评级8的评级最高。

sns.countplot(data=ratings_explicit , x='bookRating')
plt.show()

在这里插入图片描述

5. 基于简单流行度的推荐系统

此时,可以基于不同书籍的用户评级的计数来构建基于简单流行度的推荐系统。很明显, J. K. Rowling撰写的书很受欢迎。

ratings_count = pd.DataFrame(ratings_explicit.groupby(['ISBN'])['bookRating'].sum())
top10 = ratings_count.sort_values('bookRating', ascending = False).head(10)
print ("推荐下列书籍")
top10.merge(books, left_index = True, right_on = 'ISBN')

在这里插入图片描述
类似地隔离那些在1-10中给出明确评分的用户以及那些隐含行为被跟踪的用户

users_exp_ratings = users[users.userID.isin(ratings_explicit.userID)]
users_imp_ratings = users[users.userID.isin(ratings_implicit.userID)]
print (users.shape)
print (users_exp_ratings.shape)
print (users_imp_ratings.shape)

(278858, 3)
(68091, 3)
(52451, 3)

6. 基于协同过滤的推荐系统

为了应对我的机器具有的计算能力并减少数据集大小,我正在考虑已经评定至少100本书籍和至少有100个评级的书籍的用户。

counts1 = ratings_explicit['userID'].value_counts()
ratings_explicit = ratings_explicit[ratings_explicit['userID'].isin(counts1[counts1 >= 100].index)]
counts = ratings_explicit['bookRating'].value_counts()
ratings_explicit = ratings_explicit[ratings_explicit['bookRating'].isin(counts[counts >= 100].index)]

从显式的评级表生成评级矩阵
构建基于CF的推荐系统的下一个关键步骤是从评级表生成用户项目评级矩阵。

ratings_matrix = ratings_explicit.pivot(index='userID', columns='ISBN', values='bookRating')
userID = ratings_matrix.index
ISBN = ratings_matrix.columns
print(ratings_matrix.shape)
ratings_matrix.head()

在这里插入图片描述

n_users = ratings_matrix.shape[0] #只考虑那些给出明确评级的用户
n_books = ratings_matrix.shape[1]
print (n_users, n_books)

449 66574

因为NaN不能通过训练算法来处理,将它们替换为0,这表示没有评级
设置数据类型

ratings_matrix.fillna(0, inplace = True)
ratings_matrix = ratings_matrix.astype(np.int32)
ratings_matrix.head(5)

在这里插入图片描述
复查稀疏

sparsity=1.0-len(ratings_explicit)/float(users_exp_ratings.shape[0]*n_books)
print ('图书交叉数据集的稀疏级别是 ' +  str(sparsity*100) + ' %')

图书交叉数据集的稀疏级别是 99.99772184106935 %

6.1 基于用户的协同过滤

我将重用我的基于CF的推荐系统示例的功能。函数findsimilaruser输入userID和rating矩阵并返回k个类似用户的相似性和索引。

这个函数找到k个相似的用户,给定用户id和评级矩阵
这些相似点是通过使用配对距离获得的

global metric,k
k=10
metric='cosine'
def findksimilarusers(user_id, ratings, metric = metric, k=k):
    similarities=[]
    indices=[]
    model_knn = NearestNeighbors(metric = metric, algorithm = 'brute') 
    model_knn.fit(ratings)
    loc = ratings.index.get_loc(user_id)
    distances, indices = model_knn.kneighbors(ratings.iloc[loc, :].values.reshape(1, -1), n_neighbors = k+1)
    similarities = 1-distances.flatten()
            
    return similarities,indices

函数predict_userbased基于基于用户的方法预测指定用户 - 项目组合的评级。

def predict_userbased(user_id, item_id, ratings, metric = metric, k=k):
    prediction=0
    user_loc = ratings.index.get_loc(user_id)
    item_loc = ratings.columns.get_loc(item_id)
    similarities, indices=findksimilarusers(user_id, ratings,metric, k) #similar users based on cosine similarity
    mean_rating = ratings.iloc[user_loc,:].mean() #to adjust for zero based indexing
    sum_wt = np.sum(similarities)-1
    product=1
    wtd_sum = 0 
    
    for i in range(0, len(indices.flatten())):
        if indices.flatten()[i] == user_loc:
            continue;
        else: 
            ratings_diff = ratings.iloc[indices.flatten()[i],item_loc]-np.mean(ratings.iloc[indices.flatten()[i],:])
            product = ratings_diff * (similarities[i])
            wtd_sum = wtd_sum + product
    
    #在非常稀疏的数据集的情况下,使用基于协作的方法的相关度量可能会给出负面的评价
    #在这里的处理如下
    if prediction <= 0:
        prediction = 1   
    elif prediction >10:
        prediction = 10
    
    prediction = int(round(mean_rating + (wtd_sum/sum_wt)))
    print ('用户预测等级 {0} -> item {1}: {2}'.format(user_id,item_id,prediction))
 
    return prediction

测试

predict_userbased(11676,'0001056107',ratings_matrix)

用户预测等级 11676 -> item 0001056107: 2

功能recommendedItem使用上述功能来推荐基于用户或基于项目的方法的书籍(基于所选方法和度量组合)。如果图书的预测评级大于或等于6,并且图书尚未评级,则会提出建议。您可以在调用此函数时选择相似性度量(余弦/相关)

def recommendItem(user_id, ratings, metric=metric):    
    if (user_id not in ratings.index.values) or type(user_id) is not int:
        print("User id should be a valid integer from this list :\n\n {} ".format(re.sub('[\[\]]', '', np.array_str(ratings_matrix.index.values))))
    else:    
        ids = ['Item-based (correlation)','Item-based (cosine)','User-based (correlation)','User-based (cosine)']
        select = widgets.Dropdown(options=ids, value=ids[0],description='Select approach', width='1000px')
        def on_change(change):
            clear_output(wait=True)
            prediction = []            
            if change['type'] == 'change' and change['name'] == 'value':            
                if (select.value == 'Item-based (correlation)') | (select.value == 'User-based (correlation)') :
                    metric = 'correlation'
                else:                       
                    metric = 'cosine'   
                with suppress_stdout():
                    if (select.value == 'Item-based (correlation)') | (select.value == 'Item-based (cosine)'):
                        for i in range(ratings.shape[1]):
                            if (ratings[str(ratings.columns[i])][user_id] !=0): #not rated already
                                prediction.append(predict_itembased(user_id, str(ratings.columns[i]) ,ratings, metric))
                            else:                    
                                prediction.append(-1) #for already rated items
                    else:
                        for i in range(ratings.shape[1]):
                            if (ratings[str(ratings.columns[i])][user_id] !=0): #not rated already
                                prediction.append(predict_userbased(user_id, str(ratings.columns[i]) ,ratings, metric))
                            else:                    
                                prediction.append(-1) #for already rated items
                prediction = pd.Series(prediction)
                prediction = prediction.sort_values(ascending=False)
                recommended = prediction[:10]
                print("As per {0} approach....Following books are recommended...".format(select.value))
                for i in range(len(recommended)):
                     print("{0}. {1}".format(i+1,books.bookTitle[recommended.index[i]].encode('utf-8')))                        
        select.observe(on_change)
        display(select)

而且Voila !!! 根据基于用户的CF方法,检查用户4385的前10本书籍建议。

recommendItem(4385,ratings_matrix)

在这里插入图片描述

6.2 基于项目的协同过滤

已经为基于项目的CF编写了类似的函数来查找类似的书籍并预测用户对每本书的评级。相同的功能recommendedItem可用于根据基于项目的方法和选定的指标推荐书籍。如果图书的预测评级大于或等于6,并且图书尚未评级,则会提出建议。

def findksimilaritems(item_id, ratings, metric=metric, k=k):
    similarities=[]
    indices=[]
    ratings=ratings.T
    loc = ratings.index.get_loc(item_id)
    model_knn = NearestNeighbors(metric = metric, algorithm = 'brute')
    model_knn.fit(ratings)
    
    distances, indices = model_knn.kneighbors(ratings.iloc[loc, :].values.reshape(1, -1), n_neighbors = k+1)
    similarities = 1-distances.flatten()
 
    return similarities,indices
def predict_itembased(user_id, item_id, ratings, metric = metric, k=k):
    prediction= wtd_sum =0
    user_loc = ratings.index.get_loc(user_id)
    item_loc = ratings.columns.get_loc(item_id)
    similarities, indices=findksimilaritems(item_id, ratings) #similar users based on correlation coefficients
    sum_wt = np.sum(similarities)-1
    product=1
    for i in range(0, len(indices.flatten())):
        if indices.flatten()[i] == item_loc:
            continue;
        else:
            product = ratings.iloc[user_loc,indices.flatten()[i]] * (similarities[i])
            wtd_sum = wtd_sum + product                              
    prediction = int(round(wtd_sum/sum_wt))
    
    #在非常稀疏的数据集的情况下,使用基于协作的方法的相关度量可能会给出负面的评价
    #在这里处理的是下面的//代码,没有下面的代码片段,下面的代码片段是为了避免负面影响
    #在使用相关度规时,可能会出现非常稀疏的数据集的预测
    if prediction <= 0:
        prediction = 1   
    elif prediction >10:
        prediction = 10
 
    print ('用户预测等级 {0} -> item {1}: {2}'.format(user_id,item_id,prediction)    )  
    
    return prediction

测试

prediction = predict_itembased(11676,'0001056107',ratings_matrix)

用户预测等级 11676 -> item 0001056107: 1

哇!!!根据基于项目的CF方法检查用户4385的前10本书籍建议。这些与基于用户的方法建议的显着不同。

recommendItem(4385,ratings_matrix)

在这里插入图片描述

关注公众号:『AI学习星球
回复:基于协同过滤的图书推荐系统 即可获取数据下载。
论文辅导算法学习可以通过公众号滴滴我
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/216307.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LangChain学习指南(一)——Model IO

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Langchain是什么&#xff1f;二、官方文档Langchain这么长&#xff0c;我怎么看&#xff1f;三、Model IO2.1.1prompt2.1.2LLM2.1.3 OutputParsers 前言 本…

Csharp(C#)无标题栏窗体拖动代码

C#&#xff08;C Sharp&#xff09;是一种现代、通用的编程语言&#xff0c;由微软公司在2000年推出。C#是一种对象导向的编程语言&#xff0c;它兼具C语言的高效性和Visual Basic语言的易学性。C#主要应用于Windows桌面应用程序、Windows服务、Web应用程序、游戏开发等领域。C…

Jmeter接口自动化测试 —— Jmeter变量的使用

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

Linux:dockerfile编写搭建tomcat练习(9)

我使用的httpyum仓库 本地使用了5个文件&#xff0c;tomcat使用的官网解压直接用的包】 Dockerfile 主配置文件 基于centos基础镜像 jdk1.8.0_91 java环境 run.sh 启动脚本 centos.repo 仓库文件 tomcat 源码包 vim Dockerfile写入FROM centos MAINTAINER ta…

倚天屠龙:Github Copilot vs Cursor

武林至尊&#xff0c;宝刀屠龙。号令天下&#xff0c;莫敢不从。倚天不出&#xff0c;谁与争锋&#xff01; 作为开发人员吃饭的家伙&#xff0c;一款好的开发工具对开发人员的帮助是无法估量的。还记得在学校读书的时候&#xff0c;当时流行CS架构的RAD&#xff0c;Delphi和V…

二维码智慧门牌管理系统升级解决方案:存疑地址轻松管理

文章目录 前言一、存疑地址的统一管理二、数据查询、导出和编辑功能三、提交地址审核机制 前言 随着二维码智慧门牌管理系统在企业中的广泛应用&#xff0c;地址存疑成为了一个亟待解决的问题。为了帮助企业有效管理这些存疑地址&#xff0c;我们推出了升级解决方案&#xff0…

YOLOv8改进 | 2023 | AKConv轻量级架构下的高效检测(既轻量又提点)

一、本文介绍 本文给大家带来的改进内容是AKConv是一种创新的变核卷积&#xff0c;它旨在解决标准卷积操作中的固有缺陷&#xff08;采样形状是固定的&#xff09;&#xff0c;AKConv的核心思想在于它为卷积核提供了任意数量的参数和任意采样形状&#xff0c;能够使用任意数量…

FreeRTOS-软件定时器

软件定时器 在FreeRTOS中可以设置无数个软件定时器&#xff0c;都是基于系统滴答中断。 使用软件定时器需要指定时间&#xff1a;启动定时器和运行回调函数。启动定时器和运行回调函数的间隔为定时器的周期。 使用软件定时器需要指定类型&#xff1a;一次性&#xff08;回调函数…

优维产品最佳实践第17期:善用控制台

「 背 景 」 遇到页面报错时&#xff0c;是不是感到困扰&#xff0c;不知如何解决&#xff1f; 页面响应缓慢时&#xff0c;是否感到迷茫&#xff0c;不清楚从何入手排查&#xff1f; 面对主机高负载时&#xff0c;是不是觉得确认异常根因很有挑战&#xff1f; 本期最佳实践…

变配电智能监控系统

变配电智能监控系统是一种能够实时监测电力变压器和配电柜、配电箱运行状态的智能设备。这种系统利用先进的传感器和数据通信技术&#xff0c;能够实时监测电力设备的运行状态&#xff0c;包括电压、电流、温度、湿度等参数&#xff0c;并且能够对这些数据进行处理和分析&#…

新媒体营销模拟实训室解决方案

一、引言 随着互联网的发展&#xff0c;新媒体已成为企业进行营销和品牌推广的重要渠道。然而&#xff0c;对于许多企业来说&#xff0c;如何在新媒体上进行有效的营销仍是一大挑战。为了解决这个问题&#xff0c;我们推出了一款新媒体营销模拟实训室解决方案&#xff0c;以帮…

焊接专业个人简历(通用25篇)

如果大家想在焊接行业的求职中脱颖而出&#xff0c;轻松斩获心仪职位&#xff0c;参考这25篇通用的焊接专业个人简历案例&#xff0c;无论您是初学者还是资深焊工&#xff0c;都能从中找到适合自己的简历内容。参考这些简历&#xff0c;让您的求职之路更加顺畅。 焊接专业个人…

Web漏洞分析-SQL注入XXE注入(中上)

随着互联网的不断普及和Web应用的广泛应用&#xff0c;网络安全问题愈发引起广泛关注。在网络安全领域中&#xff0c;SQL注入和XXE注入是两个备受关注的话题&#xff0c;也是导致许多安全漏洞的主要原因之一。本博客将深入研究这两种常见的Web漏洞&#xff0c;带您探寻背后的原…

C++基础 -38- 模板函数的局限性

模板函数无法对自定义数据类型进行操作(如类) 这个时候我们重载一个函数来匹配操作即可 #include "iostream"using namespace std;class base { public:base(int a) : a(a) {}int a; };template <class T, class T1> bool compare(T a, T1 b) {if (a > b…

蓝桥杯-03-蓝桥杯学习计划

蓝桥杯-03-蓝桥杯学习计划 参考资料 相关文献 报了蓝桥杯比赛&#xff0c;几乎零基础&#xff0c;如何准备&#xff0c;请大牛指导一下。谢谢&#xff1f; 蓝桥杯2022各组真题汇总(完整可评测) 基础学习 C语言网 ACM竞赛入门,蓝桥杯竞赛指南 廖雪峰的官方官网 算法题单 洛谷…

【JavaEE】单例模式

作者主页&#xff1a;paper jie_博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文于《JavaEE》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和精力)打造&…

爬虫概念、基本使用及一个类型和六个方法(一)

目录 一、爬虫简介 1.什么是爬虫 2.爬虫的核心 3.爬虫的用途 4.爬虫的分类 5.反爬手段 二、Urllib基本使用 1.导入我们需要的包 2.定义一个url 3.模拟浏览器向服务器发送请求 4.获取响应中的页面的源码 5.打印数据 三、一个类型和六个方法 1.定义url&#xff0c;并…

C++初阶 | [七] string类(上)

摘要&#xff1a;标准库中的string类的常用函数 C语言中&#xff0c;字符串是以\0结尾的一些字符的集合&#xff0c;为了操作方便&#xff0c;C标准库中提供了一些str系列的库函数&#xff0c; 但是这些库函数与字符串是分离开的&#xff0c;不太符合OOP(面向对象)的思想&#…

【vue】vue-slick-carousel插件,实现横向滚动列表手动左右滚动(也可设置为自动滚动)

需求&#xff1a;图片列表横向滚动的时候&#xff0c;隐藏原始滚动条&#xff0c;通过左右箭头控制滚动条往左右按一定的步长移动。 el-carousel走马灯一滚动就是一屏&#xff0c;不适合我的需求 在npm官网搜vue-slick-carousel&#xff0c;查看更详细的配置 vue-slick-caro…

解决xshell连接诶树莓派中文乱码的问题

系统版本 解决办法 在根目录下找到 /etc/profile 修改profile文件,添加以下两行.以便重启之后也能生效: export LANGzh_CN.utf8 export LC_ALLzh_CN.utf8注意: /etc/profile的修改需要root权限才能修改! 在xshell的编码格式改为UTF-8