专栏首页志学Python数据挖掘实践指南读书笔记1

数据挖掘实践指南读书笔记1

写在之前

本书涉及的源程序和数据都可以在以下网站中找到:http://guidetodatamining.com/ 这本书理论比较简单,书中错误较少,动手锻炼较多,如果每个代码都自己写出来,收获不少。总结:适合入门。欢迎转载,转载请注明出处,如有问题欢迎指正。合集地址:https://www.zybuluo.com/hainingwyx/note/559139

协同过滤

相似用户评判标准:曼哈顿距离、欧氏距离、明氏距离。

# Manhattan.py
users = {
"Angelica": {"Blues Traveler": 3.5, "Broken Bells": 2.0, "Norah Jones": 4.5,
"Phoenix": 5.0, "Slightly Stoopid": 1.5, "The Strokes": 2.5, 
"Vampire Weekend": 2.0},
"Bill":{"Blues Traveler": 2.0, "Broken Bells": 3.5, "Deadmau5": 4.0, 
"Phoenix": 2.0,"Slightly Stoopid": 3.5, "Vampire Weekend": 3.0},
"Chan": {"Blues Traveler": 5.0, "Broken Bells": 1.0, "Deadmau5": 1.0, 
"Norah Jones": 3.0, "Phoenix": 5, "Slightly Stoopid": 1.0},
"Dan": {"Blues Traveler": 3.0, "Broken Bells": 4.0, "Deadmau5": 4.5, 
"Phoenix": 3.0, "Slightly Stoopid": 4.5, "The Strokes": 4.0, 
"Vampire Weekend": 2.0},
"Hailey": {"Broken Bells": 4.0, "Deadmau5": 1.0, "Norah Jones": 4.0, 
"The Strokes": 4.0, "Vampire Weekend": 1.0},
"Jordyn": {"Broken Bells": 4.5, "Deadmau5": 4.0, "Norah Jones": 5.0, 
"Phoenix": 5.0, "Slightly Stoopid": 4.5, "The Strokes": 4.0, 
"Vampire Weekend": 4.0},
"Sam": {"Blues Traveler": 5.0, "Broken Bells": 2.0, "Norah Jones": 3.0,
"Phoenix": 5.0, "Slightly Stoopid": 4.0, "The Strokes": 5.0},
"Veronica": {"Blues Traveler": 3.0, "Norah Jones": 5.0, "Phoenix": 4.0,
"Slightly Stoopid": 2.5, "The Strokes": 3.0}
        }

def manhattan(rating1, rating2):
    """Computes the Manhattan distance. Both rating1 and rating2 are dictionaries
       of the form {'The Strokes': 3.0, 'Slightly Stoopid': 2.5}"""
    distance = 0
    commonRatings = False 
    for key in rating1:
        if key in rating2:
            distance += abs(rating1[key] - rating2[key])
            commonRatings = True
    if commonRatings:
        return distance
    else:
        return -1 #Indicates no ratings in common

def computeNearestNeighbor(username, users):
    """creates a sorted list of users based on their distance to username"""
    distances = []
    for user in users:
        if user != username:
            distance = manhattan(users[user], users[username])
            distances.append((distance, user))
    # sort based on distance -- closest first
    distances.sort()
    return distances

def recommend(username, users):
    """Give list of recommendations"""
    # first find nearest neighbor
    nearest = computeNearestNeighbor(username, users)[0][1]
    print nearest
    recommendations = []
    # now find bands neighbor rated that user didn't
    neighborRatings = users[nearest]
    userRatings = users[username]
    for artist in neighborRatings:
        if not artist in userRatings:
            recommendations.append((artist, neighborRatings[artist]))
    # using the fn sorted for variety - sort is more efficient
    return sorted(recommendations, key=lambda artistTuple: artistTuple[1], reverse = True)
# -*- coding: utf-8 -*-
from math import sqrt

