二 根據用戶行為數據創建ALS模型并召回商品

二 根據用戶行為數據創建ALS模型并召回商品

2.0 用戶行為數據拆分

  • 方便練習可以對數據做拆分處理

    • pandas的數據分批讀取 chunk 厚厚的一塊 相當大的數量或部分
    import pandas as pd
    reader = pd.read_csv('behavior_log.csv',chunksize=100,iterator=True)
    count = 0;
    for chunk in reader:count += 1if count ==1:chunk.to_csv('test4.csv',index = False)elif count>1 and count<1000:chunk.to_csv('test4.csv',index = False, mode = 'a',header = False)else:break
    pd.read_csv('test4.csv')
    

2.1 預處理behavior_log數據集

  • 創建spark session
import os
# 配置spark driver和pyspark運行時,所使用的python解釋器路徑
PYSPARK_PYTHON = "/home/hadoop/miniconda3/envs/datapy365spark23/bin/python"
JAVA_HOME='/home/hadoop/app/jdk1.8.0_191'
# 當存在多個版本時,不指定很可能會導致出錯
os.environ["PYSPARK_PYTHON"] = PYSPARK_PYTHON
os.environ["PYSPARK_DRIVER_PYTHON"] = PYSPARK_PYTHON
os.environ['JAVA_HOME']=JAVA_HOME
# spark配置信息
from pyspark import SparkConf
from pyspark.sql import SparkSessionSPARK_APP_NAME = "preprocessingBehaviorLog"
SPARK_URL = "spark://192.168.199.188:7077"conf = SparkConf()    # 創建spark config對象
config = (("spark.app.name", SPARK_APP_NAME),    # 設置啟動的spark的app名稱,沒有提供,將隨機產生一個名稱("spark.executor.memory", "6g"),    # 設置該app啟動時占用的內存用量,默認1g("spark.master", SPARK_URL),    # spark master的地址("spark.executor.cores", "4"),    # 設置spark executor使用的CPU核心數# 以下三項配置,可以控制執行器數量
#     ("spark.dynamicAllocation.enabled", True),
#     ("spark.dynamicAllocation.initialExecutors", 1),    # 1個執行器
#     ("spark.shuffle.service.enabled", True)
# 	('spark.sql.pivotMaxValues', '99999'),  # 當需要pivot DF,且值很多時,需要修改,默認是10000
)
# 查看更詳細配置及說明:https://spark.apache.org/docs/latest/configuration.htmlconf.setAll(config)# 利用config對象,創建spark session
spark = SparkSession.builder.config(conf=conf).getOrCreate()
  • 從hdfs中加載csv文件為DataFrame
# 從hdfs加載CSV文件為DataFrame
df = spark.read.csv("hdfs://localhost:9000/datasets/behavior_log.csv", header=True)
df.show()    # 查看dataframe,默認顯示前20條
# 大致查看一下數據類型
df.printSchema()    # 打印當前dataframe的結構

顯示結果:

+------+----------+----+-----+------+
|  user|time_stamp|btag| cate| brand|
+------+----------+----+-----+------+
|558157|1493741625|  pv| 6250| 91286|
|558157|1493741626|  pv| 6250| 91286|
|558157|1493741627|  pv| 6250| 91286|
|728690|1493776998|  pv|11800| 62353|
|332634|1493809895|  pv| 1101|365477|
|857237|1493816945|  pv| 1043|110616|
|619381|1493774638|  pv|  385|428950|
|467042|1493772641|  pv| 8237|301299|
|467042|1493772644|  pv| 8237|301299|
|991528|1493780710|  pv| 7270|274795|
|991528|1493780712|  pv| 7270|274795|
|991528|1493780712|  pv| 7270|274795|
|991528|1493780712|  pv| 7270|274795|
|991528|1493780714|  pv| 7270|274795|
|991528|1493780765|  pv| 7270|274795|
|991528|1493780714|  pv| 7270|274795|
|991528|1493780765|  pv| 7270|274795|
|991528|1493780764|  pv| 7270|274795|
|991528|1493780633|  pv| 7270|274795|
|991528|1493780764|  pv| 7270|274795|
+------+----------+----+-----+------+
only showing top 20 rowsroot|-- user: string (nullable = true)|-- time_stamp: string (nullable = true)|-- btag: string (nullable = true)|-- cate: string (nullable = true)|-- brand: string (nullable = true)
  • 從hdfs加載數據為dataframe,并設置結構
