TF-IDF中的IDF是一种试图抑制噪声的加权,单纯的觉得文本频率小的单词就越重要,文本频率越大的单词就越无用,这一方式会在同类语料库中存在巨大弊端,一些同类文本的关键词容易被掩盖。例如:语料库 D 中教育类文章偏多,而文本 j 是一篇属于教育类的文化在那个,那么教育类相关词语的IDF值就会较小,使提取本文关键词的召回率更低。python
改进方法:TF−IWF (Term Frequency-Inverse Word Frequency)git
更有200本纸质书等,来就送!>>>AI充电季,开宝箱免费学正价课,200本纸质书等包邮送!-七月在线算法
聚类算法属于无监督的机器学习算法,即没有类别标签y,须要根据数据特征将类似的数据分为一组。K-means聚类算法即随机选取k个点做为聚类中心,计算其余点与中心点的距离,选择距离最近的中心并归类,归类完成后计算每类的新中心点,从新计算每一个点与中心点的聚类并选择距离最近的归类,重复此过程,直到中心点再也不变化。markdown
谱聚类的思想是将样本看做顶点,样本间的类似度看做带权的边,从而将聚类问题转为图分割问题:找到一种图分割的方法使得链接不一样组的边的权重尽量低(这意味着组间类似度要尽量低),组内的边的权重尽量高(这意味着组内类似度要尽量高),从而达到聚类的目的。网络
知识蒸馏就是将已经训练好的模型包含的知识,蒸馏到另外一个模型中去。具体来讲,知识蒸馏,能够将一个网络的知识转移到另外一个网络,两个网络能够是同构或者异构。作法是先训练一个teacher网络,而后使用这个teacher网络的输出和数据的真实标签去训练student网络。app
在训练过程当中,咱们须要使用复杂的模型,大量的计算资源,以便从很是大、高度冗余的数据集中提取出信息。在实验中,效果最好的模型每每规模很大,甚至由多个模型集成获得。而大模型不方便部署到服务中去,常见的瓶颈以下:机器学习
所以,模型压缩(在保证性能的前提下减小模型的参数量)成为了一个重要的问题。而”模型蒸馏“属于模型压缩的一种方法。oop
以Bert模型举例:性能
Logit Distillation学习
Beyond Logit Distillation:TinyBert
Curriculum Distillation:
Dynamic Early Exit:FastBert。
python经过内存池来减小内存碎片化,提升执行效率。主要经过引用计数来完成垃圾回收,经过标记-清除解决容器对象循环引用形成的问题,经过分代回收提升垃圾回收的效率。
代码示例以下:
def reduce_mem_usage(props):
# 计算当前内存
start_mem_usg = props.memory_usage().sum() / 1024 ** 2
print("Memory usage of the dataframe is :", start_mem_usg, "MB")
# 哪些列包含空值,空值用-999填充。why:由于np.nan当作float处理
NAlist = []
for col in props.columns:
# 这里只过滤了object格式,若是你的代码中还包含其余类型,请一并过滤
if (props[col].dtypes != object):
print("**************************")
print("columns: ", col)
print("dtype before", props[col].dtype)
# 判断是不是int类型
isInt = False
mmax = props[col].max()
mmin = props[col].min()
# Integer does not support NA, therefore Na needs to be filled
if not np.isfinite(props[col]).all():
NAlist.append(col)
props[col].fillna(-999, inplace=True) # 用-999填充
# test if column can be converted to an integer
asint = props[col].fillna(0).astype(np.int64)
result = np.fabs(props[col] - asint)
result = result.sum()
if result < 0.01: # 绝对偏差和小于0.01认为能够转换的,要根据task修改
isInt = True
# make interger / unsigned Integer datatypes
if isInt:
if mmin >= 0: # 最小值大于0,转换成无符号整型
if mmax <= 255:
props[col] = props[col].astype(np.uint8)
elif mmax <= 65535:
props[col] = props[col].astype(np.uint16)
elif mmax <= 4294967295:
props[col] = props[col].astype(np.uint32)
else:
props[col] = props[col].astype(np.uint64)
else: # 转换成有符号整型
if mmin > np.iinfo(np.int8).min and mmax < np.iinfo(np.int8).max:
props[col] = props[col].astype(np.int8)
elif mmin > np.iinfo(np.int16).min and mmax < np.iinfo(np.int16).max:
props[col] = props[col].astype(np.int16)
elif mmin > np.iinfo(np.int32).min and mmax < np.iinfo(np.int32).max:
props[col] = props[col].astype(np.int32)
elif mmin > np.iinfo(np.int64).min and mmax < np.iinfo(np.int64).max:
props[col] = props[col].astype(np.int64)
else: # 注意:这里对于float都转换成float16,须要根据你的状况本身更改
props[col] = props[col].astype(np.float16)
print("dtype after", props[col].dtype)
print("********************************")
print("___MEMORY USAGE AFTER COMPLETION:___")
mem_usg = props.memory_usage().sum() / 1024**2
print("Memory usage is: ",mem_usg," MB")
print("This is ",100*mem_usg/start_mem_usg,"% of the initial size")
复制代码
能够采起分块读取数据的方式。
代码示例以下:
data_path = r'E:\python\Study\BiGData\demo.csv'
def read_bigfile(path):
# 分块,每一块是一个chunk,以后将chunk进行拼接
df = pd.read_csv(path, engine='python', encoding='gbk', iterator=True)
loop = True
chunkSize = 10000
chunks = []
while loop:
try:
chunk = df.get_chunk(chunkSize)
chunks.append(chunk)
except StopIteration:
loop = False
print("Iteration is stopped.")
df = pd.concat(chunks, ignore_index=True)
after_df = read_bigfile(path = data_path)
复制代码
该题为leetcode-3,难度:【中等】
方法:双指针 + sliding window
定义两个指针 start 和 end 获得 sliding window
start 初始为0,用end线性遍历每一个字符,用 recod 记录下每一个字母最新出现的下标
两种状况:一种是新字符没有在 record 中出现过,表示没有重复,一种是新字符 char 在 record 中出现过,说明 start 须要更新,取 start 和 record[char]+1 中的最大值做为新的 start。
须要注意的是:两种状况都要对record进行更新,由于是新字符没在record出现过的时候须要添加到record中,而对于出现过的状况,也须要把record中对应的value值更新为新的下标。
代码:
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
record = {}
start,res = 0,0
for end in range(len(s)):
if s[end] in record:
start = max(start, record[s[end]] + 1)
record[s[end]] = end
res = max(res, end - start + 1)
return res
复制代码
时间复杂度:O(n)
空间复杂度:O(1)
判断链表是否有环为leetcode-141题
提供两种解题方法,以下:
方法一:哈希表
遍历全部节点,每次遍历一个节点时,判断该节点此前是否被访问过。
若是被访问过,说明该链表是环形链表,并返回True,若是没有,则将该节点加入到哈希表中,遍历完成便可。
代码以下:
class Solution:
def hasCycle(self, head: ListNode) -> bool:
seen = set()
while head:
if head in seen:
return True
seen.add(head)
head = head.next
return False
复制代码
时间复杂度:O(n)
空间复杂度:O(n)
方法二:快慢指针
定义两个指针,一快一慢,满指针每一移动一步,快指针每次移动两步,因为快指针比慢指针慢,若是链表有环,则快指针必定会和慢指针相遇。
代码以下:
class Solution:
def hasCycle(self, head: ListNode) -> bool:
fast = slow = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if fast == slow:
return True
return False
复制代码
时间复杂度:O(N)
空间复杂度:O(1)
链表环的入口 为leetcode-142题
解题思路:使用快慢指针
首先,咱们要作如下设定,设链表共有 a + b个节点,其中链表头部到链表入口(不计链表入口节点)有 a 个节点,链表环有 b 个节点,同时设快指针走了 f 步,慢指针走了 s 步;
显然,因为快指针是慢指针的两倍,所以有:f = 2s
若是两个指针第一次相遇,则知足:f = s + nb(n表示n个环),也就是 fast 比 slow 多走了 n 个环的长度;
由上可得:当两个指针第一次相遇,有s = nb, f = 2nb
如今须要解决的问题,咱们如何知道 a 的大小?
假设如今两指针第一次相遇:
对慢指针来讲,若是让慢指针走到链表入口节点,须要 a + nb步,而在相遇时,已经走了 nb 步了,所以,再让慢指针走 a 步就能够走到链表入口节点了;
对快指针来讲,若是让快指针从头指针开始走 a 步,快指针也正好走到链表入口节点;
因而可知,两指针发生第二次相遇的时候,恰好都在链表入口处。
代码以下:
class Solution:
def detectCycle(self, head: ListNode) -> ListNode:
fast = slow = head
while True:
if not (fast and fast.next):return
fast = fast.next.next
slow = slow.next
if fast == slow:break
fast = head
while fast != slow:
fast = fast.next
slow = slow.next
return fast
复制代码
时间复杂度 O(N)
空间复杂度 O(1)
更有200本纸质书等,来就送! >>>AI充电季,开宝箱免费学正价课,200本纸质书等包邮送!-七月在线
发布于刚刚