users = {"Angelica": {"Blues Traveler": 3.5, "Broken Bells": 2.0, "Norah Jones": 4.5, "Phoenix": 5.0, "Slightly Stoopid": 1.5, "The Strokes": 2.5, "Vampire Weekend": 2.0},
"Bill":{"Blues Traveler": 2.0, "Broken Bells": 3.5, "Deadmau5": 4.0, "Phoenix": 2.0, "Slightly Stoopid": 3.5, "Vampire Weekend": 3.0},
"Chan": {"Blues Traveler": 5.0, "Broken Bells": 1.0, "Deadmau5": 1.0, "Norah Jones": 3.0, "Phoenix": 5, "Slightly Stoopid": 1.0},
"Dan": {"Blues Traveler": 3.0, "Broken Bells": 4.0, "Deadmau5": 4.5, "Phoenix": 3.0, "Slightly Stoopid": 4.5, "The Strokes": 4.0, "Vampire Weekend": 2.0},
"Hailey": {"Broken Bells": 4.0, "Deadmau5": 1.0, "Norah Jones": 4.0, "The Strokes": 4.0, "Vampire Weekend": 1.0},
"Jordyn": {"Broken Bells": 4.5, "Deadmau5": 4.0, "Norah Jones": 5.0, "Phoenix": 5.0, "Slightly Stoopid": 4.5, "The Strokes": 4.0, "Vampire Weekend": 4.0},
"Sam": {"Blues Traveler": 5.0, "Broken Bells": 2.0, "Norah Jones": 3.0, "Phoenix": 5.0, "Slightly Stoopid": 4.0, "The Strokes": 5.0},
"Veronica": {"Blues Traveler": 3.0, "Norah Jones": 5.0, "Phoenix": 4.0, "Slightly Stoopid": 2.5, "The Strokes": 3.0}
}

#明氏距离
def minkowski(rating1,rating2,r):
  distance=0
  commonRatings=False
  for key in rating1:
    if key in rating2:
      distance += pow(abs(rating1[key]-rating2[key]),r)
      commonRatings=True
      distance = pow(distance,1.0/r)
    if commonRatings:
      return distance
    else:
      return -1 #Indicates no ratings in common

def computeNearestNeighbor(username, users):
  """creates a sorted list of users based on their distance to username"""
  distances = []
  for user in users:
    if user != username:
      distance = minkowski(users[user], users[username],3)
      distances.append((distance, user))
      # sort based on distance -- closest first
      distances.sort()
      return distances

def recommend(username, users):
  """Give list of recommendations"""
  # first find nearest neighbor
  nearest = computeNearestNeighbor(username, users)[0][1]
  print nearest
  recommendations = []
  # now find bands neighbor rated that user didn't
  neighborRatings = users[nearest]
  userRatings = users[username]
  for artist in neighborRatings:
    if not artist in userRatings:
      recommendations.append((artist, neighborRatings[artist]))
      # using the fn sorted for variety - sort is more efficient
  return sorted(recommendations, key=lambda artistTuple: artistTuple[1], reverse = True)

但是可能存在常数差别,但是两者爱好相同的问题。皮尔逊相关系数:

# Pearson.py
from math import sqrt

users = {"Angelica": {"Blues Traveler": 3.5, "Broken Bells": 2.0, "Norah Jones": 4.5, "Phoenix": 5.0, "Slightly Stoopid": 1.5, "The Strokes": 2.5, "Vampire Weekend": 2.0},
"Bill":{"Blues Traveler": 2.0, "Broken Bells": 3.5, "Deadmau5": 4.0, "Phoenix": 2.0, "Slightly Stoopid": 3.5, "Vampire Weekend": 3.0},
"Chan": {"Blues Traveler": 5.0, "Broken Bells": 1.0, "Deadmau5": 1.0, "Norah Jones": 3.0, "Phoenix": 5, "Slightly Stoopid": 1.0},
"Dan": {"Blues Traveler": 3.0, "Broken Bells": 4.0, "Deadmau5": 4.5, "Phoenix": 3.0, "Slightly Stoopid": 4.5, "The Strokes": 4.0, "Vampire Weekend": 2.0},
"Hailey": {"Broken Bells": 4.0, "Deadmau5": 1.0, "Norah Jones": 4.0, "The Strokes": 4.0, "Vampire Weekend": 1.0},
"Jordyn": {"Broken Bells": 4.5, "Deadmau5": 4.0, "Norah Jones": 5.0, "Phoenix": 5.0, "Slightly Stoopid": 4.5, "The Strokes": 4.0, "Vampire Weekend": 4.0},
"Sam": {"Blues Traveler": 5.0, "Broken Bells": 2.0, "Norah Jones": 3.0, "Phoenix": 5.0, "Slightly Stoopid": 4.0, "The Strokes": 5.0},
"Veronica": {"Blues Traveler": 3.0, "Norah Jones": 5.0, "Phoenix": 4.0, "Slightly Stoopid": 2.5, "The Strokes": 3.0}
}