from pyspark.sql.types import StructType, StructField, StringType, IntegerType, LongType
# 構建結構對象
schema = StructType([StructField("userId", IntegerType()),StructField("timestamp", LongType()),StructField("btag", StringType()),StructField("cateId", IntegerType()),StructField("brandId", IntegerType())
])
# 從hdfs加載數據為dataframe,并設置結構
behavior_log_df = spark.read.csv("hdfs://localhost:8020/datasets/behavior_log.csv", header=True, schema=schema)
behavior_log_df.show()
behavior_log_df.count() 

顯示結果:

+------+----------+----+------+-------+
|userId| timestamp|btag|cateId|brandId|
+------+----------+----+------+-------+
|558157|1493741625|  pv|  6250|  91286|
|558157|1493741626|  pv|  6250|  91286|
|558157|1493741627|  pv|  6250|  91286|
|728690|1493776998|  pv| 11800|  62353|
|332634|1493809895|  pv|  1101| 365477|
|857237|1493816945|  pv|  1043| 110616|
|619381|1493774638|  pv|   385| 428950|
|467042|1493772641|  pv|  8237| 301299|
|467042|1493772644|  pv|  8237| 301299|
|991528|1493780710|  pv|  7270| 274795|
|991528|1493780712|  pv|  7270| 274795|
|991528|1493780712|  pv|  7270| 274795|
|991528|1493780712|  pv|  7270| 274795|
|991528|1493780714|  pv|  7270| 274795|
|991528|1493780765|  pv|  7270| 274795|
|991528|1493780714|  pv|  7270| 274795|
|991528|1493780765|  pv|  7270| 274795|
|991528|1493780764|  pv|  7270| 274795|
|991528|1493780633|  pv|  7270| 274795|
|991528|1493780764|  pv|  7270| 274795|
+------+----------+----+------+-------+
only showing top 20 rowsroot|-- userId: integer (nullable = true)|-- timestamp: long (nullable = true)|-- btag: string (nullable = true)|-- cateId: integer (nullable = true)|-- brandId: integer (nullable = true)
  • 分析數據集字段的類型和格式
    • 查看是否有空值
    • 查看每列數據的類型
    • 查看每列數據的類別情況
print("查看userId的數據情況:", behavior_log_df.groupBy("userId").count().count())
# 約113w用戶
#注意:behavior_log_df.groupBy("userId").count()  返回的是一個dataframe,這里的count計算的是每一個分組的個數,但當前還沒有進行計算
# 當調用df.count()時才開始進行計算,這里的count計算的是dataframe的條目數,也就是共有多少個分組
查看user的數據情況: 1136340
print("查看btag的數據情況:", behavior_log_df.groupBy("btag").count().collect())    # collect會把計算結果全部加載到內存,謹慎使用
# 只有四種類型數據:pv、fav、cart、buy
# 這里由于類型只有四個,所以直接使用collect,把數據全部加載出來
查看btag的數據情況: [Row(btag='buy', count=9115919), Row(btag='fav', count=9301837), Row(btag='cart', count=15946033), Row(btag='pv', count=688904345)]
print("查看cateId的數據情況:", behavior_log_df.groupBy("cateId").count().count())
# 約12968類別id
查看cateId的數據情況: 12968
print("查看brandId的數據情況:", behavior_log_df.groupBy("brandId").count().count())
# 約460561品牌id
查看brandId的數據情況: 460561
print("判斷數據是否有空值:", behavior_log_df.count(), behavior_log_df.dropna().count())
# 約7億條目723268134 723268134
# 本數據集無空值條目,可放心處理
判斷數據是否有空值: 723268134 723268134
  • pivot透視操作,把某列里的字段值轉換成行并進行聚合運算(pyspark.sql.GroupedData.pivot)
    • 如果透視的字段中的不同屬性值超過10000個,則需要設置spark.sql.pivotMaxValues,否則計算過程中會出現錯誤。文檔介紹。