# 这里为了简单使用近似代替
def pearson(rating1,rating2):
  sum_xy=0
  sum_x=0
  sum_y=0
  sum_x2=0
  sum_y2=0
  n=0
  for key in rating1:
    if key in rating2:
      n += 1
      x = rating1[key]
      y = rating2[key]
      sum_xy += x*y
      sum_x += x
      sum_y += y
      sum_x2 += x**2
      sum_y2 += y**2
  denominnator = sqrt(sum_x2-(sum_x**2)/n)*sqrt(sum_y2-(sum_y**2)/n)
  if denominnator == 0:
    return 0
  else:
    return (sum_xy-(sum_x*sum_y)/n)/denominnator

def cos_like(rating1,rating2):
  innerProd=0
  vector_x=0
  vectoy_y=0
  for key in rating1:
    if key in rating2:
      x=rating1[key]
      y=rating2[key]
      innerProd += x*y
      vector_x += x**2
      vectoy_y += y**2
  denominnator = sqrt(vector_x) * sqrt(vectoy_y)
  if denominnator == 0:
    return 0
  else:
    return innerProd / denominnator

余弦相似度:$$cos(x, y)=\frac{x·y}{||x||\times ||y||}$$ 总结:如果数据稠密使用欧氏距离;如果数据稀疏,使用余弦相似度;如果用户评级范围不同,使用皮尔逊相关系数。但是如果仅仅是基于一个用户进行推荐,个别用户的怪癖也会被推荐。

k近邻:利用k个最相似的用户确定推荐结果,K和应有有关。利用皮尔逊系数来确定每个人的影响因子。

# A dictionary of movie critics and their ratings of a small
# set of movies
critics={'Lisa Rose': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.5,
'Just My Luck': 3.0, 'Superman Returns': 3.5, 'You, Me and Dupree': 2.5, 
'The Night Listener': 3.0},
'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5, 
'Just My Luck': 1.5, 'Superman Returns': 5.0, 'The Night Listener': 3.0, 
'You, Me and Dupree': 3.5}, 
'Michael Phillips': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.0,
'Superman Returns': 3.5, 'The Night Listener': 4.0},
'Claudia Puig': {'Snakes on a Plane': 3.5, 'Just My Luck': 3.0,
'The Night Listener': 4.5, 'Superman Returns': 4.0, 
'You, Me and Dupree': 2.5},
'Mick LaSalle': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0, 
'Just My Luck': 2.0, 'Superman Returns': 3.0, 'The Night Listener': 3.0,
'You, Me and Dupree': 2.0}, 
'Jack Matthews': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0,
'The Night Listener': 3.0, 'Superman Returns': 5.0, 'You, Me and Dupree': 3.5},
'Toby': {'Snakes on a Plane':4.5,'You, Me and Dupree':1.0,'Superman Returns':4.0}}


from math import sqrt

# Returns a distance-based similarity score for person1 and person2
def sim_distance(prefs,person1,person2):
  # Get the list of shared_items
  si={}
  for item in prefs[person1]: 
    if item in prefs[person2]: si[item]=1

  # if they have no ratings in common, return 0
  if len(si)==0: return 0

  # Add up the squares of all the differences
  sum_of_squares=sum([pow(prefs[person1][item]-prefs[person2][item],2) 
  for item in prefs[person1] if item in prefs[person2]])

  return 1/(1+sum_of_squares)

# Returns the Pearson correlation coefficient for p1 and p2
def sim_pearson(prefs,p1,p2):
  # Get the list of mutually rated items
  si={}
  for item in prefs[p1]: 
  if item in prefs[p2]: si[item]=1

  # if they are no ratings in common, return 0
  if len(si)==0: return 0

  # Sum calculations
  n=len(si)

  # Sums of all the preferences
  sum1=sum([prefs[p1][it] for it in si])
  sum2=sum([prefs[p2][it] for it in si])

  # Sums of the squares
  sum1Sq=sum([pow(prefs[p1][it],2) for it in si])
  sum2Sq=sum([pow(prefs[p2][it],2) for it in si]) 

  # Sum of the products
  pSum=sum([prefs[p1][it]*prefs[p2][it] for it in si])

  # Calculate r (Pearson score)
  num=pSum-(sum1*sum2/n)
  den=sqrt((sum1Sq-pow(sum1,2)/n)*(sum2Sq-pow(sum2,2)/n))
  if den==0: return 0

  r=num/den

  return r