# 統計每個用戶對各類商品的pv、fav、cart、buy數量
cate_count_df = behavior_log_df.groupBy(behavior_log_df.userId, behavior_log_df.cateId).pivot("btag",["pv","fav","cart","buy"]).count()
cate_count_df.printSchema()    # 此時還沒有開始計算

顯示效果:

root|-- userId: integer (nullable = true)|-- cateId: integer (nullable = true)|-- pv: long (nullable = true)|-- fav: long (nullable = true)|-- cart: long (nullable = true)|-- buy: long (nullable = true)
  • 統計每個用戶對各個品牌的pv、fav、cart、buy數量并保存結果
# 統計每個用戶對各個品牌的pv、fav、cart、buy數量
brand_count_df = behavior_log_df.groupBy(behavior_log_df.userId, behavior_log_df.brandId).pivot("btag",["pv","fav","cart","buy"]).count()
# brand_count_df.show()    # 同上
# 113w * 46w
# 由于運算時間比較長,所以這里先將結果存儲起來,供后續其他操作使用
# 寫入數據時才開始計算
cate_count_df.write.csv("hdfs://localhost:9000/preprocessing_dataset/cate_count.csv", header=True)
brand_count_df.write.csv("hdfs://localhost:9000/preprocessing_dataset/brand_count.csv", header=True)

2.2 根據用戶對類目偏好打分訓練ALS模型

  • 根據您統計的次數 + 打分規則 ==> 偏好打分數據集 ==> ALS模型
# spark ml的模型訓練是基于內存的,如果數據過大,內存空間小,迭代次數過多的化,可能會造成內存溢出,報錯
# 設置Checkpoint的話,會把所有數據落盤,這樣如果異常退出,下次重啟后,可以接著上次的訓練節點繼續運行
# 但該方法其實指標不治本,因為無法防止內存溢出,所以還是會報錯
# 如果數據量大,應考慮的是增加內存、或限制迭代次數和訓練數據量級等
spark.sparkContext.setCheckpointDir("hdfs://localhost:8020/checkPoint/")
from pyspark.sql.types import StructType, StructField, StringType, IntegerType, LongType, FloatType# 構建結構對象
schema = StructType([StructField("userId", IntegerType()),StructField("cateId", IntegerType()),StructField("pv", IntegerType()),StructField("fav", IntegerType()),StructField("cart", IntegerType()),StructField("buy", IntegerType())
])# 從hdfs加載CSV文件
cate_count_df = spark.read.csv("hdfs://localhost:9000/preprocessing_dataset/cate_count.csv", header=True, schema=schema)
cate_count_df.printSchema()
cate_count_df.first()    # 第一行數據

顯示結果:

root|-- userId: integer (nullable = true)|-- cateId: integer (nullable = true)|-- pv: integer (nullable = true)|-- fav: integer (nullable = true)|-- cart: integer (nullable = true)|-- buy: integer (nullable = true)Row(userId=1061650, cateId=4520, pv=2326, fav=None, cart=53, buy=None)
  • 處理每一行數據:r表示row對象
def process_row(r):# 處理每一行數據:r表示row對象# 偏好評分規則:#     m: 用戶對應的行為次數#     該偏好權重比例,次數上限僅供參考,具體數值應根據產品業務場景權衡#     pv: if m<=20: score=0.2*m; else score=4#     fav: if m<=20: score=0.4*m; else score=8#     cart: if m<=20: score=0.6*m; else score=12#     buy: if m<=20: score=1*m; else score=20# 注意這里要全部設為浮點數,spark運算時對類型比較敏感,要保持數據類型都一致pv_count = r.pv if r.pv else 0.0fav_count = r.fav if r.fav else 0.0cart_count = r.cart if r.cart else 0.0buy_count = r.buy if r.buy else 0.0pv_score = 0.2*pv_count if pv_count<=20 else 4.0fav_score = 0.4*fav_count if fav_count<=20 else 8.0cart_score = 0.6*cart_count if cart_count<=20 else 12.0buy_score = 1.0*buy_count if buy_count<=20 else 20.0rating = pv_score + fav_score + cart_score + buy_score# 返回用戶ID、分類ID、用戶對分類的偏好打分return r.userId, r.cateId, rating
  • 返回一個PythonRDD類型
# 返回一個PythonRDD類型,此時還沒開始計算
cate_count_df.rdd.map(process_row).toDF(["userId", "cateId", "rating"])

顯示結果:

DataFrame[userId: bigint, cateId: bigint, rating: double]
  • 用戶對商品類別的打分數據
# 用戶對商品類別的打分數據
# map返回的結果是rdd類型,需要調用toDF方法轉換為Dataframe
cate_rating_df = cate_count_df.rdd.map(process_row).toDF(["userId", "cateId", "rating"])
# 注意:toDF不是每個rdd都有的方法,僅局限于此處的rdd
# 可通過該方法獲得 user-cate-matrix
# 但由于cateId字段過多,這里運算量比很大,機器內存要求很高才能執行,否則無法完成任務
# 請謹慎使用# 但好在我們訓練ALS模型時,不需要轉換為user-cate-matrix,所以這里可以不用運行
# cate_rating_df.groupBy("userId").povit("cateId").min("rating")
# 用戶對類別的偏好打分數據
cate_rating_df

顯示結果:

DataFrame[userId: bigint, cateId: bigint, rating: double]
  • 通常如果USER-ITEM打分數據應該是通過一下方式進行處理轉換為USER-ITEM-MATRIX

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-bYZwXB3C-1691901742059)(/img/CF%E4%BB%8B%E7%BB%8D.png)]

但這里我們將使用的Spark的ALS模型進行CF推薦,因此注意這里數據輸入不需要提前轉換為矩陣,直接是 USER-ITEM-RATE的數據

  • 基于Spark的ALS隱因子模型進行CF評分預測

    • ALS的意思是交替最小二乘法(Alternating Least Squares),是Spark2.*中加入的進行基于模型的協同過濾(model-based CF)的推薦系統算法。

      同SVD,它也是一種矩陣分解技術,對數據進行降維處理。

    • 詳細使用方法:pyspark.ml.recommendation.ALS

    • 注意:由于數據量巨大,因此這里也不考慮基于內存的CF算法

      參考:為什么Spark中只有ALS

# 使用pyspark中的ALS矩陣分解方法實現CF評分預測
# 文檔地址:https://spark.apache.org/docs/2.2.2/api/python/pyspark.ml.html?highlight=vectors#module-pyspark.ml.recommendation
from pyspark.ml.recommendation import ALS   # ml:dataframe, mllib:rdd# 利用打分數據,訓練ALS模型
als = ALS(userCol='userId', itemCol='cateId', ratingCol='rating', checkpointInterval=5)# 此處訓練時間較長
model = als.fit(cate_rating_df)
  • 模型訓練好后,調用方法進行使用,具體API查看
# model.recommendForAllUsers(N) 給所有用戶推薦TOP-N個物品
ret = model.recommendForAllUsers(3)
# 由于是給所有用戶進行推薦,此處運算時間也較長
ret.show()
# 推薦結果存放在recommendations列中,
ret.select("recommendations").show()

顯示結果:

+------+--------------------+
|userId|     recommendations|
+------+--------------------+
|   148|[[3347, 12.547271...|
|   463|[[1610, 9.250818]...|
|   471|[[1610, 10.246621...|
|   496|[[1610, 5.162216]...|
|   833|[[5607, 9.065482]...|
|  1088|[[104, 6.886987],...|
|  1238|[[5631, 14.51981]...|
|  1342|[[5720, 10.89842]...|
|  1580|[[5731, 8.466453]...|
|  1591|[[1610, 12.835257...|
|  1645|[[1610, 11.968531...|
|  1829|[[1610, 17.576496...|
|  1959|[[1610, 8.353473]...|
|  2122|[[1610, 12.652732...|
|  2142|[[1610, 12.48068]...|
|  2366|[[1610, 11.904813...|
|  2659|[[5607, 11.699315...|
|  2866|[[1610, 7.752719]...|
|  3175|[[3347, 2.3429515...|
|  3749|[[1610, 3.641833]...|
+------+--------------------+
only showing top 20 rows+--------------------+
|     recommendations|
+--------------------+
|[[3347, 12.547271...|
|[[1610, 9.250818]...|
|[[1610, 10.246621...|
|[[1610, 5.162216]...|
|[[5607, 9.065482]...|
|[[104, 6.886987],...|
|[[5631, 14.51981]...|
|[[5720, 10.89842]...|
|[[5731, 8.466453]...|
|[[1610, 12.835257...|
|[[1610, 11.968531...|
|[[1610, 17.576496...|
|[[1610, 8.353473]...|
|[[1610, 12.652732...|
|[[1610, 12.48068]...|
|[[1610, 11.904813...|
|[[5607, 11.699315...|
|[[1610, 7.752719]...|
|[[3347, 2.3429515...|
|[[1610, 3.641833]...|
+--------------------+
only showing top 20 rows
  • model.recommendForUserSubset 給部分用戶推薦TOP-N個物品
# 注意:recommendForUserSubset API,2.2.2版本中無法使用
dataset = spark.createDataFrame([[1],[2],[3]])
dataset = dataset.withColumnRenamed("_1", "userId")
ret = model.recommendForUserSubset(dataset, 3)# 只給部分用推薦,運算時間短
ret.show()
ret.collect()    # 注意: collect會將所有數據加載到內存,慎用

顯示結果:

+------+--------------------+
|userId|     recommendations|
+------+--------------------+
|     1|[[1610, 25.4989],...|
|     3|[[5607, 13.665942...|
|     2|[[5579, 5.9051886...|
+------+--------------------+[Row(userId=1, recommendations=[Row(cateId=1610, rating=25.498899459838867), Row(cateId=5737, rating=24.901548385620117), Row(cateId=3347, rating=20.736785888671875)]),Row(userId=3, recommendations=[Row(cateId=5607, rating=13.665942192077637), Row(cateId=1610, rating=11.770171165466309), Row(cateId=3347, rating=10.35690689086914)]),Row(userId=2, recommendations=[Row(cateId=5579, rating=5.90518856048584), Row(cateId=2447, rating=5.624575138092041), Row(cateId=5690, rating=5.2555742263793945)])]
  • transform中提供userId和cateId可以對打分進行預測,利用打分結果排序后
# transform中提供userId和cateId可以對打分進行預測,利用打分結果排序后,同樣可以實現TOP-N的推薦
model.transform
# 將模型進行存儲
model.save("hdfs://localhost:8020/models/userCateRatingALSModel.obj")
# 測試存儲的模型
from pyspark.ml.recommendation import ALSModel
# 從hdfs加載之前存儲的模型
als_model = ALSModel.load("hdfs://localhost:8020/models/userCateRatingALSModel.obj")
# model.recommendForAllUsers(N) 給用戶推薦TOP-N個物品
result = als_model.recommendForAllUsers(3)
result.show()

顯示結果:

+------+--------------------+
|userId|     recommendations|
+------+--------------------+
|   148|[[3347, 12.547271...|
|   463|[[1610, 9.250818]...|
|   471|[[1610, 10.246621...|
|   496|[[1610, 5.162216]...|
|   833|[[5607, 9.065482]...|
|  1088|[[104, 6.886987],...|
|  1238|[[5631, 14.51981]...|
|  1342|[[5720, 10.89842]...|
|  1580|[[5731, 8.466453]...|
|  1591|[[1610, 12.835257...|
|  1645|[[1610, 11.968531...|
|  1829|[[1610, 17.576496...|
|  1959|[[1610, 8.353473]...|
|  2122|[[1610, 12.652732...|
|  2142|[[1610, 12.48068]...|
|  2366|[[1610, 11.904813...|
|  2659|[[5607, 11.699315...|
|  2866|[[1610, 7.752719]...|
|  3175|[[3347, 2.3429515...|
|  3749|[[1610, 3.641833]...|
+------+--------------------+
only showing top 20 rows
  • 召回到redis
import redis
host = "192.168.19.8"
port = 6379    
# 召回到redis
def recall_cate_by_cf(partition):# 建立redis 連接池pool = redis.ConnectionPool(host=host, port=port)# 建立redis客戶端client = redis.Redis(connection_pool=pool)for row in partition:client.hset("recall_cate", row.userId, [i.cateId for i in row.recommendations])
# 對每個分片的數據進行處理 #mapPartition Transformation   map
# foreachPartition Action操作             foreachRDD
result.foreachPartition(recall_cate_by_cf)# 注意:這里這是召回的是用戶最感興趣的n個類別
# 總的條目數,查看redis中總的條目數是否一致
result.count()

顯示結果:

1136340

2.3 根據用戶對品牌偏好打分訓練ALS模型

from pyspark.sql.types import StructType, StructField, StringType, IntegerTypeschema = StructType([StructField("userId", IntegerType()),StructField("brandId", IntegerType()),StructField("pv", IntegerType()),StructField("fav", IntegerType()),StructField("cart", IntegerType()),StructField("buy", IntegerType())
])
# 從hdfs加載預處理好的品牌的統計數據
brand_count_df = spark.read.csv("hdfs://localhost:8020/preprocessing_dataset/brand_count.csv", header=True, schema=schema)
# brand_count_df.show()
def process_row(r):# 處理每一行數據:r表示row對象# 偏好評分規則:#     m: 用戶對應的行為次數#     該偏好權重比例,次數上限僅供參考,具體數值應根據產品業務場景權衡#     pv: if m<=20: score=0.2*m; else score=4#     fav: if m<=20: score=0.4*m; else score=8#     cart: if m<=20: score=0.6*m; else score=12#     buy: if m<=20: score=1*m; else score=20# 注意這里要全部設為浮點數,spark運算時對類型比較敏感,要保持數據類型都一致pv_count = r.pv if r.pv else 0.0fav_count = r.fav if r.fav else 0.0cart_count = r.cart if r.cart else 0.0buy_count = r.buy if r.buy else 0.0pv_score = 0.2*pv_count if pv_count<=20 else 4.0fav_score = 0.4*fav_count if fav_count<=20 else 8.0cart_score = 0.6*cart_count if cart_count<=20 else 12.0buy_score = 1.0*buy_count if buy_count<=20 else 20.0rating = pv_score + fav_score + cart_score + buy_score# 返回用戶ID、品牌ID、用戶對品牌的偏好打分return r.userId, r.brandId, rating
# 用戶對品牌的打分數據
brand_rating_df = brand_count_df.rdd.map(process_row).toDF(["userId", "brandId", "rating"])
# brand_rating_df.show()
  • 基于Spark的ALS隱因子模型進行CF評分預測

    • ALS的意思是交替最小二乘法(Alternating Least Squares),是Spark中進行基于模型的協同過濾(model-based CF)的推薦系統算法,也是目前Spark內唯一一個推薦算法。

      同SVD,它也是一種矩陣分解技術,但理論上,ALS在海量數據的處理上要優于SVD。

      更多了解:pyspark.ml.recommendation.ALS

      注意:由于數據量巨大,因此這里不考慮基于內存的CF算法

      參考:為什么Spark中只有ALS

  • 使用pyspark中的ALS矩陣分解方法實現CF評分預測

# 使用pyspark中的ALS矩陣分解方法實現CF評分預測
# 文檔地址:https://spark.apache.org/docs/latest/api/python/pyspark.ml.html?highlight=vectors#module-pyspark.ml.recommendation
from pyspark.ml.recommendation import ALSals = ALS(userCol='userId', itemCol='brandId', ratingCol='rating', checkpointInterval=2)
# 利用打分數據,訓練ALS模型
# 此處訓練時間較長
model = als.fit(brand_rating_df)
# model.recommendForAllUsers(N) 給用戶推薦TOP-N個物品
model.recommendForAllUsers(3).show()
# 將模型進行存儲
model.save("hdfs://localhost:9000/models/userBrandRatingModel.obj")
# 測試存儲的模型
from pyspark.ml.recommendation import ALSModel
# 從hdfs加載模型
my_model = ALSModel.load("hdfs://localhost:9000/models/userBrandRatingModel.obj")
my_model
# model.recommendForAllUsers(N) 給用戶推薦TOP-N個物品
my_model.recommendForAllUsers(3).first()

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/35775.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/35775.shtml
英文地址,請注明出處:http://en.pswp.cn/news/35775.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

DNS協議及其工作原理

DNS是域名系統&#xff08;Domain Name System&#xff09;的縮寫&#xff0c;它是一種用于將域名轉換為IP地址的分布式數據庫系統。它是因特網的基石&#xff0c;能夠使人們通過域名方便地訪問互聯網&#xff0c;而無需記住復雜的IP地址。 DNS的歷史可以追溯到1983年&#xf…

4個簡化IT服務臺任務的ChatGPT功能

最近幾個月&#xff0c;ChatGPT 風靡全球&#xff0c;這是一個 AI 聊天機器人&#xff0c;使用戶能夠生成腳本、文章、鍛煉圖表等。這項技術在各行各業都有無窮無盡的應用&#xff0c;在本文中&#xff0c;我們將研究這種現代技術如何幫助服務臺團隊增強服務交付和客戶體驗。 什…

最佳實踐:如何優雅地提交一個 Amazon EMR Serverless 作業?

《大數據平臺架構與原型實現&#xff1a;數據中臺建設實戰》一書由博主歷時三年精心創作&#xff0c;現已通過知名IT圖書品牌電子工業出版社博文視點出版發行&#xff0c;點擊《重磅推薦&#xff1a;建大數據平臺太難了&#xff01;給我發個工程原型吧&#xff01;》了解圖書詳…

章節7:XSS檢測和利用

章節7&#xff1a;XSS檢測和利用 測試payload <script>alert(XSS)</script> <script>alert(document.cookie)</script> ><script>alert(document.cookie)</script> ><script>alert(document.cookie)</script> &qu…

元宇宙之經濟(02)理解NFT

1 NFT是什么&#xff1f; 想象一下&#xff0c;你小時候曾經在操場上集齊過各種不同的貼紙&#xff0c;然后和朋友們交換&#xff0c;這些貼紙有著獨特的圖案和價值。NFT的概念與此類似&#xff0c;但在數字世界中運作。NFT是一種基于區塊鏈技術的數字資產&#xff0c;每個NFT…

golang—面試題大全

目錄標題 sliceslice和array的區別slice擴容機制slice是否線程安全slice分配到棧上還是堆上擴容過程中是否重新寫入go深拷貝發生在什么情況下&#xff1f;切片的深拷貝是怎么做的copy和左值進行初始化區別slice和map的區別 mapmap介紹map的key的類型map對象如何比較map的底層原…

《Java極簡設計模式》第03章:工廠方法模式(FactoryMethod)

作者&#xff1a;冰河 星球&#xff1a;http://m6z.cn/6aeFbs 博客&#xff1a;https://binghe.gitcode.host 文章匯總&#xff1a;https://binghe.gitcode.host/md/all/all.html 源碼地址&#xff1a;https://github.com/binghe001/java-simple-design-patterns/tree/master/j…

無法正確識別車牌(Python、OpenCv、Tesseract)

我正在嘗試識別車牌&#xff0c;但出現了錯誤&#xff0c;例如錯誤/未讀取字符 以下是每個步驟的可視化&#xff1a; 從顏色閾值變形關閉獲得遮罩 以綠色突出顯示的車牌輪廓過濾器 將板輪廓粘貼到空白遮罩上 Tesseract OCR的預期結果 BP 1309 GD 但我得到的結果是 BP 1309…

騰訊云標準型CVM云服務器詳細介紹

騰訊云CVM服務器標準型實例的各項性能參數平衡&#xff0c;標準型云服務器適用于大多數常規業務&#xff0c;例如&#xff1a;web網站及中間件等&#xff0c;常見的標準型云服務器有CVM標準型S5、S6、SA3、SR1、S5se等規格&#xff0c;騰訊云服務器網來詳細說下云服務器CVM標準…

NAS搭建指南一——服務器的選擇與搭建

一、服務器的選擇 有自己的本地的公網 IP 的請跳過此篇文章按需求選擇一個云服務器&#xff0c;目的就是為了進行 frp 的搭建&#xff0c;完成內網穿透我選擇的是騰訊云服務器&#xff0c;我的配置如下&#xff0c;僅供參考&#xff1a; 4. 騰訊云服務器官網地址 二、服務器…

docker 鏡像的導出與導入 save 與 load

一、鏡像導出 docker save 導出 將系統中的鏡像保存為壓縮包&#xff0c;進行文件傳輸。使用 docker save --help 查看命令各參數&#xff0c;或者去docker官網查看.以 hello-world鏡像為例。 A&#xff1a;將鏡像保存為tar包 docker save image > package.tar docker sa…

day9 10-牛客67道劍指offer-JZ66、19、20、75、23、76、8、28、77、78

文章目錄 1. JZ66 構建乘積數組暴力解法雙向遍歷 2. JZ19 正則表達式匹配3. JZ20 表示數值的字符串有限狀態機遍歷 4. JZ75 字符流中第一個不重復的字符5. JZ23 鏈表中環的入口結點快慢指針哈希表 6. JZ76 刪除鏈表中重復的結點快慢指針三指針如果只保留一個重復結點 7. JZ8 二…

gitblit-使用

1.登入GitBlit服務器 默認用戶和密碼: admin/admin 2.創建一個新的版本庫 點擊圖中的“版本庫”&#xff0c;然后點擊圖中“創建版本庫” 填寫名稱和描述&#xff0c;注意名稱最后一定要加 .git選擇限制查看、克隆和推送勾選“加入README”和“加入.gitignore文件”在圖中的1處…

使用IIS服務器部署Flask python Web項目

參考文章 ""D:\Program Files (x86)\Python310\python310.exe"|"D:\Program Files (x86)\Python310\lib\site-packages\wfastcgi.py"" can now be used as a FastCGI script processor參考文章 請求路徑填寫*&#xff0c;模塊選擇FastCgiModule&…

一鍵部署 Umami 統計個人網站訪問數據

談到網站統計&#xff0c;大家第一時間想到的肯定是 Google Analytics。然而&#xff0c;我們都知道 Google Analytics 會收集所有用戶的信息&#xff0c;對數據沒有任何控制和隱私保護。 Google Analytics 收集的指標實在是太多了&#xff0c;有很多都是不必要的&#xff0c;…

Javascript 深入了解map

map() 是 JavaScript 數組提供的一個高階函數&#xff0c;它用于對數組中的每個元素執行指定的函數&#xff0c;并返回一個新的數組&#xff0c;新數組中的元素是原數組中的每個元素經過函數處理后的結果。 map() 函數的語法如下&#xff1a; javascript array.map(callback(…

Multi-object navigation in real environments using hybrid policies 論文閱讀

論文信息 題目&#xff1a;Multi-object navigation in real environments using hybrid policies 作者&#xff1a;Assem Sadek, Guillaume Bono 來源&#xff1a;CVPR 時間&#xff1a;2023 Abstract 機器人技術中的導航問題通常是通過 SLAM 和規劃的結合來解決的。 最近…

優化堆排序(Java 實例代碼)

目錄 優化堆排序 Java 實例代碼 src/runoob/heap/HeapSort.java 文件代碼&#xff1a; 優化堆排序 上一節的堆排序&#xff0c;我們開辟了額外的空間進行構造堆和對堆進行排序。這一小節&#xff0c;我們進行優化&#xff0c;使用原地堆排序。 對于一個最大堆&#xff0c;首…

【設計模式】-策略模式:優雅處理條件邏輯

Java 策略模式之優雅處理條件邏輯 前言 在軟件開發中&#xff0c;我們經常會遇到根據不同的條件執行不同邏輯的情況。這時&#xff0c;策略模式是一種常用的設計模式&#xff0c;能夠使代碼結構清晰、易于擴展和維護。 本文將詳細介紹策略模式的概念及其在Java中的應用&#x…

flume系列之:監控Systemctl托管的flume agent組

flume系列之:監控Systemctl托管的flume agent組 一、需求背景二、相關技術博客三、遠程登陸flume機器四、發送飛書告警五、監控flume agent組狀態一、需求背景 flume接kafka集群,一個kafka集群對應一個flume agent組,會把一組flume agent用systemctl托管每接一個kafka集群會…