# Returns the best matches for person from the prefs dictionary.
# Number of results and similarity function are optional params.
def topMatches(prefs,person,n=5,similarity=sim_pearson):
  scores=[(similarity(prefs,person,other),other) 
  for other in prefs if other!=person]
    scores.sort()
    scores.reverse()
  return scores[0:n]

# Gets recommendations for a person by using a weighted average
# of every other user's rankings
def getRecommendations(prefs,person,similarity=sim_pearson):
  totals={}
  simSums={}
  for other in prefs:
    # don't compare me to myself
    if other==person: continue
      sim=similarity(prefs,person,other)

    # ignore scores of zero or lower
    if sim<=0: continue
  for item in prefs[other]:

    # only score movies I haven't seen yet
    if item not in prefs[person] or prefs[person][item]==0:
    # Similarity * Score
      totals.setdefault(item,0)
      totals[item]+=prefs[other][item]*sim
    # Sum of similarities
      simSums.setdefault(item,0)
      simSums[item]+=sim

# Create the normalized list
  rankings=[(total/simSums[item],item) for item,total in totals.items()]

# Return the sorted list
  rankings.sort()
  rankings.reverse()
  return rankings

def transformPrefs(prefs):
  result={}
  for person in prefs:
  for item in prefs[person]:
    result.setdefault(item,{})

  # Flip item and person
  result[item][person]=prefs[person][item]
  return result


def calculateSimilarItems(prefs,n=10):
  # Create a dictionary of items showing which other items they
  # are most similar to.
  result={}
  # Invert the preference matrix to be item-centric
  itemPrefs=transformPrefs(prefs)
  c=0
  for item in itemPrefs:
  # Status updates for large datasets
  c+=1
  if c%100==0: print "%d / %d" % (c,len(itemPrefs))
  # Find the most similar items to this one
  scores=topMatches(itemPrefs,item,n=n,similarity=sim_distance)
  result[item]=scores
  return result

def getRecommendedItems(prefs,itemMatch,user):
  userRatings=prefs[user]
  scores={}
  totalSim={}
  # Loop over items rated by this user
  for (item,rating) in userRatings.items( ):

  # Loop over items similar to this one
  for (similarity,item2) in itemMatch[item]:

    # Ignore if this user has already rated this item
    if item2 in userRatings: continue
    # Weighted sum of rating times similarity
    scores.setdefault(item2,0)
    scores[item2]+=similarity*rating
    # Sum of all the similarities
    totalSim.setdefault(item2,0)
    totalSim[item2]+=similarity

  # Divide each total score by total weighting to get an average
  rankings=[(score/totalSim[item],item) for item,score in scores.items( )]

  # Return the rankings from highest to lowest
  rankings.sort( )
  rankings.reverse( )
  return rankings

def loadMovieLens(path='C:\Users\WangYixin\Desktop\PCI_Code\PCI_Code Folder\chapter2\data'):
  # Get movie titles
  movies={}
  for line in open(path+'/u.item'):
    (id,title)=line.split('|')[0:2]
    movies[id]=title

    # Load data
    prefs={}
  for line in open(path+'/u.data'):
    (user,movieid,rating,ts)=line.split('\t')
    prefs.setdefault(user,{})
    prefs[user][movies[movieid]]=float(rating)
  return prefs
# -*- coding: utf-8 -*-
# 推荐类
import codecs
from math import sqrt

users = {"Angelica": {"Blues Traveler": 3.5, "Broken Bells": 2.0,
"Norah Jones": 4.5, "Phoenix": 5.0,
"Slightly Stoopid": 1.5,
"The Strokes": 2.5, "Vampire Weekend": 2.0},

"Bill":{"Blues Traveler": 2.0, "Broken Bells": 3.5,
"Deadmau5": 4.0, "Phoenix": 2.0,
"Slightly Stoopid": 3.5, "Vampire Weekend": 3.0},

"Chan": {"Blues Traveler": 5.0, "Broken Bells": 1.0,
"Deadmau5": 1.0, "Norah Jones": 3.0, "Phoenix": 5,
"Slightly Stoopid": 1.0},

"Dan": {"Blues Traveler": 3.0, "Broken Bells": 4.0,
"Deadmau5": 4.5, "Phoenix": 3.0,
"Slightly Stoopid": 4.5, "The Strokes": 4.0,
"Vampire Weekend": 2.0},

"Hailey": {"Broken Bells": 4.0, "Deadmau5": 1.0,
"Norah Jones": 4.0, "The Strokes": 4.0,
"Vampire Weekend": 1.0},

"Jordyn": {"Broken Bells": 4.5, "Deadmau5": 4.0,
"Norah Jones": 5.0, "Phoenix": 5.0,
"Slightly Stoopid": 4.5, "The Strokes": 4.0,
"Vampire Weekend": 4.0},

"Sam": {"Blues Traveler": 5.0, "Broken Bells": 2.0,
"Norah Jones": 3.0, "Phoenix": 5.0,
"Slightly Stoopid": 4.0, "The Strokes": 5.0},

"Veronica": {"Blues Traveler": 3.0, "Norah Jones": 5.0,
"Phoenix": 4.0, "Slightly Stoopid": 2.5,
"The Strokes": 3.0}
}



class recommender:

  def __init__(self, data, k=1, metric='pearson', n=5):
    """ initialize recommender
    currently, if data is dictionary the recommender is initialized
    to it.
    For all other data types of data, no initialization occurs
    k is the k value for k nearest neighbor
    metric is which distance formula to use
    n is the maximum number of recommendations to make"""
    self.k = k
    self.n = n
    self.username2id = {}
    self.userid2name = {}
    self.productid2name = {}
    # for some reason I want to save the name of the metric
    self.metric = metric
    if self.metric == 'pearson':
      self.fn = self.pearson
    #
    # if data is dictionary set recommender data to it
    #
    if type(data).__name__ == 'dict':
      self.data = data

  def convertProductID2name(self, id):
    """Given product id number return product name"""
    if id in self.productid2name:
      return self.productid2name[id]
    else:
      return id


  def userRatings(self, id, n):
    """Return n top ratings for user with id"""
    print ("Ratings for " + self.userid2name[id])
    ratings = self.data[id]
    print(len(ratings))
    ratings = list(ratings.items())
    ratings = [(self.convertProductID2name(k), v)
    for (k, v) in ratings]
      # finally sort and return
      ratings.sort(key=lambda artistTuple: artistTuple[1],
      reverse = True)
      ratings = ratings[:n]
    for rating in ratings:
      print("%s\t%i" % (rating[0], rating[1]))




  def loadBookDB(self, path=''):
    """loads the BX book dataset. Path is where the BX files are
    located"""
    self.data = {}
    i = 0
    #
    # First load book ratings into self.data
    #
    f = codecs.open(path + "BX-Book-Ratings.csv", 'r', 'utf8')
    f.readline() #read the title
    for line in f:
      i += 1
      #separate line into fields
      fields = line.split(';') # still with ""
      user = fields[0].strip('"') #delete “ in the fields
      book = fields[1].strip('"')
      rating = int(fields[2].strip().strip('"'))
      if user in self.data:
        currentRatings = self.data[user]
      else:
        currentRatings = {}
        currentRatings[book] = rating
        self.data[user] = currentRatings
        #line = f.readline()
    f.close()
    #
    # Now load books into self.productid2name
    # Books contains isbn, title, and author among other fields
    #
    f = codecs.open(path + "BX-Books.csv", 'r', 'utf8')
    for line in f:
      i += 1
      #separate line into fields
      fields = line.split(';')
      isbn = fields[0].strip('"')
      title = fields[1].strip('"')
      author = fields[2].strip().strip('"')
      title = title + ' by ' + author
      self.productid2name[isbn] = title
    f.close()
    #
    # Now load user info into both self.userid2name and
    # self.username2id
    #
    f = codecs.open(path + "BX-Users.csv", 'r', 'utf8')
    for line in f:
      i += 1
      #print(line)
      #separate line into fields
      fields = line.split(';')
      userid = fields[0].strip('"')
      location = fields[1].strip('"')
      if len(fields) > 3:
        age = fields[2].strip().strip('"')
      else:
        age = 'NULL'
      if age != 'NULL':
        value = location + ' (age: ' + age + ')'
      else:
        value = location
        self.userid2name[userid] = value
        self.username2id[location] = userid
    f.close()
    print(i)


  def pearson(self, rating1, rating2):
    sum_xy = 0
    sum_x = 0
    sum_y = 0
    sum_x2 = 0
    sum_y2 = 0
    n = 0
    for key in rating1:
      if key in rating2:
        n += 1
        x = rating1[key]
        y = rating2[key]
        sum_xy += x * y
        sum_x += x
        sum_y += y
        sum_x2 += pow(x, 2)
        sum_y2 += pow(y, 2)
  if n == 0:
    return 0
  # now compute denominator
  denominator = (sqrt(sum_x2 - pow(sum_x, 2) / n)
  * sqrt(sum_y2 - pow(sum_y, 2) / n))
  if denominator == 0:
    return 0
  else:
    return (sum_xy - (sum_x * sum_y) / n) / denominator


  def computeNearestNeighbor(self, username):
    """creates a sorted list of users based on their distance to
    username"""
    distances = []
    for instance in self.data:
      if instance != username:
        distance = self.fn(self.data[username],
        self.data[instance])
        distances.append((instance, distance))
  # sort based on distance -- closest first
  distances.sort(key=lambda artistTuple: artistTuple[1],
  reverse=True)
  return distances

  def recommend(self, user):
    """Give list of recommendations"""
    recommendations = {}
    # first get list of users ordered by nearness
    nearest = self.computeNearestNeighbor(user)
    # now get the ratings for the user
    userRatings = self.data[user]
    # determine the total distance
    totalDistance = 0.0
    for i in range(self.k):
      totalDistance += nearest[i][1]
      # now iterate through the k nearest neighbors
      # accumulating their ratings
    for i in range(self.k):
      # compute slice of pie
      weight = nearest[i][1] / totalDistance
      # get the name of the person
      name = nearest[i][0]
      # get the ratings for this person
      neighborRatings = self.data[name]
      # get the name of the person
      # now find bands neighbor rated that user didn't
    for artist in neighborRatings:
      if not artist in userRatings:
        if artist not in recommendations:
          recommendations[artist] = (neighborRatings[artist] * weight)
        else:
          recommendations[artist] = (recommendations[artist] + neighborRatings[artist] * weight)
      # now make list from dictionary
    recommendations = list(recommendations.items())
    recommendations = [(self.convertProductID2name(k), v)
    for (k, v) in recommendations]
      # finally sort and return
      recommendations.sort(key=lambda artistTuple: artistTuple[1],
      reverse = True)
      # Return the first n items
  return recommendations[:self.n]

  ############test code############
  #r = recommender(users)
  #r.recommend('Jordyn')
  #r.recommend('Hailey')
  #r.loadBookDB('BX-CSV-Dump/')
  #r.recommend('171118')
  #r.userRatings('171118', 5)

本文分享自微信公众号 - 志学Python(gh_755651538c61),作者:志学Python

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-10-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 数据挖掘实践指南读书笔记7

    http://guidetodatamining.com/ 这本书理论比较简单,书中错误较少,动手锻炼较多,如果每个代码都自己写出来,收获不少。总结:适合入门。...

    公众号---志学Python
  • python 实现多继承

    python是少数支持多重继承的现代编程语言之一。多重继承是同时从多个基类派生一个类的能力

    公众号---志学Python
  • 数据挖掘实践指南读书笔记5

    http://guidetodatamining.com/ 这本书理论比较简单,书中错误较少,动手锻炼较多,如果每个代码都自己写出来,收获不少。总结:适合入门。...

    公众号---志学Python
  • 实用干货| 投稿cover letter 怎么写才能留下完美第一印象

    Cover letter 可以说决定了编辑看到你作品的“第一印象”,“外表好看”才能决定别人有没有兴趣去深入了解你的文章

    百味科研芝士
  • 推荐Android几个比较实用的Github开源项目

    作为一个程序猿,最大的开源社区Github肯定是知道的,Android老鸟更加的不用说了,赶项目的时候肯定是去找过合适的开源控件,时间多的时候就...

    Rookie
  • 在SAP云平台ABAP编程环境里使用CAP模型创建Fiori应用

    创建必须的CDS view,激活,然后基于CDS view创建behavior definition:

    Jerry Wang
  • 身在毒中不知毒,日用品中潜藏的危机

    分享达人秀
  • 【python爬虫】游民星空福利和壁纸帖图片爬虫

    代码源码贴在我的Github:https://github.com/qqxx6661/python/blob/master/gamerskyPic1.0.py

    后端技术漫谈
  • jupyter 错误

    参考:https://github.com/jupyterlab/jupyterlab/issues/5345

    iOSDevLog
  • 怎样一个金箍圈(Pipeline),让至尊宝(Openshift)完成了到孙悟空(DevOps)的蜕变

    但说出这句话,和实现Devops全工具链落地之间的差距,与造出原子弹和E=MC2公式的差距,实不逞多让。

    魏新宇

扫码关注云+社区

领取腾讯云代金券